diff --git a/mesonbuild/interpreter/interpreterobjects.py b/mesonbuild/interpreter/interpreterobjects.py index db42c6701..ac37f3a52 100644 --- a/mesonbuild/interpreter/interpreterobjects.py +++ b/mesonbuild/interpreter/interpreterobjects.py @@ -520,7 +520,6 @@ class ExternalProgramHolder(ObjectHolder[ExternalProgram]): self.methods.update({'found': self.found_method, 'path': self.path_method, 'full_path': self.full_path_method}) - self.cached_version = None @noPosargs @permittedKwargs({}) @@ -558,26 +557,6 @@ class ExternalProgramHolder(ObjectHolder[ExternalProgram]): return exe.name return exe.get_name() - def get_version(self, interpreter): - if isinstance(self.held_object, build.Executable): - return self.held_object.project_version - if not self.cached_version: - raw_cmd = self.get_command() + ['--version'] - cmd = [self, '--version'] - res = interpreter.run_command_impl(interpreter.current_node, cmd, {}, True) - if res.returncode != 0: - m = 'Running {!r} failed' - raise InterpreterException(m.format(raw_cmd)) - output = res.stdout.strip() - if not output: - output = res.stderr.strip() - match = re.search(r'([0-9][0-9\.]+)', output) - if not match: - m = 'Could not find a version number in output of {!r}' - raise InterpreterException(m.format(raw_cmd)) - self.cached_version = match.group(1) - return self.cached_version - class ExternalLibraryHolder(ObjectHolder[ExternalLibrary]): def __init__(self, el: ExternalLibrary, subproject: str): super().__init__(el, subproject=subproject) diff --git a/mesonbuild/programs.py b/mesonbuild/programs.py index 06af320f0..bb14f964a 100644 --- a/mesonbuild/programs.py +++ b/mesonbuild/programs.py @@ -19,6 +19,7 @@ import os import shutil import stat import sys +import re import typing as T from pathlib import Path @@ -28,6 +29,7 @@ from .mesonlib import MachineChoice if T.TYPE_CHECKING: from .environment import Environment + from .interpreter import Interpreter class ExternalProgram(mesonlib.HoldableObject): @@ -41,7 +43,8 @@ class ExternalProgram(mesonlib.HoldableObject): silent: bool = False, search_dir: T.Optional[str] = None, extra_search_dirs: T.Optional[T.List[str]] = None): self.name = name - self.path = None # type: T.Optional[str] + self.path: T.Optional[str] = None + self.cached_version: T.Optional[str] = None if command is not None: self.command = mesonlib.listify(command) if mesonlib.is_windows(): @@ -97,6 +100,24 @@ class ExternalProgram(mesonlib.HoldableObject): '''Human friendly description of the command''' return ' '.join(self.command) + def get_version(self, interpreter: 'Interpreter') -> str: + if not self.cached_version: + raw_cmd = self.get_command() + ['--version'] + cmd: T.List[T.Union[str, ExternalProgram]] = [self, '--version'] + res = interpreter.run_command_impl(interpreter.current_node, cmd, {}, True) + if res.returncode != 0: + m = 'Running {!r} failed' + raise mesonlib.MesonException(m.format(raw_cmd)) + output = res.stdout.strip() + if not output: + output = res.stderr.strip() + match = re.search(r'([0-9][0-9\.]+)', output) + if not match: + m = 'Could not find a version number in output of {!r}' + raise mesonlib.MesonException(m.format(raw_cmd)) + self.cached_version = match.group(1) + return self.cached_version + @classmethod def from_bin_list(cls, env: 'Environment', for_machine: MachineChoice, name: str) -> 'ExternalProgram': # There is a static `for_machine` for this class because the binary