diff --git a/docs/reference/config-settings.rst b/docs/reference/config-settings.rst index daecb5d6e..7dedc15dc 100644 --- a/docs/reference/config-settings.rst +++ b/docs/reference/config-settings.rst @@ -44,5 +44,9 @@ them. .. option:: editable-verbose - Enable :ref:`verbose mode ` - when building for an :ref:`editable install `. + Enable :ref:`verbose mode ` when + building for an :ref:`editable install `. + Accepts an optional argument interpreted as a boolean: the strings ``true`` + and ``1`` are mapped to true, and the strings ``false`` and ``0`` to + false. This config setting takes precedence over the project setting with + the same name. diff --git a/docs/reference/pyproject-settings.rst b/docs/reference/pyproject-settings.rst index 6a7177c10..0dab117b9 100644 --- a/docs/reference/pyproject-settings.rst +++ b/docs/reference/pyproject-settings.rst @@ -26,6 +26,13 @@ use them and examples. documentation. This option ensures that the package authors are aware of this requirement. +.. option:: tool.meson-python.editable-verbose + + A boolean indicating whether :ref:`verbose mode + ` should be enabled when building + an :ref:`editable install `. This setting + can be overridden via the config option of the same name. + .. option:: tool.meson-python.limited-api A boolean indicating whether the extension modules contained in the diff --git a/mesonpy/__init__.py b/mesonpy/__init__.py index 36e1f17d2..fa94616cc 100644 --- a/mesonpy/__init__.py +++ b/mesonpy/__init__.py @@ -603,6 +603,7 @@ def _string_or_path(value: Any, name: str) -> str: 'exclude': _strings, 'include': _strings, }), + 'editable-verbose': _bool, }) table = pyproject.get('tool', {}).get('meson-python', {}) @@ -617,8 +618,16 @@ def _string(value: Any, name: str) -> str: raise ConfigError(f'Only one value for "{name}" can be specified') return value - def _bool(value: Any, name: str) -> bool: - return True + def _empty_or_bool(value: Any, name: str) -> bool: + if isinstance(value, bool): + return value + if isinstance(value, str): + if value == 'false' or value == '0': + return False + # For bakward compatibility, treat a missing value as True. + if value == '' or value == 'true' or value == '1': + return True + raise ConfigError(f'Invalid value for "{name}": {value!r}') def _string_or_strings(value: Any, name: str) -> List[str]: return list([value,] if isinstance(value, str) else value) @@ -626,7 +635,7 @@ def _string_or_strings(value: Any, name: str) -> List[str]: options = { 'builddir': _string, 'build-dir': _string, - 'editable-verbose': _bool, + 'editable-verbose': _empty_or_bool, 'dist-args': _string_or_strings, 'setup-args': _string_or_strings, 'compile-args': _string_or_strings, @@ -667,11 +676,10 @@ def __init__( source_dir: Path, build_dir: Path, meson_args: Optional[MesonArgs] = None, - editable_verbose: bool = False, + editable_verbose: Optional[bool] = None, ) -> None: self._source_dir = pathlib.Path(source_dir).absolute() self._build_dir = pathlib.Path(build_dir).absolute() - self._editable_verbose = editable_verbose self._meson_native_file = self._build_dir / 'meson-python-native-file.ini' self._meson_cross_file = self._build_dir / 'meson-python-cross-file.ini' self._meson_args: MesonArgs = collections.defaultdict(list) @@ -685,6 +693,12 @@ def __init__( for key, value in pyproject_config.get('args', {}).items(): self._meson_args[key].extend(value) + # editable-verbose setting from build options takes precedence over + # setting in pyproject.toml + if editable_verbose is None: + editable_verbose = bool(pyproject_config.get('editable-verbose')) + self._editable_verbose = editable_verbose + # meson arguments from the command line take precedence over # arguments from the configuration file thus are added later if meson_args: @@ -1114,7 +1128,7 @@ def _project(config_settings: Optional[Dict[Any, Any]] = None) -> Iterator[Proje meson_args = typing.cast('MesonArgs', {name: settings.get(f'{name}-args', []) for name in _MESON_ARGS_KEYS}) source_dir = os.path.curdir build_dir = settings.get('build-dir') - editable_verbose = bool(settings.get('editable-verbose')) + editable_verbose = settings.get('editable-verbose') with contextlib.ExitStack() as ctx: if build_dir is None: diff --git a/tests/conftest.py b/tests/conftest.py index 919a57c75..6a09b3d27 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -200,7 +200,7 @@ def meson_fatal_warnings(): mpatch = pytest.MonkeyPatch() mesonpy_project_init = mesonpy.Project.__init__ - def __init__(self, source_dir, build_dir, meson_args=None, editable_verbose=False): + def __init__(self, source_dir, build_dir, meson_args=None, editable_verbose=None): if pathlib.Path(source_dir).absolute().name not in { # The CMake subproject emits ``WARNING: CMake Toolchain: diff --git a/tests/test_project.py b/tests/test_project.py index b511b2171..160a0bff9 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -23,6 +23,8 @@ import mesonpy +from mesonpy._util import chdir + from .conftest import MESON_VERSION, in_git_repo_context, metadata, package_dir @@ -410,3 +412,55 @@ def test_ios_project(package_simple, monkeypatch, multiarch, tmp_path): assert "\nsystem = 'ios'\n" in cross_config assert f"\nc = '{arch}-apple-{subsystem}-clang'\n" in cross_config assert f"\nsubsystem = '{subsystem}'\n" in cross_config + + +@pytest.mark.parametrize('verbose', ['true', 'false']) +def test_editable_verbose_pyproject(tmp_path, verbose): + tmp_path.joinpath('pyproject.toml').write_text(textwrap.dedent(f''' + [build-system] + build-backend = 'mesonpy' + requires = ['meson-python'] + + [project] + name = 'test' + version = '1.0.0' + + [tool.meson-python] + editable-verbose = {verbose} + '''), encoding='utf8') + + tmp_path.joinpath('meson.build').write_text(textwrap.dedent(''' + project('test') + '''), encoding='utf8') + + project = mesonpy.Project(tmp_path, tmp_path / 'build') + assert project._editable_verbose == (verbose == 'true') + + +@pytest.mark.parametrize('settings,expected', [ + ({}, True), + ({'editable-verbose': ''}, True), + ({'editable-verbose': 'true'}, True), + ({'editable-verbose': 'false'}, False), +], ids=['', '-Ceditable-verbose', '-Ceditable-verbose=true', '-Ceditable-verbose=false']) +def test_editable_verbose_settings(tmp_path, settings, expected): + tmp_path.joinpath('pyproject.toml').write_text(textwrap.dedent(''' + [build-system] + build-backend = 'mesonpy' + requires = ['meson-python'] + + [project] + name = 'test' + version = '1.0.0' + + [tool.meson-python] + editable-verbose = true + '''), encoding='utf8') + + tmp_path.joinpath('meson.build').write_text(textwrap.dedent(''' + project('test') + '''), encoding='utf8') + + with chdir(tmp_path): + with mesonpy._project(settings) as project: + assert project._editable_verbose == expected