Skip to content

Commit

Permalink
Display the built file name instead of the canonicalized name in `uv …
Browse files Browse the repository at this point in the history
…build` (#11593)

We keep the raw filename (prior to parsing/normalization) on the
`BuildMessage` so we can display it.

Closes #11103.
Closes #11635.
  • Loading branch information
jtfmumm authored Feb 20, 2025
1 parent 6d3614e commit ab551ea
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 33 deletions.
82 changes: 55 additions & 27 deletions crates/uv/src/commands/build_frontend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,7 @@ async fn build_package(
build_results.push(sdist_build.clone());

// Extract the source distribution into a temporary directory.
let path = output_dir.join(sdist_build.filename().to_string());
let path = output_dir.join(sdist_build.raw_filename());
let reader = fs_err::tokio::File::open(&path).await?;
let ext = SourceDistExtension::from_path(path.as_path())
.map_err(|err| Error::InvalidSourceDistExt(path.user_display().to_string(), err))?;
Expand All @@ -695,7 +695,7 @@ async fn build_package(
subdirectory,
version_id,
build_output,
Some(sdist_build.filename().version()),
Some(sdist_build.normalized_filename().version()),
)
.await?;
build_results.push(wheel_build);
Expand Down Expand Up @@ -767,7 +767,7 @@ async fn build_package(
subdirectory,
version_id,
build_output,
Some(sdist_build.filename().version()),
Some(sdist_build.normalized_filename().version()),
)
.await?;
build_results.push(sdist_build);
Expand Down Expand Up @@ -866,9 +866,10 @@ async fn build_sdist(
uv_build_backend::list_source_dist(&source_tree_, uv_version::version())
})
.await??;

let raw_filename = filename.to_string();
BuildMessage::List {
filename: DistFilename::SourceDistFilename(filename),
normalized_filename: DistFilename::SourceDistFilename(filename),
raw_filename,
source_tree: source_tree.to_path_buf(),
file_list,
}
Expand Down Expand Up @@ -897,10 +898,11 @@ async fn build_sdist(
.to_string();

BuildMessage::Build {
filename: DistFilename::SourceDistFilename(
normalized_filename: DistFilename::SourceDistFilename(
SourceDistFilename::parsed_normalized_filename(&filename)
.map_err(Error::InvalidBuiltSourceDistFilename)?,
),
raw_filename: filename,
output_dir: output_dir.to_path_buf(),
}
}
Expand Down Expand Up @@ -931,10 +933,11 @@ async fn build_sdist(
.map_err(|err| Error::BuildDispatch(err.into()))?;
let filename = builder.build(output_dir).await?;
BuildMessage::Build {
filename: DistFilename::SourceDistFilename(
normalized_filename: DistFilename::SourceDistFilename(
SourceDistFilename::parsed_normalized_filename(&filename)
.map_err(Error::InvalidBuiltSourceDistFilename)?,
),
raw_filename: filename,
output_dir: output_dir.to_path_buf(),
}
}
Expand Down Expand Up @@ -968,8 +971,10 @@ async fn build_wheel(
uv_build_backend::list_wheel(&source_tree_, uv_version::version())
})
.await??;
let raw_filename = filename.to_string();
BuildMessage::List {
filename: DistFilename::WheelFilename(filename),
normalized_filename: DistFilename::WheelFilename(filename),
raw_filename,
source_tree: source_tree.to_path_buf(),
file_list,
}
Expand Down Expand Up @@ -997,8 +1002,10 @@ async fn build_wheel(
})
.await??;

let raw_filename = filename.to_string();
BuildMessage::Build {
filename: DistFilename::WheelFilename(filename),
normalized_filename: DistFilename::WheelFilename(filename),
raw_filename,
output_dir: output_dir.to_path_buf(),
}
}
Expand Down Expand Up @@ -1029,15 +1036,16 @@ async fn build_wheel(
.map_err(|err| Error::BuildDispatch(err.into()))?;
let filename = builder.build(output_dir).await?;
BuildMessage::Build {
filename: DistFilename::WheelFilename(
normalized_filename: DistFilename::WheelFilename(
WheelFilename::from_str(&filename).map_err(Error::InvalidBuiltWheelFilename)?,
),
raw_filename: filename,
output_dir: output_dir.to_path_buf(),
}
}
};
if let Some(expected) = version {
let actual = build_message.filename().version();
let actual = build_message.normalized_filename().version();
if expected != actual {
return Err(Error::VersionMismatch(expected.clone(), actual.clone()));
}
Expand Down Expand Up @@ -1138,15 +1146,19 @@ impl Source<'_> {
enum BuildMessage {
/// A built wheel or source distribution.
Build {
/// The name of the built distribution.
filename: DistFilename,
/// The normalized name of the built distribution.
normalized_filename: DistFilename,
/// The name of the built distribution before parsing and normalization.
raw_filename: String,
/// The location of the built distribution.
output_dir: PathBuf,
},
/// Show the list of files that would be included in a distribution.
List {
/// The name of the build distribution.
filename: DistFilename,
/// The normalized name of the build distribution.
normalized_filename: DistFilename,
/// The name of the built distribution before parsing and normalization.
raw_filename: String,
// All source files are relative to the source tree.
source_tree: PathBuf,
// Included file and source file, if not generated.
Expand All @@ -1155,39 +1167,55 @@ enum BuildMessage {
}

impl BuildMessage {
/// The filename of the wheel or source distribution.
fn filename(&self) -> &DistFilename {
/// The normalized filename of the wheel or source distribution.
fn normalized_filename(&self) -> &DistFilename {
match self {
BuildMessage::Build { filename: name, .. } => name,
BuildMessage::List { filename: name, .. } => name,
BuildMessage::Build {
normalized_filename: name,
..
} => name,
BuildMessage::List {
normalized_filename: name,
..
} => name,
}
}

/// The filename of the wheel or source distribution before normalization.
fn raw_filename(&self) -> &str {
match self {
BuildMessage::Build {
raw_filename: name, ..
} => name,
BuildMessage::List {
raw_filename: name, ..
} => name,
}
}

fn print(&self, printer: Printer) -> Result<()> {
match self {
BuildMessage::Build {
filename,
raw_filename,
output_dir,
..
} => {
writeln!(
printer.stderr(),
"Successfully built {}",
output_dir
.join(filename.to_string())
.user_display()
.bold()
.cyan()
output_dir.join(raw_filename).user_display().bold().cyan()
)?;
}
BuildMessage::List {
filename,
raw_filename,
file_list,
source_tree,
..
} => {
writeln!(
printer.stdout(),
"{}",
format!("Building {filename} will include the following files:").bold()
format!("Building {raw_filename} will include the following files:").bold()
)?;
for (file, source) in file_list {
if let Some(source) = source {
Expand Down
70 changes: 64 additions & 6 deletions crates/uv/tests/it/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1881,7 +1881,7 @@ fn build_workspace_virtual_root() -> Result<()> {
members = ["packages/*"]
"#})?;

uv_snapshot!(context.filters(), context.build().arg("--no-build-logs"), @r###"
uv_snapshot!(context.filters(), context.build().arg("--no-build-logs"), @r"
success: true
exit_code: 0
----- stdout -----
Expand All @@ -1891,8 +1891,8 @@ fn build_workspace_virtual_root() -> Result<()> {
warning: `[TEMP_DIR]/` appears to be a workspace root without a Python project; consider using `uv sync` to install the workspace, or add a `[build-system]` table to `pyproject.toml`
Building wheel from source distribution...
Successfully built dist/cache-0.0.0.tar.gz
Successfully built dist/unknown-0.0.0-py3-none-any.whl
"###);
Successfully built dist/UNKNOWN-0.0.0-py3-none-any.whl
");
Ok(())
}

Expand All @@ -1910,7 +1910,7 @@ fn build_pyproject_toml_not_a_project() -> Result<()> {
line-length = 88
"})?;

uv_snapshot!(context.filters(), context.build().arg("--no-build-logs"), @r###"
uv_snapshot!(context.filters(), context.build().arg("--no-build-logs"), @r"
success: true
exit_code: 0
----- stdout -----
Expand All @@ -1920,7 +1920,65 @@ fn build_pyproject_toml_not_a_project() -> Result<()> {
warning: `[TEMP_DIR]/` does not appear to be a Python project, as the `pyproject.toml` does not include a `[build-system]` table, and neither `setup.py` nor `setup.cfg` are present in the directory
Building wheel from source distribution...
Successfully built dist/cache-0.0.0.tar.gz
Successfully built dist/unknown-0.0.0-py3-none-any.whl
"###);
Successfully built dist/UNKNOWN-0.0.0-py3-none-any.whl
");
Ok(())
}

#[test]
fn build_with_nonnormalized_name() -> Result<()> {
let context = TestContext::new("3.12");
let filters = context
.filters()
.into_iter()
.chain([(r"exit code: 1", "exit status: 1"), (r"\\\.", "")])
.collect::<Vec<_>>();

let project = context.temp_dir.child("project");

let pyproject_toml = project.child("pyproject.toml");
pyproject_toml.write_str(
r#"
[project]
name = "my.PROJECT"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = ["anyio==3.7.0"]
[build-system]
requires = ["setuptools>=42,<69"]
build-backend = "setuptools.build_meta"
"#,
)?;

project
.child("src")
.child("my.PROJECT")
.child("__init__.py")
.touch()?;
project.child("README").touch()?;

// Build the specified path.
uv_snapshot!(&filters, context.build().arg("--no-build-logs").current_dir(&project), @r"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Building source distribution...
Building wheel from source distribution...
Successfully built dist/my.PROJECT-0.1.0.tar.gz
Successfully built dist/my.PROJECT-0.1.0-py3-none-any.whl
");

project
.child("dist")
.child("my.PROJECT-0.1.0.tar.gz")
.assert(predicate::path::is_file());
project
.child("dist")
.child("my.PROJECT-0.1.0-py3-none-any.whl")
.assert(predicate::path::is_file());

Ok(())
}

0 comments on commit ab551ea

Please sign in to comment.