mirror of
https://github.com/astral-sh/uv
synced 2026-01-21 13:30:11 -05:00
Only write portable paths in RECORD (#17339)
The spec allows both, but we're already using forward paths for paths that are not created by uv. See * https://github.com/astral-sh/uv/issues/14446 * https://github.com/python/importlib_metadata/issues/528 Closes #14446 --------- Co-authored-by: Tomasz Kramkowski <tom@astral.sh>
This commit is contained in:
@@ -373,7 +373,9 @@ pub(crate) fn move_folder_recorded(
|
||||
src.simplified_display()
|
||||
))
|
||||
})?;
|
||||
entry.path = relative_to(&target, site_packages)?.display().to_string();
|
||||
entry.path = relative_to(&target, site_packages)?
|
||||
.portable_display()
|
||||
.to_string();
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@@ -576,7 +578,7 @@ fn install_script(
|
||||
})?;
|
||||
|
||||
// Update the entry in the `RECORD`.
|
||||
entry.path = script_relative.simplified_display().to_string();
|
||||
entry.path = script_relative.portable_display().to_string();
|
||||
if let Some((size, encoded_hash)) = size_and_encoded_hash {
|
||||
entry.size = Some(size);
|
||||
entry.hash = Some(encoded_hash);
|
||||
|
||||
@@ -13660,3 +13660,65 @@ fn build_backend_wrong_wheel_platform() -> Result<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Test that RECORD entries use forward slashes on all platforms.
|
||||
///
|
||||
/// See <https://github.com/astral-sh/uv/issues/14446>.
|
||||
#[test]
|
||||
fn record_uses_forward_slashes() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
// Create a package with scripts via uv_build data directory.
|
||||
let pyproject_toml = context.temp_dir.child("pyproject.toml");
|
||||
pyproject_toml.write_str(indoc! {r#"
|
||||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
|
||||
[build-system]
|
||||
requires = ["uv_build>=0.7,<10000"]
|
||||
build-backend = "uv_build"
|
||||
|
||||
[tool.uv.build-backend.data]
|
||||
scripts = "scripts"
|
||||
headers = "headers"
|
||||
"#})?;
|
||||
|
||||
let module_dir = context.temp_dir.child("src").child("project");
|
||||
module_dir.child("__init__.py").touch()?;
|
||||
|
||||
// Create a script that uses the install_script path.
|
||||
let scripts_dir = context.temp_dir.child("scripts");
|
||||
scripts_dir.child("my_script").write_str(indoc! {r#"
|
||||
#!python
|
||||
print("Hello from script")
|
||||
"#})?;
|
||||
|
||||
let scripts_dir = context.temp_dir.child("headers");
|
||||
scripts_dir.child("project.h").write_str(indoc! {r"
|
||||
#include <stdio.h>
|
||||
"})?;
|
||||
|
||||
context.pip_install().arg(".").assert().success();
|
||||
|
||||
// Read the RECORD file and check that all paths use forward slashes.
|
||||
let record_path = context
|
||||
.site_packages()
|
||||
.join("project-0.1.0.dist-info")
|
||||
.join("RECORD");
|
||||
|
||||
let record = fs::read_to_string(&record_path)?;
|
||||
let record_lines: Vec<_> = record
|
||||
.lines()
|
||||
.filter(|line| !line.trim().is_empty())
|
||||
.collect();
|
||||
assert!(record_lines.iter().any(|line| line.contains("/my_script")));
|
||||
assert!(record_lines.iter().any(|line| line.contains("/project.h")));
|
||||
for line in record_lines {
|
||||
// Each RECORD line is: path,hash,size
|
||||
let path = line.split(',').next().unwrap();
|
||||
assert!(!path.contains('\\'), "{path}");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -3147,9 +3147,9 @@ fn tool_run_windows_runnable_types() -> anyhow::Result<()> {
|
||||
----- stderr -----
|
||||
An executable named `does_not_exist` is not provided by package `foo`.
|
||||
The following executables are available:
|
||||
- custom_pydoc.exe
|
||||
- custom_pydoc.bat
|
||||
- custom_pydoc.cmd
|
||||
- custom_pydoc.exe
|
||||
- custom_pydoc.ps1
|
||||
"###);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user