diff --git a/src/build/__main__.py b/src/build/__main__.py index b246e596..2c483fb8 100644 --- a/src/build/__main__.py +++ b/src/build/__main__.py @@ -78,16 +78,15 @@ def _make_logger() -> _ctx.Logger: fill = partial(textwrap.fill, subsequent_indent=' ', width=max_terminal_width) - def log(message: str, *, origin: tuple[str, ...] | None = None) -> None: + def log(message: str, *, kind: tuple[str, ...] | None = None) -> None: if _ctx.verbosity >= -1: - if origin is None: - (first, *rest) = message.splitlines() - _cprint('{bold}{}{reset}', fill(first, initial_indent='* '), file=sys.stderr) - for line in rest: - print(fill(line, initial_indent=' '), file=sys.stderr) - - elif origin[0] == 'subprocess': - initial_indent = '> ' if origin[1] == 'cmd' else '< ' + if kind is None: + print(fill(message, initial_indent=' '), file=sys.stderr) + elif kind[0] == 'step': + _cprint('{bold}{}{reset}', fill(message, initial_indent='* '), file=sys.stderr) + + elif kind[0] == 'subprocess': + initial_indent = '> ' if kind[1] == 'cmd' else '< ' for line in message.splitlines(): _cprint('{dim}{}{reset}', fill(line, initial_indent=initial_indent), file=sys.stderr) @@ -313,7 +312,7 @@ def build_package_via_sdist( with tarfile.TarFile.open(sdist) as t: t.extractall(sdist_out) try: - _ctx.log(f'Building {_natural_language_list(distributions)} from sdist') + _ctx.log(f'Building {_natural_language_list(distributions)} from sdist', kind=('step',)) srcdir = os.path.join(sdist_out, sdist_name[: -len('.tar.gz')]) for distribution in distributions: out = _build( diff --git a/src/build/_builder.py b/src/build/_builder.py index 1201d193..29a1b362 100644 --- a/src/build/_builder.py +++ b/src/build/_builder.py @@ -218,7 +218,7 @@ def get_requires_for_build( (``sdist`` or ``wheel``) :param config_settings: Config settings for the build backend """ - _ctx.log(f'Getting build dependencies for {distribution}...') + _ctx.log(f'Getting build dependencies for {distribution}...', kind=('step',)) hook_name = f'get_requires_for_build_{distribution}' get_requires = getattr(self._hook, hook_name) @@ -256,7 +256,7 @@ def prepare( :param config_settings: Config settings for the build backend :returns: The full path to the prepared metadata directory """ - _ctx.log(f'Getting metadata for {distribution}...') + _ctx.log(f'Getting metadata for {distribution}...', kind=('step',)) try: return self._call_backend( f'prepare_metadata_for_build_{distribution}', @@ -286,7 +286,8 @@ def build( previous ``prepare`` call on the same ``distribution`` kind :returns: The full path to the built distribution """ - _ctx.log(f'Building {distribution}...') + _ctx.log(f'Building {distribution}...', kind=('step',)) + kwargs = {} if metadata_directory is None else {'metadata_directory': metadata_directory} return self._call_backend(f'build_{distribution}', output_directory, config_settings, **kwargs) diff --git a/src/build/_ctx.py b/src/build/_ctx.py index 9e2be6a0..4f9c4f1d 100644 --- a/src/build/_ctx.py +++ b/src/build/_ctx.py @@ -11,16 +11,16 @@ class Logger(typing.Protocol): # pragma: no cover - def __call__(self, message: str, *, origin: tuple[str, ...] | None = None) -> None: ... + def __call__(self, message: str, *, kind: tuple[str, ...] | None = None) -> None: ... _package_name = __spec__.parent _default_logger = logging.getLogger(_package_name) -def _log_default(message: str, *, origin: tuple[str, ...] | None = None) -> None: - if origin is None: - _default_logger.log(logging.INFO, message, stacklevel=2) +def _log_default(message: str, *, kind: tuple[str, ...] | None = None) -> None: + # the log function that works in tests, real log function is set in __main__ + _default_logger.log(logging.INFO, message, stacklevel=2) LOGGER = contextvars.ContextVar('LOGGER', default=_log_default) @@ -30,12 +30,12 @@ def _log_default(message: str, *, origin: tuple[str, ...] | None = None) -> None def log_subprocess_error(error: subprocess.CalledProcessError) -> None: log = LOGGER.get() - log(subprocess.list2cmdline(error.cmd), origin=('subprocess', 'cmd')) + log(subprocess.list2cmdline(error.cmd), kind=('subprocess', 'cmd')) for stream_name in ('stdout', 'stderr'): stream = getattr(error, stream_name) if stream: - log(stream.decode() if isinstance(stream, bytes) else stream, origin=('subprocess', stream_name)) + log(stream.decode() if isinstance(stream, bytes) else stream, kind=('subprocess', stream_name)) def run_subprocess(cmd: Sequence[StrPath], cwd: str | None = None, env: Mapping[str, str] | None = None) -> None: @@ -52,13 +52,13 @@ def run_subprocess(cmd: Sequence[StrPath], cwd: str | None = None, env: Mapping[ cmd, cwd=cwd, encoding='utf-8', env=env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT ) as process, ): - log(subprocess.list2cmdline(cmd), origin=('subprocess', 'cmd')) + log(subprocess.list2cmdline(cmd), kind=('subprocess', 'cmd')) @executor.submit def log_stream() -> None: assert process.stdout for line in process.stdout: - log(line, origin=('subprocess', 'stdout')) + log(line, kind=('subprocess', 'stdout')) concurrent.futures.wait([log_stream]) diff --git a/src/build/env.py b/src/build/env.py index 62209603..0ac4b0ac 100644 --- a/src/build/env.py +++ b/src/build/env.py @@ -101,7 +101,7 @@ def __enter__(self) -> DefaultIsolatedEnv: else: self._env_backend = _PipBackend() - _ctx.log(f'Creating isolated environment: {self._env_backend.display_name}...') + _ctx.log(f'Creating isolated environment: {self._env_backend.display_name}...', kind=('step',)) self._env_backend.create(self._path) except Exception: # cleanup folder if creation fails @@ -144,7 +144,9 @@ def install(self, requirements: Collection[str], constraints: Collection[str] = if not requirements: return - _ctx.log('Installing packages in isolated environment:\n' + '\n'.join(f'- {r}' for r in sorted(requirements))) + _ctx.log('Installing packages in isolated environment:', kind=('step',)) + for r in sorted(requirements): + _ctx.log(f'- {r}') self._env_backend.install_dependencies(requirements, constraints) diff --git a/tests/test_ctx_logger.py b/tests/test_ctx_logger.py index 5c609a53..b2b163a4 100644 --- a/tests/test_ctx_logger.py +++ b/tests/test_ctx_logger.py @@ -21,14 +21,6 @@ def test_default_ctx_logger(caplog: pytest.LogCaptureFixture): assert record.message == 'foo' -def test_default_ctx_logger_only_logs_null_origin_messages(caplog: pytest.LogCaptureFixture): - build._ctx.log('foo', origin=None) - build._ctx.log('bar', origin=('bar',)) - - [record] = caplog.records - assert record.message == 'foo' - - def test_ctx_custom_logger(mocker: pytest_mock.MockerFixture): log_stub = mocker.stub('custom_logger') @@ -71,4 +63,4 @@ def test_custom_subprocess_runner_ctx_logging( build._ctx.run_subprocess([sys.executable, '-m', 'build', '-V']) assert log_stub.call_count == len(kwarg_origins) - assert [c.kwargs['origin'] for c in log_stub.call_args_list] == kwarg_origins + assert [c.kwargs['kind'] for c in log_stub.call_args_list] == kwarg_origins diff --git a/tests/test_env.py b/tests/test_env.py index 4c3c88b5..39c6d355 100644 --- a/tests/test_env.py +++ b/tests/test_env.py @@ -108,7 +108,8 @@ def test_isolated_env_log( assert [(record.levelname, record.message) for record in caplog.records] == [ ('INFO', 'Creating isolated environment: venv+pip...'), - ('INFO', 'Installing packages in isolated environment:\n- something'), + ('INFO', 'Installing packages in isolated environment:'), + ('INFO', '- something'), ]