Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use rich diagnostics for build failures #9335

Merged
merged 1 commit into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 29 additions & 19 deletions crates/uv/src/commands/build_frontend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,8 @@ async fn build_impl(
}))
.await;

for (source, result) in &results {
let mut success = true;
for (source, result) in results {
match result {
Ok(assets) => match assets {
BuiltDistributions::Wheel(wheel) => {
Expand All @@ -318,31 +319,30 @@ async fn build_impl(
}
},
Err(err) => {
let mut causes = err.chain();
#[derive(Debug, miette::Diagnostic, thiserror::Error)]
#[error("Failed to build `{source}`", source = source.cyan())]
#[diagnostic()]
struct Diagnostic {
source: String,
#[source]
cause: anyhow::Error,
}

let message = format!(
"{}: {}",
"error".red().bold(),
causes.next().unwrap().to_string().trim()
);
writeln!(printer.stderr(), "{}", source.annotate(&message))?;
let report = miette::Report::new(Diagnostic {
source: source.to_string(),
cause: err,
});
anstream::eprint!("{report:?}");

for err in causes {
writeln!(
printer.stderr(),
" {}: {}",
"Caused by".red().bold(),
err.to_string().trim()
)?;
}
success = false;
}
}
}

if results.iter().any(|(_, result)| result.is_err()) {
Ok(BuildResult::Failure)
} else {
if success {
Ok(BuildResult::Success)
} else {
Ok(BuildResult::Failure)
}
}

Expand Down Expand Up @@ -818,6 +818,16 @@ impl<'a> From<Source<'a>> for AnnotatedSource<'a> {
}
}

impl std::fmt::Display for AnnotatedSource<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Some(package) = &self.package {
write!(f, "{} @ {}", package, self.path().simplified_display())
} else {
write!(f, "{}", self.path().simplified_display())
}
}
}

#[derive(Debug, Clone, PartialEq, Eq)]
enum Source<'a> {
/// The input source is a file (i.e., a source distribution in a `.tar.gz` or `.zip` file).
Expand Down
63 changes: 36 additions & 27 deletions crates/uv/tests/it/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,8 @@ fn build() -> Result<()> {

----- stderr -----
Building source distribution...
error: [TEMP_DIR]/ does not appear to be a Python project, as neither `pyproject.toml` nor `setup.py` are present in the directory

× Failed to build `[TEMP_DIR]/`
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really know what exactly we want here... Right now, we only show the package name if they attempt to build multiple. We could also say "Failed to build source distribution for...", but it says "Building source distribution above". Or we could omit this line entirely.

╰─▶ [TEMP_DIR]/ does not appear to be a Python project, as neither `pyproject.toml` nor `setup.py` are present in the directory
"###);

// Build to a specified path.
Expand Down Expand Up @@ -738,7 +738,8 @@ fn wheel_from_sdist() -> Result<()> {
----- stdout -----

----- stderr -----
error: Pass `--wheel` explicitly to build a wheel from a source distribution
× Failed to build `[TEMP_DIR]/project/dist/project-0.1.0.tar.gz`
╰─▶ Pass `--wheel` explicitly to build a wheel from a source distribution
"###);

// Error if `--sdist` is specified.
Expand All @@ -748,7 +749,8 @@ fn wheel_from_sdist() -> Result<()> {
----- stdout -----

----- stderr -----
error: Building an `--sdist` from a source distribution is not supported
× Failed to build `[TEMP_DIR]/project/dist/project-0.1.0.tar.gz`
╰─▶ Building an `--sdist` from a source distribution is not supported
"###);

// Build the wheel from the sdist.
Expand Down Expand Up @@ -816,7 +818,8 @@ fn wheel_from_sdist() -> Result<()> {

----- stderr -----
Building wheel from source distribution...
error: `dist/project-0.1.0-py3-none-any.whl` is not a valid build source. Expected to receive a source directory, or a source distribution ending in one of: `.tar.gz`, `.zip`, `.tar.bz2`, `.tar.lz`, `.tar.lzma`, `.tar.xz`, `.tar.zst`, `.tar`, `.tbz`, `.tgz`, `.tlz`, or `.txz`.
× Failed to build `[TEMP_DIR]/project/dist/project-0.1.0-py3-none-any.whl`
╰─▶ `dist/project-0.1.0-py3-none-any.whl` is not a valid build source. Expected to receive a source directory, or a source distribution ending in one of: `.tar.gz`, `.zip`, `.tar.bz2`, `.tar.lz`, `.tar.lzma`, `.tar.xz`, `.tar.zst`, `.tar`, `.tbz`, `.tgz`, `.tlz`, or `.txz`.
"###);

Ok(())
Expand Down Expand Up @@ -888,7 +891,8 @@ fn fail() -> Result<()> {
File "<string>", line 2
from setuptools import setup
IndentationError: unexpected indent
error: Build backend failed to determine requirements with `build_sdist()` (exit status: 1)
× Failed to build `[TEMP_DIR]/project`
╰─▶ Build backend failed to determine requirements with `build_sdist()` (exit status: 1)
"###);

Ok(())
Expand Down Expand Up @@ -1328,7 +1332,8 @@ fn build_all_with_failure() -> Result<()> {
[PKG] Building wheel from source distribution...
[PKG] Building wheel from source distribution...
Successfully built dist/member_a-0.1.0.tar.gz and dist/member_a-0.1.0-py3-none-any.whl
[PKG] error: Build backend failed to determine requirements with `build_sdist()` (exit status: 1)
× Failed to build `member-b @ [TEMP_DIR]/project/packages/member_b`
╰─▶ Build backend failed to determine requirements with `build_sdist()` (exit status: 1)
Successfully built dist/project-0.1.0.tar.gz and dist/project-0.1.0-py3-none-any.whl
"###);

Expand Down Expand Up @@ -1397,9 +1402,10 @@ fn build_constraints() -> Result<()> {

----- stderr -----
Building source distribution...
error: Failed to resolve requirements from `build-system.requires`
Caused by: No solution found when resolving: `setuptools>=42`
Caused by: Because you require setuptools>=42 and setuptools==0.1.0, we can conclude that your requirements are unsatisfiable.
× Failed to build `[TEMP_DIR]/project`
├─▶ Failed to resolve requirements from `build-system.requires`
├─▶ No solution found when resolving: `setuptools>=42`
╰─▶ Because you require setuptools>=42 and setuptools==0.1.0, we can conclude that your requirements are unsatisfiable.
"###);

project
Expand Down Expand Up @@ -1458,15 +1464,16 @@ fn sha() -> Result<()> {

----- stderr -----
Building source distribution...
error: Failed to install requirements from `build-system.requires`
Caused by: Failed to download `setuptools==68.2.2`
Caused by: Hash mismatch for `setuptools==68.2.2`
× Failed to build `[TEMP_DIR]/project`
├─▶ Failed to install requirements from `build-system.requires`
├─▶ Failed to download `setuptools==68.2.2`
╰─▶ Hash mismatch for `setuptools==68.2.2`

Expected:
sha256:a248cb506794bececcddeddb1678bc722f9cfcacf02f98f7c0af6b9ed893caf2
Expected:
sha256:a248cb506794bececcddeddb1678bc722f9cfcacf02f98f7c0af6b9ed893caf2

Computed:
sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a
Computed:
sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a
"###);

project
Expand All @@ -1488,15 +1495,16 @@ fn sha() -> Result<()> {

----- stderr -----
Building source distribution...
error: Failed to install requirements from `build-system.requires`
Caused by: Failed to download `setuptools==68.2.2`
Caused by: Hash mismatch for `setuptools==68.2.2`
× Failed to build `[TEMP_DIR]/project`
├─▶ Failed to install requirements from `build-system.requires`
├─▶ Failed to download `setuptools==68.2.2`
╰─▶ Hash mismatch for `setuptools==68.2.2`

Expected:
sha256:a248cb506794bececcddeddb1678bc722f9cfcacf02f98f7c0af6b9ed893caf2
Expected:
sha256:a248cb506794bececcddeddb1678bc722f9cfcacf02f98f7c0af6b9ed893caf2

Computed:
sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a
Computed:
sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a
"###);

project
Expand All @@ -1521,9 +1529,10 @@ fn sha() -> Result<()> {

----- stderr -----
Building source distribution...
error: Failed to resolve requirements from `build-system.requires`
Caused by: No solution found when resolving: `setuptools>=42`
Caused by: In `--require-hashes` mode, all requirements must be pinned upfront with `==`, but found: `setuptools`
× Failed to build `[TEMP_DIR]/project`
├─▶ Failed to resolve requirements from `build-system.requires`
├─▶ No solution found when resolving: `setuptools>=42`
╰─▶ In `--require-hashes` mode, all requirements must be pinned upfront with `==`, but found: `setuptools`
"###);

project
Expand Down
Loading