diff --git a/docs/projects.md b/docs/projects.md index 3e3ce6a8..e57078ba 100644 --- a/docs/projects.md +++ b/docs/projects.md @@ -49,7 +49,7 @@ In addition, most of the [RAPIDSAI](https://github.com/rapidsai) projects use sc * CuDF ([source](https://github.com/rapidsai/cudf/blob/HEAD/python/cudf/pyproject.toml)) * CuGraph ([source](https://github.com/rapidsai/cugraph/blob/HEAD/python/cugraph/pyproject.toml)) -* CuML ([source](https://github.com/rapidsai/cuml/blob/HEAD/python/pyproject.toml)) +* CuML ([source](https://github.com/rapidsai/cuml/blob/HEAD/python/cuml/pyproject.toml)) * CuSpatial ([source](https://github.com/rapidsai/cuspatial/blob/HEAD/python/cuspatial/pyproject.toml)) * RMM ([source](https://github.com/rapidsai/rmm/blob/HEAD/python/rmm/pyproject.toml)) * Raft ([source](https://github.com/rapidsai/raft/blob/HEAD/python/pylibraft/pyproject.toml)) diff --git a/src/scikit_build_core/_logging.py b/src/scikit_build_core/_logging.py index 941510e3..c60b4201 100644 --- a/src/scikit_build_core/_logging.py +++ b/src/scikit_build_core/_logging.py @@ -1,13 +1,22 @@ from __future__ import annotations import contextlib +import functools import logging import os import re import sys -from typing import Any +from typing import Any, NoReturn -__all__ = ["ScikitBuildLogger", "logger", "raw_logger", "rich_print", "LEVEL_VALUE"] +__all__ = [ + "ScikitBuildLogger", + "logger", + "raw_logger", + "rich_print", + "rich_warning", + "rich_error", + "LEVEL_VALUE", +] def __dir__() -> list[str]: @@ -147,3 +156,13 @@ def rich_print(*args: object, **kwargs: object) -> None: if args != args_2: args_2 = (*args_2[:-1], args_2[-1] + colors()["reset"]) print(*args_2, **kwargs, flush=True) # type: ignore[call-overload] # noqa: T201 + + +@functools.lru_cache(maxsize=None) +def rich_warning(*args: object, **kwargs: object) -> None: + rich_print("[red][yellow]WARNING:[/bold]", *args, **kwargs) + + +def rich_error(*args: object, **kwargs: object) -> NoReturn: + rich_print("[red][bold]ERROR:[/bold]", *args, **kwargs) + raise SystemExit(7) diff --git a/src/scikit_build_core/settings/skbuild_read_settings.py b/src/scikit_build_core/settings/skbuild_read_settings.py index ea6e5263..15bb6941 100644 --- a/src/scikit_build_core/settings/skbuild_read_settings.py +++ b/src/scikit_build_core/settings/skbuild_read_settings.py @@ -15,7 +15,7 @@ from .. import __version__ from .._compat import tomllib -from .._logging import logger, rich_print +from .._logging import logger, rich_error, rich_print, rich_warning from ..errors import CMakeConfigError from .auto_cmake_version import find_min_cmake_version from .auto_requires import get_min_requires @@ -180,25 +180,22 @@ def _handle_minimum_version( and minimum_version is not None and minimum_version < Version("0.8") ): - rich_print( - f"[red][bold]ERROR:[/bold] Cannot set {name}.version if minimum-version is set to less than 0.8 (which is where it was introduced)" + rich_error( + f"Cannot set {name}.version if minimum-version is set to less than 0.8 (which is where it was introduced)" ) - raise SystemExit(7) # Backwards compatibility for minimum_version if dc.minimum_version is not None: msg = f"Use {name}.version instead of {name}.minimum-version with scikit-build-core >= 0.8" if minimum_version is None: - rich_print(f"[yellow][bold]WARNING:[/bold] {msg}") + rich_warning(msg) elif minimum_version >= Version("0.8"): - rich_print(f"[red][bold]ERROR:[/bold] {msg}") - raise SystemExit(7) + rich_error(msg) if dc.version != version_default: - rich_print( - f"[red][bold]ERROR:[/bold] Cannot set both {name}.minimum_version and {name}.version; use version only for scikit-build-core >= 0.8." + rich_error( + f"Cannot set both {name}.minimum_version and {name}.version; use version only for scikit-build-core >= 0.8." ) - raise SystemExit(7) dc.version = SpecifierSet(f">={dc.minimum_version}") @@ -216,33 +213,28 @@ def _handle_move( """ if after and minimum_version is not None and minimum_version < introduced_in: - rich_print( - f"[red][bold]ERROR:[/bold] Cannot set {after_name} if minimum-version is set to less than {introduced_in} (which is where it was introduced)" + rich_error( + f"Cannot set {after_name} if minimum-version is set to less than {introduced_in} (which is where it was introduced)" ) - raise SystemExit(7) if ( before is not None and minimum_version is not None and minimum_version >= introduced_in ): - rich_print( - f"[red][bold]ERROR:[/bold] Cannot set {before_name} if minimum-version is set to {introduced_in} or higher" + rich_error( + f"Cannot set {before_name} if minimum-version is set to {introduced_in} or higher" ) - raise SystemExit(7) if before is not None and after: - rich_print( - f"[red][bold]ERROR:[/bold] Cannot set {before_name} and {after_name} at the same time" - ) - raise SystemExit(7) + rich_error(f"Cannot set {before_name} and {after_name} at the same time") if before is None: return after if minimum_version is None: - rich_print( - f"[yellow][bold]WARNING:[/bold] Use {after_name} instead of {before_name} for scikit-build-core >= {introduced_in}" + rich_warning( + f"Use {after_name} instead of {before_name} for scikit-build-core >= {introduced_in}" ) return before @@ -350,11 +342,10 @@ def __init__( reqlist = pyproject["build-system"]["requires"] min_v = get_min_requires("scikit-build-core", reqlist) if min_v is None: - rich_print( - "[red][bold]ERROR:[/bold] scikit-build-core needs a min version in " + rich_error( + "scikit-build-core needs a min version in " "build-system.requires to use minimum-version='build-system.requires'" ) - raise SystemExit(7) pyproject["tool"]["scikit-build"]["minimum-version"] = str(min_v) toml_srcs = [TOMLSource("tool", "scikit-build", settings=pyproject)] @@ -401,16 +392,10 @@ def __init__( if self.settings.editable.rebuild: if self.settings.editable.mode == "inplace": - rich_print( - "[red][bold]ERROR:[/bold] editable rebuild is incompatible with inplace mode" - ) - raise SystemExit(7) + rich_error("editable rebuild is incompatible with inplace mode") if not self.settings.build_dir: - rich_print( - "[red][bold]ERROR:[/bold] editable mode with rebuild requires build-dir" - ) - raise SystemExit(7) + rich_error("editable mode with rebuild requires build-dir") install_policy = ( self.settings.minimum_version is None @@ -435,29 +420,27 @@ def __init__( new_min_cmake = find_min_cmake_version(f.read()) except FileNotFoundError: new_min_cmake = "3.15" - rich_print( - "[red][bold]WARNING:[/bold] CMakeLists.txt not found when looking for minimum CMake version. " + rich_warning( + "CMakeLists.txt not found when looking for minimum CMake version. " "Report this or (and) set manually to avoid this warning. Using 3.15 as a fall-back." ) if new_min_cmake is None: if force_auto_cmake: - rich_print( - "[red][bold]ERROR:[/bold] Minimum CMake version set as " + rich_error( + "Minimum CMake version set as " "'CMakeLists.txt' wasn't able to find minimum version setting. " "If the CMakeLists.txt is valid, this might be a bug in our search algorithm." ) - raise SystemExit(7) - rich_print( - "[red][bold]WARNING:[/bold] Minimum CMake version not found in CMakeLists.txt. " + rich_warning( + "Minimum CMake version not found in CMakeLists.txt. " "If the CMakeLists.txt is valid, this might be a bug in our search algorithm. Report " "this or (and) set manually to avoid this warning." ) new_min_cmake = "3.15" if Version(new_min_cmake) < Version("3.15"): - rich_print( - "[red][bold]WARNING:[/bold] Minimum CMake version set as " - "'CMakeLists.txt' is less than 3.15. " + rich_warning( + "Minimum CMake version set as 'CMakeLists.txt' is less than 3.15. " "This is not supported by scikit-build-core; set manually or increase to avoid this warning." ) new_min_cmake = "3.15" @@ -528,27 +511,20 @@ def validate_may_exit(self) -> None: for key, value in self.settings.metadata.items(): if "provider" not in value: sys.stdout.flush() - rich_print( - f"[red][bold]ERROR:[/bold] provider= must be provided in {key!r}:" - ) - raise SystemExit(7) + rich_error(f"provider= must be provided in {key!r}:") if not self.settings.experimental and ( "provider-path" in value or not value["provider"].startswith("scikit_build_core.") ): sys.stdout.flush() - rich_print( - "[red][bold]ERROR:[/bold] experimental must be enabled currently to use plugins not provided by scikit-build-core" + rich_error( + "experimental must be enabled currently to use plugins not provided by scikit-build-core" ) - raise SystemExit(7) for gen in self.settings.generate: if not gen.template and not gen.template_path: sys.stdout.flush() - rich_print( - "[red][bold]ERROR:[/bold] template= or template-path= must be provided in generate" - ) - raise SystemExit(7) + rich_error("template= or template-path= must be provided in generate") @classmethod def from_file( diff --git a/tests/test_skbuild_settings.py b/tests/test_skbuild_settings.py index 2d76947e..da4a7580 100644 --- a/tests/test_skbuild_settings.py +++ b/tests/test_skbuild_settings.py @@ -11,6 +11,7 @@ from packaging.specifiers import SpecifierSet from packaging.version import Version +import scikit_build_core._logging import scikit_build_core.settings.skbuild_read_settings from scikit_build_core.settings.skbuild_model import GenerateSettings from scikit_build_core.settings.skbuild_read_settings import SettingsReader @@ -684,6 +685,7 @@ def test_skbuild_settings_auto_cmake_warning( monkeypatch.setattr( scikit_build_core.settings.skbuild_read_settings, "__version__", "0.10.0" ) + scikit_build_core._logging.rich_warning.cache_clear() pyproject_toml = tmp_path / "pyproject.toml" pyproject_toml.write_text( textwrap.dedent(