diff --git a/crates/uv-resolver/src/lock/requirements_txt.rs b/crates/uv-resolver/src/lock/requirements_txt.rs index b7f25dba4b90..a1dc75983476 100644 --- a/crates/uv-resolver/src/lock/requirements_txt.rs +++ b/crates/uv-resolver/src/lock/requirements_txt.rs @@ -1,7 +1,8 @@ +use std::borrow::Cow; use std::collections::hash_map::Entry; use std::collections::VecDeque; use std::fmt::Formatter; -use std::path::{Path, PathBuf}; +use std::path::{Component, Path, PathBuf}; use either::Either; use petgraph::visit::IntoNodeReferences; @@ -191,20 +192,14 @@ impl std::fmt::Display for RequirementsTxtExport<'_> { write!(f, "{} @ {}", package.id.name, url)?; } Source::Path(path) | Source::Directory(path) => { - if path.as_os_str().is_empty() { - write!(f, ".")?; - } else if path.is_absolute() { + if path.is_absolute() { write!(f, "{}", Url::from_file_path(path).unwrap())?; } else { - write!(f, "{}", path.portable_display())?; + write!(f, "{}", anchor(path).portable_display())?; } } Source::Editable(path) => { - if path.as_os_str().is_empty() { - write!(f, "-e .")?; - } else { - write!(f, "-e {}", path.portable_display())?; - } + write!(f, "-e {}", anchor(path).portable_display())?; } Source::Virtual(_) => { continue; @@ -252,3 +247,14 @@ impl<'lock> From<&'lock Package> for NodeComparator<'lock> { } } } + +/// Modify a relative [`Path`] to anchor it at the current working directory. +/// +/// For example, given `foo/bar`, returns `./foo/bar`. +fn anchor(path: &Path) -> Cow<'_, Path> { + match path.components().next() { + None => Cow::Owned(PathBuf::from(".")), + Some(Component::CurDir | Component::ParentDir) => Cow::Borrowed(path), + _ => Cow::Owned(PathBuf::from("./").join(path)), + } +} diff --git a/crates/uv/tests/export.rs b/crates/uv/tests/export.rs index 6839b36fec35..aca409c99ef4 100644 --- a/crates/uv/tests/export.rs +++ b/crates/uv/tests/export.rs @@ -451,7 +451,7 @@ fn non_root() -> Result<()> { ----- stdout ----- # This file was autogenerated by uv via the following command: # uv export --cache-dir [CACHE_DIR] --package child - -e child + -e ./child iniconfig==2.0.0 \ --hash=sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3 \ --hash=sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374 @@ -767,7 +767,7 @@ fn no_emit() -> Result<()> { # This file was autogenerated by uv via the following command: # uv export --cache-dir [CACHE_DIR] --no-emit-package anyio -e . - -e child + -e ./child idna==3.6 \ --hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \ --hash=sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f @@ -789,7 +789,7 @@ fn no_emit() -> Result<()> { ----- stdout ----- # This file was autogenerated by uv via the following command: # uv export --cache-dir [CACHE_DIR] --no-emit-project - -e child + -e ./child anyio==3.7.0 \ --hash=sha256:275d9973793619a5374e1c89a4f4ad3f4b0a5510a2b5b939444bee8f4c4d37ce \ --hash=sha256:eddca883c4175f14df8aedce21054bfca3adb70ffe76a9f607aef9d7fa2ea7f0