From 1d5808c18af022b983ca5db6ef691b83b6104a23 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Sat, 24 Aug 2024 22:25:09 -0400 Subject: [PATCH] Allow relative --- crates/pypi-types/src/requirement.rs | 6 ++++-- crates/uv-fs/src/path.rs | 3 +++ crates/uv-resolver/src/lock.rs | 27 +++++++++++++++++---------- crates/uv/tests/sync.rs | 6 +++--- 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/crates/pypi-types/src/requirement.rs b/crates/pypi-types/src/requirement.rs index 3952af9777e52..594b187cf1bcf 100644 --- a/crates/pypi-types/src/requirement.rs +++ b/crates/pypi-types/src/requirement.rs @@ -507,7 +507,8 @@ impl RequirementSource { ext, url, } => Ok(Self::Path { - install_path: relative_to(&install_path, path)?, + install_path: relative_to(&install_path, path) + .or_else(|_| std::path::absolute(install_path))?, ext, url, }), @@ -516,7 +517,8 @@ impl RequirementSource { editable, url, } => Ok(Self::Directory { - install_path: relative_to(&install_path, path)?, + install_path: relative_to(&install_path, path) + .or_else(|_| std::path::absolute(install_path))?, editable, url, }), diff --git a/crates/uv-fs/src/path.rs b/crates/uv-fs/src/path.rs index 5174817f98778..25e435b92a6a6 100644 --- a/crates/uv-fs/src/path.rs +++ b/crates/uv-fs/src/path.rs @@ -270,6 +270,9 @@ pub fn canonicalize_executable(path: impl AsRef) -> std::io::Result `foo/__init__.py` /// `lib/marker.txt` and `lib/python/site-packages` -> `../../marker.txt` /// `bin/foo_launcher` and `lib/python/site-packages` -> `../../../bin/foo_launcher` +/// +/// Returns `Err` if there is no relative path between `path` and `base` (for example, if the paths +/// are on different drives on Windows). pub fn relative_to( path: impl AsRef, base: impl AsRef, diff --git a/crates/uv-resolver/src/lock.rs b/crates/uv-resolver/src/lock.rs index 38eb47f1a3fc6..3c78c664a0bde 100644 --- a/crates/uv-resolver/src/lock.rs +++ b/crates/uv-resolver/src/lock.rs @@ -791,7 +791,9 @@ impl Lock { IndexUrl::Pypi(_) | IndexUrl::Url(_) => None, IndexUrl::Path(index_url) => { let path = index_url.to_file_path().ok()?; - let path = relative_to(&path, workspace.install_path()).ok()?; + let path = relative_to(&path, workspace.install_path()) + .or_else(|_| std::path::absolute(path)) + .ok()?; Some(path) } }) @@ -802,7 +804,9 @@ impl Lock { FlatIndexLocation::Url(_) => None, FlatIndexLocation::Path(index_url) => { let path = index_url.to_file_path().ok()?; - let path = relative_to(&path, workspace.install_path()).ok()?; + let path = relative_to(&path, workspace.install_path()) + .or_else(|_| std::path::absolute(path)) + .ok()?; Some(path) } }), @@ -2026,14 +2030,15 @@ impl Source { fn from_path_built_dist(path_dist: &PathBuiltDist, root: &Path) -> Result { let path = relative_to(&path_dist.install_path, root) + .or_else(|_| std::path::absolute(&path_dist.install_path)) .map_err(LockErrorKind::DistributionRelativePath)?; Ok(Source::Path(path)) } fn from_path_source_dist(path_dist: &PathSourceDist, root: &Path) -> Result { let path = relative_to(&path_dist.install_path, root) + .or_else(|_| std::path::absolute(&path_dist.install_path)) .map_err(LockErrorKind::DistributionRelativePath)?; - Ok(Source::Path(path)) } @@ -2042,6 +2047,7 @@ impl Source { root: &Path, ) -> Result { let path = relative_to(&directory_dist.install_path, root) + .or_else(|_| std::path::absolute(&directory_dist.install_path)) .map_err(LockErrorKind::DistributionRelativePath)?; if directory_dist.editable { Ok(Source::Editable(path)) @@ -2059,11 +2065,10 @@ impl Source { Ok(Source::Registry(source)) } IndexUrl::Path(url) => { - let path = relative_to( - url.to_file_path().map_err(|()| LockErrorKind::UrlToPath)?, - root, - ) - .map_err(LockErrorKind::IndexRelativePath)?; + let path = url.to_file_path().map_err(|()| LockErrorKind::UrlToPath)?; + let path = relative_to(&path, root) + .or_else(|_| std::path::absolute(&path)) + .map_err(LockErrorKind::IndexRelativePath)?; let source = RegistrySource::Path(path); Ok(Source::Registry(source)) } @@ -2520,7 +2525,8 @@ impl SourceDist { .map_err(LockErrorKind::InvalidFileUrl)? .to_file_path() .map_err(|()| LockErrorKind::UrlToPath)?; - let path = relative_to(reg_dist_path, index_path) + let path = relative_to(®_dist_path, index_path) + .or_else(|_| std::path::absolute(®_dist_path)) .map_err(LockErrorKind::DistributionRelativePath)?; let hash = reg_dist.file.hashes.iter().max().cloned().map(Hash::from); let size = reg_dist.file.size; @@ -2798,7 +2804,8 @@ impl Wheel { .map_err(LockErrorKind::InvalidFileUrl)? .to_file_path() .map_err(|()| LockErrorKind::UrlToPath)?; - let path = relative_to(wheel_path, index_path) + let path = relative_to(&wheel_path, index_path) + .or_else(|_| std::path::absolute(&wheel_path)) .map_err(LockErrorKind::DistributionRelativePath)?; Ok(Wheel { url: WheelWireSource::Path { path }, diff --git a/crates/uv/tests/sync.rs b/crates/uv/tests/sync.rs index 2ea551facf0f7..f2462ab76ef81 100644 --- a/crates/uv/tests/sync.rs +++ b/crates/uv/tests/sync.rs @@ -724,7 +724,7 @@ fn sync_relative_wheel() -> Result<()> { [[package]] name = "ok" version = "1.0.0" - source = { path = "wheels/ok-1.0.0-py3-none-any.whl" } + source = { path = "[TEMP_DIR]/wheels/ok-1.0.0-py3-none-any.whl" } wheels = [ { filename = "ok-1.0.0-py3-none-any.whl", hash = "sha256:79f0b33e6ce1e09eaa1784c8eee275dfe84d215d9c65c652f07c18e85fdaac5f" }, ] @@ -732,13 +732,13 @@ fn sync_relative_wheel() -> Result<()> { [[package]] name = "relative-wheel" version = "0.1.0" - source = { editable = "." } + source = { editable = "[TEMP_DIR]/" } dependencies = [ { name = "ok" }, ] [package.metadata] - requires-dist = [{ name = "ok", path = "wheels/ok-1.0.0-py3-none-any.whl" }] + requires-dist = [{ name = "ok", path = "[TEMP_DIR]/wheels/ok-1.0.0-py3-none-any.whl" }] "### ); }