Mock uv version in build backend tests (#8205)

This commit is contained in:
konsti 2024-10-15 11:27:33 +02:00 committed by GitHub
parent dda91d443c
commit 7c5d94030d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 67 additions and 53 deletions

2
Cargo.lock generated
View file

@ -4177,6 +4177,7 @@ dependencies = [
"uv-static", "uv-static",
"uv-tool", "uv-tool",
"uv-types", "uv-types",
"uv-version",
"uv-virtualenv", "uv-virtualenv",
"uv-warnings", "uv-warnings",
"uv-workspace", "uv-workspace",
@ -4259,7 +4260,6 @@ dependencies = [
"uv-pep508", "uv-pep508",
"uv-pubgrub", "uv-pubgrub",
"uv-pypi-types", "uv-pypi-types",
"uv-version",
"uv-warnings", "uv-warnings",
"walkdir", "walkdir",
"zip", "zip",

View file

@ -20,7 +20,6 @@ uv-pep440 = { workspace = true }
uv-pep508 = { workspace = true } uv-pep508 = { workspace = true }
uv-pubgrub = { workspace = true } uv-pubgrub = { workspace = true }
uv-pypi-types = { workspace = true } uv-pypi-types = { workspace = true }
uv-version = { workspace = true }
uv-warnings = { workspace = true } uv-warnings = { workspace = true }
csv = { workspace = true} csv = { workspace = true}
@ -41,5 +40,5 @@ workspace = true
[dev-dependencies] [dev-dependencies]
indoc = { version = "2.0.5" } indoc = { version = "2.0.5" }
insta = { version = "1.40.0", features = ["filters"] } insta = { version = "1.40.0" }
tempfile = { version = "3.12.0" } tempfile = { version = "3.12.0" }

View file

@ -280,10 +280,11 @@ pub fn build(
source_tree: &Path, source_tree: &Path,
wheel_dir: &Path, wheel_dir: &Path,
metadata_directory: Option<&Path>, metadata_directory: Option<&Path>,
uv_version: &str,
) -> Result<WheelFilename, Error> { ) -> Result<WheelFilename, Error> {
let contents = fs_err::read_to_string(source_tree.join("pyproject.toml"))?; let contents = fs_err::read_to_string(source_tree.join("pyproject.toml"))?;
let pyproject_toml = PyProjectToml::parse(&contents)?; let pyproject_toml = PyProjectToml::parse(&contents)?;
pyproject_toml.check_build_system(); pyproject_toml.check_build_system("1.0.0+test");
check_metadata_directory(source_tree, metadata_directory, &pyproject_toml)?; check_metadata_directory(source_tree, metadata_directory, &pyproject_toml)?;
@ -329,18 +330,27 @@ pub fn build(
} }
debug!("Adding metadata files to {}", wheel_path.user_display()); debug!("Adding metadata files to {}", wheel_path.user_display());
let dist_info_dir = let dist_info_dir = write_dist_info(
write_dist_info(&mut wheel_writer, &pyproject_toml, &filename, source_tree)?; &mut wheel_writer,
&pyproject_toml,
&filename,
source_tree,
uv_version,
)?;
wheel_writer.close(&dist_info_dir)?; wheel_writer.close(&dist_info_dir)?;
Ok(filename) Ok(filename)
} }
/// Write the dist-info directory to the output directory without building the wheel. /// Write the dist-info directory to the output directory without building the wheel.
pub fn metadata(source_tree: &Path, metadata_directory: &Path) -> Result<String, Error> { pub fn metadata(
source_tree: &Path,
metadata_directory: &Path,
uv_version: &str,
) -> Result<String, Error> {
let contents = fs_err::read_to_string(source_tree.join("pyproject.toml"))?; let contents = fs_err::read_to_string(source_tree.join("pyproject.toml"))?;
let pyproject_toml = PyProjectToml::parse(&contents)?; let pyproject_toml = PyProjectToml::parse(&contents)?;
pyproject_toml.check_build_system(); pyproject_toml.check_build_system("1.0.0+test");
let filename = WheelFilename { let filename = WheelFilename {
name: pyproject_toml.name().clone(), name: pyproject_toml.name().clone(),
@ -356,8 +366,13 @@ pub fn metadata(source_tree: &Path, metadata_directory: &Path) -> Result<String,
metadata_directory.user_display() metadata_directory.user_display()
); );
let mut wheel_writer = FilesystemWrite::new(metadata_directory); let mut wheel_writer = FilesystemWrite::new(metadata_directory);
let dist_info_dir = let dist_info_dir = write_dist_info(
write_dist_info(&mut wheel_writer, &pyproject_toml, &filename, source_tree)?; &mut wheel_writer,
&pyproject_toml,
&filename,
source_tree,
uv_version,
)?;
wheel_writer.close(&dist_info_dir)?; wheel_writer.close(&dist_info_dir)?;
Ok(dist_info_dir) Ok(dist_info_dir)
@ -419,6 +434,7 @@ fn write_dist_info(
pyproject_toml: &PyProjectToml, pyproject_toml: &PyProjectToml,
filename: &WheelFilename, filename: &WheelFilename,
root: &Path, root: &Path,
uv_version: &str,
) -> Result<String, Error> { ) -> Result<String, Error> {
let dist_info_dir = format!( let dist_info_dir = format!(
"{}-{}.dist-info", "{}-{}.dist-info",
@ -429,7 +445,7 @@ fn write_dist_info(
writer.write_directory(&dist_info_dir)?; writer.write_directory(&dist_info_dir)?;
// Add `WHEEL`. // Add `WHEEL`.
let wheel_info = wheel_info(filename); let wheel_info = wheel_info(filename, uv_version);
writer.write_bytes(&format!("{dist_info_dir}/WHEEL"), wheel_info.as_bytes())?; writer.write_bytes(&format!("{dist_info_dir}/WHEEL"), wheel_info.as_bytes())?;
// Add `entry_points.txt`. // Add `entry_points.txt`.
@ -450,11 +466,11 @@ fn write_dist_info(
} }
/// Returns the `WHEEL` file contents. /// Returns the `WHEEL` file contents.
fn wheel_info(filename: &WheelFilename) -> String { fn wheel_info(filename: &WheelFilename, uv_version: &str) -> String {
// https://packaging.python.org/en/latest/specifications/binary-distribution-format/#file-contents // https://packaging.python.org/en/latest/specifications/binary-distribution-format/#file-contents
let mut wheel_info = vec![ let mut wheel_info = vec![
("Wheel-Version", "1.0".to_string()), ("Wheel-Version", "1.0".to_string()),
("Generator", format!("uv {}", uv_version::version())), ("Generator", format!("uv {uv_version}")),
("Root-Is-Purelib", "true".to_string()), ("Root-Is-Purelib", "true".to_string()),
]; ];
for python_tag in &filename.python_tag { for python_tag in &filename.python_tag {

View file

@ -85,7 +85,7 @@ impl PyProjectToml {
/// ``` /// ```
/// ///
/// Returns whether all checks passed. /// Returns whether all checks passed.
pub(crate) fn check_build_system(&self) -> bool { pub(crate) fn check_build_system(&self, uv_version: &str) -> bool {
let mut passed = true; let mut passed = true;
if self.build_system.build_backend.as_deref() != Some("uv") { if self.build_system.build_backend.as_deref() != Some("uv") {
warn_user_once!( warn_user_once!(
@ -95,8 +95,8 @@ impl PyProjectToml {
passed = false; passed = false;
} }
let uv_version = Version::from_str(uv_version::version()) let uv_version =
.expect("uv's own version is not PEP 440 compliant"); Version::from_str(uv_version).expect("uv's own version is not PEP 440 compliant");
let next_minor = uv_version.release().get(1).copied().unwrap_or_default() + 1; let next_minor = uv_version.release().get(1).copied().unwrap_or_default() + 1;
let next_breaking = Version::new([0, next_minor]); let next_breaking = Version::new([0, next_minor]);
@ -131,8 +131,7 @@ impl PyProjectToml {
// This is allowed to happen when testing prereleases, but we should still warn. // This is allowed to happen when testing prereleases, but we should still warn.
warn_user_once!( warn_user_once!(
r#"`build_system.requires = ["{uv_requirement}"]` does not contain the r#"`build_system.requires = ["{uv_requirement}"]` does not contain the
current uv version {}"#, current uv version {uv_version}"#,
uv_version::version()
); );
passed = false; passed = false;
} }

View file

@ -151,7 +151,7 @@ fn valid() {
fn build_system_valid() { fn build_system_valid() {
let contents = extend_project(""); let contents = extend_project("");
let pyproject_toml = PyProjectToml::parse(&contents).unwrap(); let pyproject_toml = PyProjectToml::parse(&contents).unwrap();
assert!(pyproject_toml.check_build_system()); assert!(pyproject_toml.check_build_system("1.0.0+test"));
} }
#[test] #[test]
@ -166,7 +166,7 @@ fn build_system_no_bound() {
build-backend = "uv" build-backend = "uv"
"#}; "#};
let pyproject_toml = PyProjectToml::parse(contents).unwrap(); let pyproject_toml = PyProjectToml::parse(contents).unwrap();
assert!(!pyproject_toml.check_build_system()); assert!(!pyproject_toml.check_build_system("1.0.0+test"));
} }
#[test] #[test]
@ -181,7 +181,7 @@ fn build_system_multiple_packages() {
build-backend = "uv" build-backend = "uv"
"#}; "#};
let pyproject_toml = PyProjectToml::parse(contents).unwrap(); let pyproject_toml = PyProjectToml::parse(contents).unwrap();
assert!(!pyproject_toml.check_build_system()); assert!(!pyproject_toml.check_build_system("1.0.0+test"));
} }
#[test] #[test]
@ -196,7 +196,7 @@ fn build_system_no_requires_uv() {
build-backend = "uv" build-backend = "uv"
"#}; "#};
let pyproject_toml = PyProjectToml::parse(contents).unwrap(); let pyproject_toml = PyProjectToml::parse(contents).unwrap();
assert!(!pyproject_toml.check_build_system()); assert!(!pyproject_toml.check_build_system("1.0.0+test"));
} }
#[test] #[test]
@ -211,7 +211,7 @@ fn build_system_not_uv() {
build-backend = "setuptools" build-backend = "setuptools"
"#}; "#};
let pyproject_toml = PyProjectToml::parse(contents).unwrap(); let pyproject_toml = PyProjectToml::parse(contents).unwrap();
assert!(!pyproject_toml.check_build_system()); assert!(!pyproject_toml.check_build_system("1.0.0+test"));
} }
#[test] #[test]

View file

@ -1,5 +1,5 @@
use super::*; use super::*;
use insta::{assert_snapshot, with_settings}; use insta::assert_snapshot;
use std::str::FromStr; use std::str::FromStr;
use tempfile::TempDir; use tempfile::TempDir;
use uv_normalize::PackageName; use uv_normalize::PackageName;
@ -16,17 +16,13 @@ fn test_wheel() {
platform_tag: vec!["any".to_string()], platform_tag: vec!["any".to_string()],
}; };
with_settings!({ assert_snapshot!(wheel_info(&filename, "1.0.0+test"), @r"
filters => [(uv_version::version(), "[VERSION]")], Wheel-Version: 1.0
}, { Generator: uv 1.0.0+test
assert_snapshot!(wheel_info(&filename), @r" Root-Is-Purelib: true
Wheel-Version: 1.0 Tag: py2-none-any
Generator: uv [VERSION] Tag: py3-none-any
Root-Is-Purelib: true ");
Tag: py2-none-any
Tag: py3-none-any
");
});
} }
#[test] #[test]
@ -50,7 +46,7 @@ fn test_record() {
fn test_determinism() { fn test_determinism() {
let temp1 = TempDir::new().unwrap(); let temp1 = TempDir::new().unwrap();
let uv_backend = Path::new("../../scripts/packages/uv_backend"); let uv_backend = Path::new("../../scripts/packages/uv_backend");
build(uv_backend, temp1.path(), None).unwrap(); build(uv_backend, temp1.path(), None, "1.0.0+test").unwrap();
// Touch the file to check that we don't serialize the last modified date. // Touch the file to check that we don't serialize the last modified date.
fs_err::write( fs_err::write(
@ -60,7 +56,7 @@ fn test_determinism() {
.unwrap(); .unwrap();
let temp2 = TempDir::new().unwrap(); let temp2 = TempDir::new().unwrap();
build(uv_backend, temp2.path(), None).unwrap(); build(uv_backend, temp2.path(), None, "1.0.0+test").unwrap();
let wheel_filename = "uv_backend-0.1.0-py3-none-any.whl"; let wheel_filename = "uv_backend-0.1.0-py3-none-any.whl";
assert_eq!( assert_eq!(
@ -74,7 +70,7 @@ fn test_determinism() {
fn test_prepare_metadata() { fn test_prepare_metadata() {
let metadata_dir = TempDir::new().unwrap(); let metadata_dir = TempDir::new().unwrap();
let uv_backend = Path::new("../../scripts/packages/uv_backend"); let uv_backend = Path::new("../../scripts/packages/uv_backend");
metadata(uv_backend, metadata_dir.path()).unwrap(); metadata(uv_backend, metadata_dir.path(), "1.0.0+test").unwrap();
let mut files: Vec<_> = WalkDir::new(metadata_dir.path()) let mut files: Vec<_> = WalkDir::new(metadata_dir.path())
.into_iter() .into_iter()
@ -117,21 +113,16 @@ fn test_prepare_metadata() {
.path() .path()
.join("uv_backend-0.1.0.dist-info/RECORD"); .join("uv_backend-0.1.0.dist-info/RECORD");
assert_snapshot!(fs_err::read_to_string(record_file).unwrap(), @r###" assert_snapshot!(fs_err::read_to_string(record_file).unwrap(), @r###"
uv_backend-0.1.0.dist-info/WHEEL,sha256=1889a32410898a395359e85de53e3063be35d9113130eaf23659cb84740c0c6c,79 uv_backend-0.1.0.dist-info/WHEEL,sha256=3da1bfa0e8fd1b6cc246aa0b2b44a35815596c600cb485c39a6f8c106c3d5a8d,83
uv_backend-0.1.0.dist-info/METADATA,sha256=e4a0d390317d7182f65ea978254c71ed283e0a4242150cf1c99a694b113ff68d,224 uv_backend-0.1.0.dist-info/METADATA,sha256=e4a0d390317d7182f65ea978254c71ed283e0a4242150cf1c99a694b113ff68d,224
uv_backend-0.1.0.dist-info/RECORD,, uv_backend-0.1.0.dist-info/RECORD,,
"###); "###);
let wheel_file = metadata_dir.path().join("uv_backend-0.1.0.dist-info/WHEEL"); let wheel_file = metadata_dir.path().join("uv_backend-0.1.0.dist-info/WHEEL");
let filters = vec![(uv_version::version(), "[VERSION]")]; assert_snapshot!(fs_err::read_to_string(wheel_file).unwrap(), @r###"
with_settings!({ Wheel-Version: 1.0
filters => filters Generator: uv 1.0.0+test
}, { Root-Is-Purelib: true
assert_snapshot!(fs_err::read_to_string(wheel_file).unwrap(), @r###" Tag: py3-none-any
Wheel-Version: 1.0 "###);
Generator: uv [VERSION]
Root-Is-Purelib: true
Tag: py3-none-any
"###);
});
} }

View file

@ -50,6 +50,7 @@ uv-static = { workspace = true }
uv-tool = { workspace = true } uv-tool = { workspace = true }
uv-types = { workspace = true } uv-types = { workspace = true }
uv-virtualenv = { workspace = true } uv-virtualenv = { workspace = true }
uv-version = { workspace = true }
uv-warnings = { workspace = true } uv-warnings = { workspace = true }
uv-workspace = { workspace = true } uv-workspace = { workspace = true }

View file

@ -12,8 +12,12 @@ pub(crate) fn build_wheel(
wheel_directory: &Path, wheel_directory: &Path,
metadata_directory: Option<&Path>, metadata_directory: Option<&Path>,
) -> Result<ExitStatus> { ) -> Result<ExitStatus> {
let filename = let filename = uv_build_backend::build(
uv_build_backend::build(&env::current_dir()?, wheel_directory, metadata_directory)?; &env::current_dir()?,
wheel_directory,
metadata_directory,
uv_version::version(),
)?;
println!("{filename}"); println!("{filename}");
Ok(ExitStatus::Success) Ok(ExitStatus::Success)
} }
@ -33,7 +37,11 @@ pub(crate) fn get_requires_for_build_wheel() -> Result<ExitStatus> {
todo!() todo!()
} }
pub(crate) fn prepare_metadata_for_build_wheel(metadata_directory: &Path) -> Result<ExitStatus> { pub(crate) fn prepare_metadata_for_build_wheel(metadata_directory: &Path) -> Result<ExitStatus> {
let filename = uv_build_backend::metadata(&env::current_dir()?, metadata_directory)?; let filename = uv_build_backend::metadata(
&env::current_dir()?,
metadata_directory,
uv_version::version(),
)?;
println!("{filename}"); println!("{filename}");
Ok(ExitStatus::Success) Ok(ExitStatus::Success)
} }