Use consistent formatting for build system errors (#9340)
Some checks are pending
CI / mkdocs (push) Waiting to run
CI / check system | python on macos aarch64 (push) Blocked by required conditions
CI / Determine changes (push) Waiting to run
CI / check windows trampoline | i686 (push) Blocked by required conditions
CI / lint (push) Waiting to run
CI / cargo clippy | ubuntu (push) Blocked by required conditions
CI / cargo clippy | windows (push) Blocked by required conditions
CI / cargo dev generate-all (push) Blocked by required conditions
CI / cargo shear (push) Waiting to run
CI / check windows trampoline | x86_64 (push) Blocked by required conditions
CI / cargo test | ubuntu (push) Blocked by required conditions
CI / cargo test | macos (push) Blocked by required conditions
CI / cargo test | windows (push) Blocked by required conditions
CI / check windows trampoline | aarch64 (push) Blocked by required conditions
CI / test windows trampoline | i686 (push) Blocked by required conditions
CI / test windows trampoline | x86_64 (push) Blocked by required conditions
CI / typos (push) Waiting to run
CI / build binary | linux (push) Blocked by required conditions
CI / build binary | macos aarch64 (push) Blocked by required conditions
CI / build binary | macos x86_64 (push) Blocked by required conditions
CI / build binary | windows (push) Blocked by required conditions
CI / cargo build (msrv) (push) Blocked by required conditions
CI / build binary | freebsd (push) Blocked by required conditions
CI / ecosystem test | prefecthq/prefect (push) Blocked by required conditions
CI / ecosystem test | pallets/flask (push) Blocked by required conditions
CI / integration test | conda on ubuntu (push) Blocked by required conditions
CI / integration test | free-threaded on linux (push) Blocked by required conditions
CI / integration test | free-threaded on windows (push) Blocked by required conditions
CI / integration test | pypy on ubuntu (push) Blocked by required conditions
CI / integration test | pypy on windows (push) Blocked by required conditions
CI / integration test | graalpy on ubuntu (push) Blocked by required conditions
CI / integration test | graalpy on windows (push) Blocked by required conditions
CI / integration test | github actions (push) Blocked by required conditions
CI / integration test | determine publish changes (push) Blocked by required conditions
CI / check system | alpine (push) Blocked by required conditions
CI / integration test | uv publish (push) Blocked by required conditions
CI / check cache | ubuntu (push) Blocked by required conditions
CI / check cache | macos aarch64 (push) Blocked by required conditions
CI / check system | python on debian (push) Blocked by required conditions
CI / check system | python on fedora (push) Blocked by required conditions
CI / check system | python on ubuntu (push) Blocked by required conditions
CI / check system | python on opensuse (push) Blocked by required conditions
CI / check system | python on rocky linux 8 (push) Blocked by required conditions
CI / check system | python on rocky linux 9 (push) Blocked by required conditions
CI / check system | pypy on ubuntu (push) Blocked by required conditions
CI / check system | pyston (push) Blocked by required conditions
CI / check system | homebrew python on macos aarch64 (push) Blocked by required conditions
CI / check system | python on macos x86_64 (push) Blocked by required conditions
CI / check system | python3.10 on windows (push) Blocked by required conditions
CI / check system | python3.10 on windows x86 (push) Blocked by required conditions
CI / check system | python3.13 on windows (push) Blocked by required conditions
CI / check system | python3.12 via chocolatey (push) Blocked by required conditions
CI / check system | python3.9 via pyenv (push) Blocked by required conditions
CI / check system | python3.13 (push) Blocked by required conditions
CI / check system | conda3.11 on linux (push) Blocked by required conditions
CI / check system | conda3.8 on linux (push) Blocked by required conditions
CI / check system | conda3.11 on macos (push) Blocked by required conditions
CI / check system | conda3.8 on macos (push) Blocked by required conditions
CI / check system | conda3.11 on windows (push) Blocked by required conditions
CI / check system | conda3.8 on windows (push) Blocked by required conditions
CI / check system | amazonlinux (push) Blocked by required conditions
CI / check system | embedded python3.10 on windows (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions

## Summary

These look pretty different from the help / hint messages we show on
resolver failure. I've added color, backticks, and a "hint:" prefix.

Before:

![Screenshot 2024-11-21 at 5 45
40 PM](https://github.com/user-attachments/assets/71ee2551-8fc6-4715-a9d7-68055cd34547)

After:

![Screenshot 2024-11-21 at 6 05
31 PM](https://github.com/user-attachments/assets/24e7fb46-49aa-4b6f-a442-115a71a3414b)
This commit is contained in:
Charlie Marsh 2024-11-27 09:22:53 -05:00 committed by GitHub
parent 0cd9c542ad
commit ee84620e90
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 127 additions and 99 deletions

View file

@ -108,17 +108,22 @@ impl Display for MissingHeaderCause {
{
write!(
f,
"This error likely indicates that you need to install a library that provides \"{header}\" for {package_name}@{package_version}",
"This error likely indicates that you need to install a library that provides \"{}\" for `{}`",
header.cyan(),
format!("{package_name}@{package_version}").cyan(),
)
} else if let Some(version_id) = &self.version_id {
write!(
f,
"This error likely indicates that you need to install a library that provides \"{header}\" for {version_id}",
"This error likely indicates that you need to install a library that provides \"{}\" for `{}`",
header.cyan(),
version_id.cyan(),
)
} else {
write!(
f,
"This error likely indicates that you need to install a library that provides \"{header}\"",
"This error likely indicates that you need to install a library that provides \"{}\"",
header.cyan(),
)
}
}
@ -128,17 +133,25 @@ impl Display for MissingHeaderCause {
{
write!(
f,
"This error likely indicates that you need to install the library that provides a shared library for {library} for {package_name}@{package_version} (e.g., lib{library}-dev)",
"This error likely indicates that you need to install the library that provides a shared library for `{}` for `{}` (e.g., `{}`)",
library.cyan(),
format!("{package_name}@{package_version}").cyan(),
format!("lib{library}-dev").cyan(),
)
} else if let Some(version_id) = &self.version_id {
write!(
f,
"This error likely indicates that you need to install the library that provides a shared library for {library} for {version_id} (e.g., lib{library}-dev)",
"This error likely indicates that you need to install the library that provides a shared library for `{}` for `{}` (e.g., `{}`)",
library.cyan(),
version_id.cyan(),
format!("lib{library}-dev").cyan(),
)
} else {
write!(
f,
"This error likely indicates that you need to install the library that provides a shared library for {library} (e.g., lib{library}-dev)",
"This error likely indicates that you need to install the library that provides a shared library for `{}` (e.g., `{}`)",
library.cyan(),
format!("lib{library}-dev").cyan(),
)
}
}
@ -148,17 +161,36 @@ impl Display for MissingHeaderCause {
{
write!(
f,
"This error likely indicates that {package_name}@{package_version} depends on {package}, but doesn't declare it as a build dependency. If {package_name} is a first-party package, consider adding {package} to its `build-system.requires`. Otherwise, `uv pip install {package}` into the environment and re-run with `--no-build-isolation`."
"This error likely indicates that `{}` depends on `{}`, but doesn't declare it as a build dependency. If `{}` is a first-party package, consider adding `{}` to its `{}`. Otherwise, `{}` into the environment and re-run with `{}`.",
format!("{package_name}@{package_version}").cyan(),
package.cyan(),
package_name.cyan(),
package.cyan(),
"build-system.requires".green(),
format!("uv pip install {package}").green(),
"--no-build-isolation".green(),
)
} else if let Some(version_id) = &self.version_id {
write!(
f,
"This error likely indicates that {version_id} depends on {package}, but doesn't declare it as a build dependency. If {version_id} is a first-party package, consider adding {package} to its `build-system.requires`. Otherwise, `uv pip install {package}` into the environment and re-run with `--no-build-isolation`.",
"This error likely indicates that `{}` depends on `{}`, but doesn't declare it as a build dependency. If `{}` is a first-party package, consider adding `{}` to its `{}`. Otherwise, `{}` into the environment and re-run with `{}`.",
version_id.cyan(),
package.cyan(),
version_id.cyan(),
package.cyan(),
"build-system.requires".green(),
format!("uv pip install {package}").green(),
"--no-build-isolation".green(),
)
} else {
write!(
f,
"This error likely indicates that a package depends on {package}, but doesn't declare it as a build dependency. If the package is a first-party package, consider adding {package} to its `build-system.requires`. Otherwise, `uv pip install {package}` into the environment and re-run with `--no-build-isolation`.",
"This error likely indicates that a package depends on `{}`, but doesn't declare it as a build dependency. If the package is a first-party package, consider adding `{}` to its `{}`. Otherwise, `{}` into the environment and re-run with `{}`.",
package.cyan(),
package.cyan(),
"build-system.requires".green(),
format!("uv pip install {package}").green(),
"--no-build-isolation".green(),
)
}
}
@ -168,12 +200,18 @@ impl Display for MissingHeaderCause {
{
write!(
f,
"{package} was removed from the standard library in Python {version}. Consider adding a constraint (like `{package_name} >{package_version}`) to avoid building a version of {package_name} that depends on {package}.",
"`{}` was removed from the standard library in Python {version}. Consider adding a constraint (like `{}`) to avoid building a version of `{}` that depends on `{}`.",
package.cyan(),
format!("{package_name} >{package_version}").green(),
package_name.cyan(),
package.cyan(),
)
} else {
write!(
f,
"{package} was removed from the standard library in Python {version}. Consider adding a constraint to avoid building a package-version that depends on {package}.",
"`{}` was removed from the standard library in Python {version}. Consider adding a constraint to avoid building a package that depends on `{}`.",
package.cyan(),
package.cyan(),
)
}
}
@ -219,7 +257,6 @@ pub struct MissingHeaderError {
exit_code: ExitStatus,
stdout: Vec<String>,
stderr: Vec<String>,
#[source]
cause: MissingHeaderCause,
}
@ -227,21 +264,21 @@ impl Display for MissingHeaderError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{} ({})", self.message, self.exit_code)?;
let mut non_empty = false;
if self.stdout.iter().any(|line| !line.trim().is_empty()) {
write!(f, "\n\n{}\n{}", "[stdout]".red(), self.stdout.join("\n"))?;
non_empty = true;
}
if self.stderr.iter().any(|line| !line.trim().is_empty()) {
write!(f, "\n\n{}\n{}", "[stderr]".red(), self.stderr.join("\n"))?;
non_empty = true;
}
if non_empty {
writeln!(f)?;
}
write!(
f,
"\n\n{}{} {}",
"hint".bold().cyan(),
":".bold(),
self.cause
)?;
Ok(())
}
@ -401,11 +438,9 @@ mod test {
| ^~~~~~~~~~~~~~~~~~~
compilation terminated.
error: command '/usr/bin/gcc' failed with exit code 1
hint: This error likely indicates that you need to install a library that provides "graphviz/cgraph.h" for `pygraphviz-1.11`
"###);
insta::assert_snapshot!(
std::error::Error::source(&err).unwrap(),
@r###"This error likely indicates that you need to install a library that provides "graphviz/cgraph.h" for pygraphviz-1.11"###
);
}
#[test]
@ -447,11 +482,9 @@ mod test {
/usr/bin/ld: cannot find -lncurses: No such file or directory
collect2: error: ld returned 1 exit status
error: command '/usr/bin/x86_64-linux-gnu-gcc' failed with exit code 1
hint: This error likely indicates that you need to install the library that provides a shared library for `ncurses` for `pygraphviz-1.11` (e.g., `libncurses-dev`)
"###);
insta::assert_snapshot!(
std::error::Error::source(&err).unwrap(),
@"This error likely indicates that you need to install the library that provides a shared library for ncurses for pygraphviz-1.11 (e.g., libncurses-dev)"
);
}
#[test]
@ -495,11 +528,9 @@ mod test {
or: setup.py cmd --help
error: invalid command 'bdist_wheel'
hint: This error likely indicates that `pygraphviz-1.11` depends on `wheel`, but doesn't declare it as a build dependency. If `pygraphviz-1.11` is a first-party package, consider adding `wheel` to its `build-system.requires`. Otherwise, `uv pip install wheel` into the environment and re-run with `--no-build-isolation`.
"###);
insta::assert_snapshot!(
std::error::Error::source(&err).unwrap(),
@"This error likely indicates that pygraphviz-1.11 depends on wheel, but doesn't declare it as a build dependency. If pygraphviz-1.11 is a first-party package, consider adding wheel to its `build-system.requires`. Otherwise, `uv pip install wheel` into the environment and re-run with `--no-build-isolation`."
);
}
#[test]
@ -536,10 +567,8 @@ mod test {
[stderr]
import distutils.core
ModuleNotFoundError: No module named 'distutils'
hint: `distutils` was removed from the standard library in Python 3.12. Consider adding a constraint (like `pygraphviz >1.11`) to avoid building a version of `pygraphviz` that depends on `distutils`.
"###);
insta::assert_snapshot!(
std::error::Error::source(&err).unwrap(),
@"distutils was removed from the standard library in Python 3.12. Consider adding a constraint (like `pygraphviz >1.11`) to avoid building a version of pygraphviz that depends on distutils."
);
}
}