Improve error message copy for failed builds (#7849)

This commit is contained in:
Charlie Marsh 2024-10-01 13:11:09 -04:00 committed by GitHub
parent 6c7f8bb564
commit 6aa1e012ed
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 36 additions and 42 deletions

View file

@ -63,13 +63,15 @@ pub enum Error {
InvalidPyprojectTomlSchema(#[from] toml_edit::de::Error), InvalidPyprojectTomlSchema(#[from] toml_edit::de::Error),
#[error("Editable installs with setup.py legacy builds are unsupported, please specify a build backend in pyproject.toml")] #[error("Editable installs with setup.py legacy builds are unsupported, please specify a build backend in pyproject.toml")]
EditableSetupPy, EditableSetupPy,
#[error("Failed to resolve requirements from {0}")]
RequirementsResolve(&'static str, #[source] anyhow::Error),
#[error("Failed to install requirements from {0}")] #[error("Failed to install requirements from {0}")]
RequirementsInstall(&'static str, #[source] anyhow::Error), RequirementsInstall(&'static str, #[source] anyhow::Error),
#[error("Failed to create temporary virtualenv")] #[error("Failed to create temporary virtualenv")]
Virtualenv(#[from] uv_virtualenv::Error), Virtualenv(#[from] uv_virtualenv::Error),
#[error("Failed to run `{0}`")] #[error("Failed to run `{0}`")]
CommandFailed(PathBuf, #[source] io::Error), CommandFailed(PathBuf, #[source] io::Error),
#[error("{message} with {exit_code}\n--- stdout:\n{stdout}\n--- stderr:\n{stderr}\n---")] #[error("{message} ({exit_code})\n--- stdout:\n{stdout}\n--- stderr:\n{stderr}\n---")]
BuildBackendOutput { BuildBackendOutput {
message: String, message: String,
exit_code: ExitStatus, exit_code: ExitStatus,
@ -77,7 +79,7 @@ pub enum Error {
stderr: String, stderr: String,
}, },
/// Nudge the user towards installing the missing dev library /// Nudge the user towards installing the missing dev library
#[error("{message} with {exit_code}\n--- stdout:\n{stdout}\n--- stderr:\n{stderr}\n---")] #[error("{message} ({exit_code})\n--- stdout:\n{stdout}\n--- stderr:\n{stderr}\n---")]
MissingHeaderOutput { MissingHeaderOutput {
message: String, message: String,
exit_code: ExitStatus, exit_code: ExitStatus,
@ -86,12 +88,12 @@ pub enum Error {
#[source] #[source]
missing_header_cause: MissingHeaderCause, missing_header_cause: MissingHeaderCause,
}, },
#[error("{message} with {exit_code}")] #[error("{message} ({exit_code})")]
BuildBackend { BuildBackend {
message: String, message: String,
exit_code: ExitStatus, exit_code: ExitStatus,
}, },
#[error("{message} with {exit_code}")] #[error("{message} ({exit_code})")]
MissingHeader { MissingHeader {
message: String, message: String,
exit_code: ExitStatus, exit_code: ExitStatus,
@ -327,7 +329,7 @@ mod test {
// Unix uses exit status, Windows uses exit code. // Unix uses exit status, Windows uses exit code.
let formatted = err.to_string().replace("exit status: ", "exit code: "); let formatted = err.to_string().replace("exit status: ", "exit code: ");
insta::assert_snapshot!(formatted, @r###" insta::assert_snapshot!(formatted, @r###"
Failed building wheel through setup.py with exit code: 0 Failed building wheel through setup.py (exit code: 0)
--- stdout: --- stdout:
running bdist_wheel running bdist_wheel
running build running build
@ -382,7 +384,7 @@ mod test {
// Unix uses exit status, Windows uses exit code. // Unix uses exit status, Windows uses exit code.
let formatted = err.to_string().replace("exit status: ", "exit code: "); let formatted = err.to_string().replace("exit status: ", "exit code: ");
insta::assert_snapshot!(formatted, @r###" insta::assert_snapshot!(formatted, @r###"
Failed building wheel through setup.py with exit code: 0 Failed building wheel through setup.py (exit code: 0)
--- stdout: --- stdout:
--- stderr: --- stderr:
@ -430,7 +432,7 @@ mod test {
// Unix uses exit status, Windows uses exit code. // Unix uses exit status, Windows uses exit code.
let formatted = err.to_string().replace("exit status: ", "exit code: "); let formatted = err.to_string().replace("exit status: ", "exit code: ");
insta::assert_snapshot!(formatted, @r###" insta::assert_snapshot!(formatted, @r###"
Failed building wheel through setup.py with exit code: 0 Failed building wheel through setup.py (exit code: 0)
--- stdout: --- stdout:
--- stderr: --- stderr:
@ -476,7 +478,7 @@ mod test {
// Unix uses exit status, Windows uses exit code. // Unix uses exit status, Windows uses exit code.
let formatted = err.to_string().replace("exit status: ", "exit code: "); let formatted = err.to_string().replace("exit status: ", "exit code: ");
insta::assert_snapshot!(formatted, @r###" insta::assert_snapshot!(formatted, @r###"
Failed building wheel through setup.py with exit code: 0 Failed building wheel through setup.py (exit code: 0)
--- stdout: --- stdout:
--- stderr: --- stderr:

View file

@ -310,9 +310,7 @@ impl SourceBuild {
build_context build_context
.install(&resolved_requirements, &venv) .install(&resolved_requirements, &venv)
.await .await
.map_err(|err| { .map_err(|err| Error::RequirementsInstall("`build-system.requires`", err))?;
Error::RequirementsInstall("`build-system.requires` (install)", err)
})?;
} else { } else {
debug!("Proceeding without build isolation"); debug!("Proceeding without build isolation");
} }
@ -407,9 +405,7 @@ impl SourceBuild {
let resolved_requirements = build_context let resolved_requirements = build_context
.resolve(&default_backend.requirements) .resolve(&default_backend.requirements)
.await .await
.map_err(|err| { .map_err(|err| Error::RequirementsResolve("`setup.py` build", err))?;
Error::RequirementsInstall("`setup.py` build (resolve)", err)
})?;
*resolution = Some(resolved_requirements.clone()); *resolution = Some(resolved_requirements.clone());
resolved_requirements resolved_requirements
} }
@ -417,9 +413,7 @@ impl SourceBuild {
build_context build_context
.resolve(&pep517_backend.requirements) .resolve(&pep517_backend.requirements)
.await .await
.map_err(|err| { .map_err(|err| Error::RequirementsResolve("`build-system.requires`", err))?
Error::RequirementsInstall("`build-system.requires` (resolve)", err)
})?
}, },
) )
} }
@ -808,7 +802,7 @@ async fn create_pep517_build_environment(
.await?; .await?;
if !output.status.success() { if !output.status.success() {
return Err(Error::from_command_output( return Err(Error::from_command_output(
format!("Build backend failed to determine extra requires with `build_{build_kind}()`"), format!("Build backend failed to determine requirements with `build_{build_kind}()`"),
&output, &output,
level, level,
package_name, package_name,
@ -821,7 +815,7 @@ async fn create_pep517_build_environment(
let contents = fs_err::read(&outfile).map_err(|err| { let contents = fs_err::read(&outfile).map_err(|err| {
Error::from_command_output( Error::from_command_output(
format!( format!(
"Build backend failed to read extra requires from `get_requires_for_build_{build_kind}`: {err}" "Build backend failed to read requirements from `get_requires_for_build_{build_kind}`: {err}"
), ),
&output, &output,
level, level,
@ -835,7 +829,7 @@ async fn create_pep517_build_environment(
let extra_requires: Vec<pep508_rs::Requirement<VerbatimParsedUrl>> = serde_json::from_slice::<Vec<pep508_rs::Requirement<VerbatimParsedUrl>>>(&contents).map_err(|err| { let extra_requires: Vec<pep508_rs::Requirement<VerbatimParsedUrl>> = serde_json::from_slice::<Vec<pep508_rs::Requirement<VerbatimParsedUrl>>>(&contents).map_err(|err| {
Error::from_command_output( Error::from_command_output(
format!( format!(
"Build backend failed to return extra requires with `get_requires_for_build_{build_kind}`: {err}" "Build backend failed to return requirements from `get_requires_for_build_{build_kind}`: {err}"
), ),
&output, &output,
level, level,
@ -864,12 +858,12 @@ async fn create_pep517_build_environment(
let resolution = build_context let resolution = build_context
.resolve(&requirements) .resolve(&requirements)
.await .await
.map_err(|err| Error::RequirementsInstall("`build-system.requires` (resolve)", err))?; .map_err(|err| Error::RequirementsResolve("`build-system.requires`", err))?;
build_context build_context
.install(&resolution, venv) .install(&resolution, venv)
.await .await
.map_err(|err| Error::RequirementsInstall("`build-system.requires` (install)", err))?; .map_err(|err| Error::RequirementsInstall("`build-system.requires`", err))?;
} }
Ok(()) Ok(())

View file

@ -888,7 +888,7 @@ fn fail() -> Result<()> {
File "<string>", line 2 File "<string>", line 2
from setuptools import setup from setuptools import setup
IndentationError: unexpected indent IndentationError: unexpected indent
error: Build backend failed to determine extra requires with `build_sdist()` with exit status: 1 error: Build backend failed to determine requirements with `build_sdist()` (exit status: 1)
"###); "###);
Ok(()) Ok(())
@ -1328,7 +1328,7 @@ fn build_all_with_failure() -> Result<()> {
[PKG] Building wheel from source distribution... [PKG] Building wheel from source distribution...
[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 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 extra requires with `build_sdist()` with exit status: 1 [PKG] error: 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 Successfully built dist/project-0.1.0.tar.gz and dist/project-0.1.0-py3-none-any.whl
"###); "###);
@ -1397,7 +1397,7 @@ fn build_constraints() -> Result<()> {
----- stderr ----- ----- stderr -----
Building source distribution... Building source distribution...
error: Failed to install requirements from `build-system.requires` (resolve) error: Failed to resolve requirements from `build-system.requires`
Caused by: No solution found when resolving: `setuptools>=42` 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. Caused by: Because you require setuptools>=42 and setuptools==0.1.0, we can conclude that your requirements are unsatisfiable.
"###); "###);
@ -1551,7 +1551,7 @@ fn sha() -> Result<()> {
----- stderr ----- ----- stderr -----
Building source distribution... Building source distribution...
error: Failed to install requirements from `build-system.requires` (install) error: Failed to install requirements from `build-system.requires`
Caused by: Failed to prepare distributions Caused by: Failed to prepare distributions
Caused by: Failed to fetch wheel: setuptools==68.2.2 Caused by: Failed to fetch wheel: setuptools==68.2.2
Caused by: Hash mismatch for `setuptools==68.2.2` Caused by: Hash mismatch for `setuptools==68.2.2`
@ -1585,7 +1585,7 @@ fn sha() -> Result<()> {
----- stderr ----- ----- stderr -----
Building source distribution... Building source distribution...
error: Failed to install requirements from `build-system.requires` (resolve) error: Failed to resolve requirements from `build-system.requires`
Caused by: No solution found when resolving: `setuptools>=42` 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` Caused by: In `--require-hashes` mode, all requirements must be pinned upfront with `==`, but found: `setuptools`
"###); "###);

View file

@ -4594,7 +4594,7 @@ fn fail_to_add_revert_project() -> Result<()> {
Resolved 2 packages in [TIME] Resolved 2 packages in [TIME]
error: Failed to prepare distributions error: Failed to prepare distributions
Caused by: Failed to fetch wheel: pytorch==1.0.2 Caused by: Failed to fetch wheel: pytorch==1.0.2
Caused by: Build backend failed to build wheel through `build_wheel()` with exit status: 1 Caused by: Build backend failed to build wheel through `build_wheel()` (exit status: 1)
--- stdout: --- stdout:
--- stderr: --- stderr:

View file

@ -11782,7 +11782,7 @@ fn incompatible_build_constraint() -> Result<()> {
----- stderr ----- ----- stderr -----
× Failed to download and build `requests==1.2.0` × Failed to download and build `requests==1.2.0`
Failed to install requirements from `setup.py` build (resolve) Failed to resolve requirements from `setup.py` build
No solution found when resolving: `setuptools>=40.8.0` No solution found when resolving: `setuptools>=40.8.0`
Because you require setuptools>=40.8.0 and setuptools==1, we can conclude that your requirements are unsatisfiable. Because you require setuptools>=40.8.0 and setuptools==1, we can conclude that your requirements are unsatisfiable.
"### "###

View file

@ -227,11 +227,9 @@ dependencies = ["flask==1.0.x"]
let requirements_txt = context.temp_dir.child("requirements.txt"); let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.write_str("./path_dep")?; requirements_txt.write_str("./path_dep")?;
let filters = [("exit status", "exit code")] let filters = std::iter::once((r"exit code: 1", "exit status: 1"))
.into_iter()
.chain(context.filters()) .chain(context.filters())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
uv_snapshot!(filters, context.pip_install() uv_snapshot!(filters, context.pip_install()
.arg("-r") .arg("-r")
.arg("requirements.txt"), @r###" .arg("requirements.txt"), @r###"
@ -241,7 +239,7 @@ dependencies = ["flask==1.0.x"]
----- stderr ----- ----- stderr -----
error: Failed to build: `project @ file://[TEMP_DIR]/path_dep` error: Failed to build: `project @ file://[TEMP_DIR]/path_dep`
Caused by: Build backend failed to determine extra requires with `build_wheel()` with exit code: 1 Caused by: Build backend failed to determine requirements with `build_wheel()` (exit status: 1)
--- stdout: --- stdout:
configuration error: `project.dependencies[0]` must be pep508 configuration error: `project.dependencies[0]` must be pep508
DESCRIPTION: DESCRIPTION:
@ -3820,7 +3818,7 @@ fn no_build_isolation() -> Result<()> {
----- stderr ----- ----- stderr -----
error: Failed to download and build: `anyio @ https://files.pythonhosted.org/packages/db/4d/3970183622f0330d3c23d9b8a5f52e365e50381fd484d08e3285104333d3/anyio-4.3.0.tar.gz` error: Failed to download and build: `anyio @ https://files.pythonhosted.org/packages/db/4d/3970183622f0330d3c23d9b8a5f52e365e50381fd484d08e3285104333d3/anyio-4.3.0.tar.gz`
Caused by: Build backend failed to determine metadata through `prepare_metadata_for_build_wheel` with exit status: 1 Caused by: Build backend failed to determine metadata through `prepare_metadata_for_build_wheel` (exit status: 1)
--- stdout: --- stdout:
--- stderr: --- stderr:
@ -3890,7 +3888,7 @@ fn respect_no_build_isolation_env_var() -> Result<()> {
----- stderr ----- ----- stderr -----
error: Failed to download and build: `anyio @ https://files.pythonhosted.org/packages/db/4d/3970183622f0330d3c23d9b8a5f52e365e50381fd484d08e3285104333d3/anyio-4.3.0.tar.gz` error: Failed to download and build: `anyio @ https://files.pythonhosted.org/packages/db/4d/3970183622f0330d3c23d9b8a5f52e365e50381fd484d08e3285104333d3/anyio-4.3.0.tar.gz`
Caused by: Build backend failed to determine metadata through `prepare_metadata_for_build_wheel` with exit status: 1 Caused by: Build backend failed to determine metadata through `prepare_metadata_for_build_wheel` (exit status: 1)
--- stdout: --- stdout:
--- stderr: --- stderr:
@ -6759,7 +6757,7 @@ fn incompatible_build_constraint() -> Result<()> {
----- stderr ----- ----- stderr -----
× Failed to download and build `requests==1.2.0` × Failed to download and build `requests==1.2.0`
Failed to install requirements from `setup.py` build (resolve) Failed to resolve requirements from `setup.py` build
No solution found when resolving: `setuptools>=40.8.0` No solution found when resolving: `setuptools>=40.8.0`
Because you require setuptools>=40.8.0 and setuptools==1, we can conclude that your requirements are unsatisfiable. Because you require setuptools>=40.8.0 and setuptools==1, we can conclude that your requirements are unsatisfiable.
"### "###
@ -6835,7 +6833,7 @@ fn install_build_isolation_package() -> Result<()> {
----- stderr ----- ----- stderr -----
error: Failed to download and build: `iniconfig @ https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz` error: Failed to download and build: `iniconfig @ https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz`
Caused by: Build backend failed to determine metadata through `prepare_metadata_for_build_wheel` with exit status: 1 Caused by: Build backend failed to determine metadata through `prepare_metadata_for_build_wheel` (exit status: 1)
--- stdout: --- stdout:
--- stderr: --- stderr:
@ -7096,7 +7094,7 @@ fn sklearn() {
----- stderr ----- ----- stderr -----
× Failed to download and build `sklearn==0.0.post12` × Failed to download and build `sklearn==0.0.post12`
Build backend failed to determine extra requires with `build_wheel()` with exit status: 1 Build backend failed to determine requirements with `build_wheel()` (exit status: 1)
--- stdout: --- stdout:
--- stderr: --- stderr:

View file

@ -5499,7 +5499,7 @@ fn incompatible_build_constraint() -> Result<()> {
Resolved 1 package in [TIME] Resolved 1 package in [TIME]
error: Failed to prepare distributions error: Failed to prepare distributions
Caused by: Failed to fetch wheel: requests==1.2.0 Caused by: Failed to fetch wheel: requests==1.2.0
Caused by: Failed to install requirements from `setup.py` build (resolve) Caused by: Failed to resolve requirements from `setup.py` build
Caused by: No solution found when resolving: `setuptools>=40.8.0` Caused by: No solution found when resolving: `setuptools>=40.8.0`
Caused by: Because you require setuptools>=40.8.0 and setuptools==1, we can conclude that your requirements are unsatisfiable. Caused by: Because you require setuptools>=40.8.0 and setuptools==1, we can conclude that your requirements are unsatisfiable.
"### "###

View file

@ -577,7 +577,7 @@ fn sync_build_isolation_package() -> Result<()> {
Resolved 2 packages in [TIME] Resolved 2 packages in [TIME]
error: Failed to prepare distributions error: Failed to prepare distributions
Caused by: Failed to fetch wheel: source-distribution @ https://files.pythonhosted.org/packages/10/1f/57aa4cce1b1abf6b433106676e15f9fa2c92ed2bd4cf77c3b50a9e9ac773/source_distribution-0.0.1.tar.gz Caused by: Failed to fetch wheel: source-distribution @ https://files.pythonhosted.org/packages/10/1f/57aa4cce1b1abf6b433106676e15f9fa2c92ed2bd4cf77c3b50a9e9ac773/source_distribution-0.0.1.tar.gz
Caused by: Build backend failed to build wheel through `build_wheel()` with exit status: 1 Caused by: Build backend failed to build wheel through `build_wheel()` (exit status: 1)
--- stdout: --- stdout:
--- stderr: --- stderr:
@ -669,7 +669,7 @@ fn sync_build_isolation_extra() -> Result<()> {
Resolved [N] packages in [TIME] Resolved [N] packages in [TIME]
error: Failed to prepare distributions error: Failed to prepare distributions
Caused by: Failed to fetch wheel: source-distribution @ https://files.pythonhosted.org/packages/10/1f/57aa4cce1b1abf6b433106676e15f9fa2c92ed2bd4cf77c3b50a9e9ac773/source_distribution-0.0.1.tar.gz Caused by: Failed to fetch wheel: source-distribution @ https://files.pythonhosted.org/packages/10/1f/57aa4cce1b1abf6b433106676e15f9fa2c92ed2bd4cf77c3b50a9e9ac773/source_distribution-0.0.1.tar.gz
Caused by: Build backend failed to build wheel through `build_wheel()` with exit status: 1 Caused by: Build backend failed to build wheel through `build_wheel()` (exit status: 1)
--- stdout: --- stdout:
--- stderr: --- stderr:
@ -689,7 +689,7 @@ fn sync_build_isolation_extra() -> Result<()> {
Resolved [N] packages in [TIME] Resolved [N] packages in [TIME]
error: Failed to prepare distributions error: Failed to prepare distributions
Caused by: Failed to fetch wheel: source-distribution @ https://files.pythonhosted.org/packages/10/1f/57aa4cce1b1abf6b433106676e15f9fa2c92ed2bd4cf77c3b50a9e9ac773/source_distribution-0.0.1.tar.gz Caused by: Failed to fetch wheel: source-distribution @ https://files.pythonhosted.org/packages/10/1f/57aa4cce1b1abf6b433106676e15f9fa2c92ed2bd4cf77c3b50a9e9ac773/source_distribution-0.0.1.tar.gz
Caused by: Build backend failed to build wheel through `build_wheel()` with exit status: 1 Caused by: Build backend failed to build wheel through `build_wheel()` (exit status: 1)
--- stdout: --- stdout:
--- stderr: --- stderr: