feat: Print FatalError messages using Logger (#2292)

* feat: Print FatalError messages using Logger

This makes them appear GHA annotations in CI logs, which makes them easier to spot. I've also added the "cibuildwheel: " prefix to those errors, I think it helps when viewing a log to know which tool is talking to you - it can be difficult to understand with build tools.

* Nicer error message on invalid architecture

* Fix some message formatting and test expectations
This commit is contained in:
Joe Rickerby
2025-03-01 10:47:44 +01:00
committed by GitHub
parent 708cf1d32b
commit 9e72cd9b54
6 changed files with 28 additions and 23 deletions
+4 -5
View File
@@ -68,7 +68,7 @@ def main() -> None:
if log.step_active:
log.step_end_with_error(message)
else:
print(f"cibuildwheel: {message}", file=sys.stderr)
log.error(message)
if global_options.print_traceback_on_error:
traceback.print_exc(file=sys.stderr)
@@ -253,7 +253,7 @@ def _compute_platform_auto() -> PlatformName:
return "windows"
else:
msg = (
'cibuildwheel: Unable to detect platform from "sys.platform". cibuildwheel doesn\'t '
'Unable to detect platform from "sys.platform". cibuildwheel doesn\'t '
"support building wheels for this platform. You might be able to build for a different "
"platform using the --platform argument. Check --help output for more information."
)
@@ -343,9 +343,8 @@ def print_new_wheels(msg: str, output_dir: Path) -> Generator[None, None, None]:
def build_in_directory(args: CommandLineArguments) -> None:
platform: PlatformName = _compute_platform(args)
if platform == "pyodide" and sys.platform == "win32":
msg = "cibuildwheel: Building for pyodide is not supported on Windows"
print(msg, file=sys.stderr)
sys.exit(2)
msg = "Building for pyodide is not supported on Windows"
raise errors.ConfigurationError(msg)
options = compute_options(platform=platform, command_line_arguments=args, env=os.environ)
+7 -1
View File
@@ -8,6 +8,8 @@ from collections.abc import Set
from enum import StrEnum, auto
from typing import Final, Literal
from cibuildwheel import errors
from .typing import PlatformName
PRETTY_NAMES: Final[dict[PlatformName, str]] = {
@@ -78,7 +80,11 @@ class Architecture(StrEnum):
elif arch_str == "auto32":
result |= Architecture.bitness_archs(platform=platform, bitness="32")
else:
result.add(Architecture(arch_str))
try:
result.add(Architecture(arch_str))
except ValueError as e:
msg = f"Invalid architecture '{arch_str}'"
raise errors.ConfigurationError(msg) from e
return result
@staticmethod
+6 -6
View File
@@ -451,12 +451,12 @@ def build(options: Options, tmp_path: Path) -> None: # noqa: ARG001
except subprocess.CalledProcessError as error:
msg = unwrap(
f"""
cibuildwheel: {build_step.container_engine.name} not found. An
OCI exe like Docker or Podman is required to run Linux builds.
If you're building on Travis CI, add `services: [docker]` to
your .travis.yml. If you're building on Circle CI in Linux,
add a `setup_remote_docker` step to your .circleci/config.yml.
If you're building on Cirrus CI, use `docker_builder` task.
{build_step.container_engine.name} not found. An OCI exe like
Docker or Podman is required to run Linux builds. If you're
building on Travis CI, add `services: [docker]` to your
.travis.yml. If you're building on Circle CI in Linux, add a
`setup_remote_docker` step to your .circleci/config.yml. If
you're building on Cirrus CI, use `docker_builder` task.
"""
)
raise errors.ConfigurationError(msg) from error
+6 -6
View File
@@ -159,24 +159,24 @@ class Logger:
def notice(self, message: str) -> None:
if self.fold_mode == "github":
print(f"::notice::{message}\n", file=sys.stderr)
print(f"::notice::cibuildwheel: {message}\n", file=sys.stderr)
else:
c = self.colors
print(f"{c.bold}Note{c.end}: {message}\n", file=sys.stderr)
print(f"cibuildwheel: {c.bold}note{c.end}: {message}\n", file=sys.stderr)
def warning(self, message: str) -> None:
if self.fold_mode == "github":
print(f"::warning::{message}\n", file=sys.stderr)
print(f"::warning::cibuildwheel: {message}\n", file=sys.stderr)
else:
c = self.colors
print(f"{c.yellow}Warning{c.end}: {message}\n", file=sys.stderr)
print(f"cibuildwheel: {c.yellow}warning{c.end}: {message}\n", file=sys.stderr)
def error(self, error: BaseException | str) -> None:
if self.fold_mode == "github":
print(f"::error::{error}\n", file=sys.stderr)
print(f"::error::cibuildwheel: {error}\n", file=sys.stderr)
else:
c = self.colors
print(f"{c.bright_red}Error{c.end}: {error}\n", file=sys.stderr)
print(f"cibuildwheel: {c.bright_red}error{c.end}: {error}\n", file=sys.stderr)
@property
def step_active(self) -> bool:
+2 -2
View File
@@ -265,7 +265,7 @@ def setup_python(
which_python = call("which", "python", env=env, capture_stdout=True).strip()
print(which_python)
if which_python != str(venv_bin_path / "python"):
msg = "cibuildwheel: python available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it."
msg = "python available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it."
raise errors.FatalError(msg)
call("python", "--version", env=env)
@@ -275,7 +275,7 @@ def setup_python(
which_pip = call("which", "pip", env=env, capture_stdout=True).strip()
print(which_pip)
if which_pip != str(venv_bin_path / "pip"):
msg = "cibuildwheel: pip available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it."
msg = "pip available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it."
raise errors.FatalError(msg)
call("pip", "--version", env=env)
+3 -3
View File
@@ -41,7 +41,7 @@ def test_unknown_platform_on_ci(monkeypatch, capsys):
assert exit.value.code == 2
_, err = capsys.readouterr()
assert 'cibuildwheel: Unable to detect platform from "sys.platform"' in err
assert 'Unable to detect platform from "sys.platform"' in err
def test_unknown_platform(monkeypatch, capsys):
@@ -52,7 +52,7 @@ def test_unknown_platform(monkeypatch, capsys):
_, err = capsys.readouterr()
assert exit.value.code == 2
assert "cibuildwheel: Unsupported platform: nonexistent" in err
assert "Unsupported platform: nonexistent" in err
def test_platform_argument(platform, intercepted_build_args, monkeypatch):
@@ -276,4 +276,4 @@ def test_pyodide_on_windows(monkeypatch, capsys):
_, err = capsys.readouterr()
assert exit.value.code == 2
assert "cibuildwheel: Building for pyodide is not supported on Windows" in err
assert "Building for pyodide is not supported on Windows" in err