diff options
-rw-r--r-- | mesonbuild/interpreter.py | 4 | ||||
-rw-r--r-- | mesonbuild/interpreterbase.py | 21 | ||||
-rwxr-xr-x | run_unittests.py | 5 | ||||
-rw-r--r-- | test cases/unit/82 meson version compare/meson.build | 17 |
4 files changed, 44 insertions, 3 deletions
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index 2924172..322cc26 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -30,7 +30,7 @@ from .interpreterbase import check_stringlist, flatten, noPosargs, noKwargs, str from .interpreterbase import InterpreterException, InvalidArguments, InvalidCode, SubdirDoneRequest from .interpreterbase import InterpreterObject, MutableInterpreterObject, Disabler, disablerIfNotFound from .interpreterbase import FeatureNew, FeatureDeprecated, FeatureNewKwargs, FeatureDeprecatedKwargs -from .interpreterbase import ObjectHolder +from .interpreterbase import ObjectHolder, MesonVersionString from .modules import ModuleReturnValue from .cmake import CMakeInterpreter from .backend.backends import TestProtocol @@ -2172,7 +2172,7 @@ class MesonMain(InterpreterObject): @noPosargs @permittedKwargs({}) def version_method(self, args, kwargs): - return coredata.version + return MesonVersionString(coredata.version) @noPosargs @permittedKwargs({}) diff --git a/mesonbuild/interpreterbase.py b/mesonbuild/interpreterbase.py index 6c4f273..e071243 100644 --- a/mesonbuild/interpreterbase.py +++ b/mesonbuild/interpreterbase.py @@ -54,6 +54,9 @@ TYPE_var = T.Union[TYPE_elementary, list, dict, InterpreterObject, ObjectHolder] TYPE_nvar = T.Union[TYPE_var, mparser.BaseNode] TYPE_nkwargs = T.Dict[T.Union[mparser.BaseNode, str], TYPE_nvar] +class MesonVersionString(str): + pass + # Decorators for method calls. def check_stringlist(a: T.Any, msg: str = 'Arguments must be strings.') -> None: @@ -451,6 +454,11 @@ class InterpreterBase: # Current node set during a function call. This can be used as location # when printing a warning message during a method call. self.current_node = None # type: mparser.BaseNode + # This is set to `version_string` when this statement is evaluated: + # meson.version().compare_version(version_string) + # If it was part of a if-clause, it is used to temporally override the + # current meson version target within that if-block. + self.tmp_meson_version = None # type: str def load_root_meson_file(self) -> None: mesonfile = os.path.join(self.source_root, self.subdir, environment.build_filename) @@ -606,13 +614,22 @@ class InterpreterBase: def evaluate_if(self, node: mparser.IfClauseNode) -> T.Optional[Disabler]: assert(isinstance(node, mparser.IfClauseNode)) for i in node.ifs: + # Reset self.tmp_meson_version to know if it gets set during this + # statement evaluation. + self.tmp_meson_version = None result = self.evaluate_statement(i.condition) if isinstance(result, Disabler): return result if not(isinstance(result, bool)): raise InvalidCode('If clause {!r} does not evaluate to true or false.'.format(result)) if result: - self.evaluate_codeblock(i.block) + prev_meson_version = mesonlib.project_meson_versions[self.subproject] + if self.tmp_meson_version: + mesonlib.project_meson_versions[self.subproject] = self.tmp_meson_version + try: + self.evaluate_codeblock(i.block) + finally: + mesonlib.project_meson_versions[self.subproject] = prev_meson_version return None if not isinstance(node.elseblock, mparser.EmptyNode): self.evaluate_codeblock(node.elseblock) @@ -1023,6 +1040,8 @@ The result of this is undefined and will become a hard error in a future Meson r cmpr = posargs[0] if not isinstance(cmpr, str): raise InterpreterException('Version_compare() argument must be a string.') + if isinstance(obj, MesonVersionString): + self.tmp_meson_version = cmpr return mesonlib.version_compare(obj, cmpr) elif method_name == 'substring': if len(posargs) > 2: diff --git a/run_unittests.py b/run_unittests.py index c095605..8c03693 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -5094,6 +5094,11 @@ recommended as it is not supported on some platforms''') self.init(testdir) self.build() + def test_meson_version_compare(self): + testdir = os.path.join(self.unit_test_dir, '82 meson version compare') + out = self.init(testdir) + self.assertNotRegex(out, r'WARNING') + class FailureTests(BasePlatformTests): ''' Tests that test failure conditions. Build files here should be dynamically diff --git a/test cases/unit/82 meson version compare/meson.build b/test cases/unit/82 meson version compare/meson.build new file mode 100644 index 0000000..ed69a8b --- /dev/null +++ b/test cases/unit/82 meson version compare/meson.build @@ -0,0 +1,17 @@ +project('version compare', meson_version: '>= 0.1') + +if meson.version().version_compare('>= 9999') + error('This should not be executed') +elif meson.version().version_compare('>= 0.55') and false + error('This should not be executed') +elif not meson.version().version_compare('>= 0.55') + error('This should not be executed') +elif meson.version().version_compare('>= 0.55') + # This Should not produce warning even when using function not available in + # meson 0.1. + foo_dep = declare_dependency() + meson.override_dependency('foo', foo_dep) +endif + +# This will error out if elif cause did not enter +assert(foo_dep.found(), 'meson.version_compare did not work') |