diff options
-rw-r--r-- | mesonbuild/interpreterbase/interpreterbase.py | 16 | ||||
-rw-r--r-- | test cases/failing/1 project not first/test.json | 2 |
2 files changed, 15 insertions, 3 deletions
diff --git a/mesonbuild/interpreterbase/interpreterbase.py b/mesonbuild/interpreterbase/interpreterbase.py index f0668e4..4930bee 100644 --- a/mesonbuild/interpreterbase/interpreterbase.py +++ b/mesonbuild/interpreterbase/interpreterbase.py @@ -45,7 +45,7 @@ from .disabler import Disabler, is_disabled from .helpers import check_stringlist, default_resolve_key, flatten, resolve_second_level_holders from ._unholder import _unholder -import os, copy, re +import os, copy, re, pathlib import typing as T if T.TYPE_CHECKING: @@ -123,7 +123,19 @@ class InterpreterBase: raise InvalidCode('No statements in code.') first = self.ast.lines[0] if not isinstance(first, mparser.FunctionNode) or first.func_name != 'project': - raise InvalidCode('First statement must be a call to project') + p = pathlib.Path(self.source_root).resolve() + found = p + for parent in p.parents: + if (parent / 'meson.build').is_file(): + found = parent + else: + break + + error = 'first statement must be a call to project()' + if found != p: + raise InvalidCode(f'Not the project root: {error}\n\nDid you mean to run meson from the directory: "{found}"?') + else: + raise InvalidCode(f'Invalid source tree: {error}') def run(self) -> None: # Evaluate everything after the first line, which is project() because diff --git a/test cases/failing/1 project not first/test.json b/test cases/failing/1 project not first/test.json index 70f3c41..27bae02 100644 --- a/test cases/failing/1 project not first/test.json +++ b/test cases/failing/1 project not first/test.json @@ -1,7 +1,7 @@ { "stdout": [ { - "line": "ERROR: First statement must be a call to project" + "line": "ERROR: Invalid source tree: first statement must be a call to project()" } ] } |