From e6126ce0dc105c329dac4d45cf74c2ea8c944882 Mon Sep 17 00:00:00 2001 From: Frost Ming <me@frostming.com> Date: Thu, 26 Dec 2024 22:33:32 +0800 Subject: [PATCH] fix: always write slash paths to RECORD file (#10164) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Frost Ming <me@frostming.com> <!-- Thank you for contributing to uv! To help us out with reviewing, please consider the following: - Does this pull request include a summary of the change? (See below.) - Does this pull request include a descriptive title? - Does this pull request include references to any relevant issues? --> ## Summary This PR solves an issue on Windows that platform-specific paths are written to the `RECORD` file when installing, which is inconsistent with PEP 376, quoting: > Each record is composed of three elements: > >the file’s path > * a ‘/’-separated path, relative to the base location, if the file is under the base location. > * a ‘/’-separated path, relative to the base location, if the file is under the installation prefix AND if the base location is a subpath of the installation prefix. > * an absolute path, using the local platform separator ## Test Plan <!-- How was it tested? --> Test case included --------- Signed-off-by: Frost Ming <me@frostming.com> Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com> --- crates/uv-install-wheel/src/wheel.rs | 37 ++++++++++++++++++++++++++-- crates/uv-tool/src/lib.rs | 11 ++++----- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/crates/uv-install-wheel/src/wheel.rs b/crates/uv-install-wheel/src/wheel.rs index a349b8a79854..8218f75ae758 100644 --- a/crates/uv-install-wheel/src/wheel.rs +++ b/crates/uv-install-wheel/src/wheel.rs @@ -604,7 +604,7 @@ pub(crate) fn write_file_recorded( let hash = Sha256::new().chain_update(content.as_ref()).finalize(); let encoded_hash = format!("sha256={}", BASE64URL_NOPAD.encode(&hash)); record.push(RecordEntry { - path: relative_path.display().to_string(), + path: relative_path.portable_display().to_string(), hash: Some(encoded_hash), size: Some(content.as_ref().len() as u64), }); @@ -741,7 +741,8 @@ mod test { use crate::Error; use super::{ - get_script_executable, parse_email_message_file, parse_wheel_file, read_record_file, Script, + get_script_executable, parse_email_message_file, parse_wheel_file, read_record_file, + write_installer_metadata, RecordEntry, Script, }; #[test] @@ -1016,4 +1017,36 @@ mod test { Ok(()) } + + #[test] + fn test_write_installer_metadata() { + let temp_dir = assert_fs::TempDir::new().unwrap(); + let site_packages = temp_dir.path(); + let mut record: Vec<RecordEntry> = Vec::new(); + temp_dir + .child("foo-0.1.0.dist-info") + .create_dir_all() + .unwrap(); + write_installer_metadata( + site_packages, + "foo-0.1.0", + true, + None, + None, + Some("uv"), + &mut record, + ) + .unwrap(); + let expected = [ + "foo-0.1.0.dist-info/REQUESTED", + "foo-0.1.0.dist-info/INSTALLER", + ] + .map(ToString::to_string) + .to_vec(); + let actual = record + .into_iter() + .map(|entry| entry.path) + .collect::<Vec<String>>(); + assert_eq!(expected, actual); + } } diff --git a/crates/uv-tool/src/lib.rs b/crates/uv-tool/src/lib.rs index 94e67a6cceee..081be9a72511 100644 --- a/crates/uv-tool/src/lib.rs +++ b/crates/uv-tool/src/lib.rs @@ -418,12 +418,11 @@ pub fn entrypoint_paths( }; let absolute_path = layout.scheme.scripts.join(path_in_scripts); - let script_name = entry - .path - .rsplit(std::path::MAIN_SEPARATOR) - .next() - .unwrap_or(&entry.path) - .to_string(); + let script_name = relative_path + .file_name() + .and_then(|filename| filename.to_str()) + .map(ToString::to_string) + .unwrap_or(entry.path); entrypoints.push((script_name, absolute_path)); }