Skip to content

Commit

Permalink
Use portable paths when serializing sources (#7504)
Browse files Browse the repository at this point in the history
## Summary

Closes #7493.
  • Loading branch information
charliermarsh authored Sep 18, 2024
1 parent 1379b53 commit e36cc99
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 36 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 12 additions & 6 deletions crates/uv-distribution/src/metadata/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,20 +88,20 @@ impl LoweredRequirement {
if matches!(requirement.version_or_url, Some(VersionOrUrl::Url(_))) {
return Err(LoweringError::ConflictingUrls);
}
git_source(&git, subdirectory, rev, tag, branch)?
git_source(&git, subdirectory.map(PathBuf::from), rev, tag, branch)?
}
Source::Url { url, subdirectory } => {
if matches!(requirement.version_or_url, Some(VersionOrUrl::Url(_))) {
return Err(LoweringError::ConflictingUrls);
}
url_source(url, subdirectory)?
url_source(url, subdirectory.map(PathBuf::from))?
}
Source::Path { path, editable } => {
if matches!(requirement.version_or_url, Some(VersionOrUrl::Url(_))) {
return Err(LoweringError::ConflictingUrls);
}
path_source(
path,
PathBuf::from(path),
origin,
project_dir,
workspace.install_path(),
Expand Down Expand Up @@ -203,19 +203,25 @@ impl LoweredRequirement {
if matches!(requirement.version_or_url, Some(VersionOrUrl::Url(_))) {
return Err(LoweringError::ConflictingUrls);
}
git_source(&git, subdirectory, rev, tag, branch)?
git_source(&git, subdirectory.map(PathBuf::from), rev, tag, branch)?
}
Source::Url { url, subdirectory } => {
if matches!(requirement.version_or_url, Some(VersionOrUrl::Url(_))) {
return Err(LoweringError::ConflictingUrls);
}
url_source(url, subdirectory)?
url_source(url, subdirectory.map(PathBuf::from))?
}
Source::Path { path, editable } => {
if matches!(requirement.version_or_url, Some(VersionOrUrl::Url(_))) {
return Err(LoweringError::ConflictingUrls);
}
path_source(path, Origin::Project, dir, dir, editable.unwrap_or(false))?
path_source(
PathBuf::from(path),
Origin::Project,
dir,
dir,
editable.unwrap_or(false),
)?
}
Source::Registry { index } => registry_source(&requirement, index)?,
Source::Workspace { .. } => {
Expand Down
1 change: 1 addition & 0 deletions crates/uv-fs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ encoding_rs_io = { workspace = true }
fs-err = { workspace = true }
fs2 = { workspace = true }
path-slash = { workspace = true }
schemars = { workspace = true, optional = true }
serde = { workspace = true, optional = true }
tokio = { workspace = true, optional = true}
tempfile = { workspace = true }
Expand Down
11 changes: 11 additions & 0 deletions crates/uv-fs/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,17 @@ pub struct PortablePath<'a>(&'a Path);
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PortablePathBuf(PathBuf);

#[cfg(feature = "schemars")]
impl schemars::JsonSchema for PortablePathBuf {
fn schema_name() -> String {
PathBuf::schema_name()
}

fn json_schema(_gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
PathBuf::json_schema(_gen)
}
}

impl AsRef<Path> for PortablePath<'_> {
fn as_ref(&self) -> &Path {
self.0
Expand Down
2 changes: 1 addition & 1 deletion crates/uv-workspace/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ workspace = true
pep440_rs = { workspace = true }
pep508_rs = { workspace = true }
pypi-types = { workspace = true }
uv-fs = { workspace = true, features = ["tokio"] }
uv-fs = { workspace = true, features = ["tokio", "schemars"] }
uv-git = { workspace = true }
uv-macros = { workspace = true }
uv-normalize = { workspace = true }
Expand Down
26 changes: 14 additions & 12 deletions crates/uv-workspace/src/pyproject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use url::Url;

use pep440_rs::{Version, VersionSpecifiers};
use pypi_types::{RequirementSource, SupportedEnvironments, VerbatimParsedUrl};
use uv_fs::relative_to;
use uv_fs::{relative_to, PortablePathBuf};
use uv_git::GitReference;
use uv_macros::OptionsMetadata;
use uv_normalize::{ExtraName, PackageName};
Expand Down Expand Up @@ -413,7 +413,7 @@ pub enum Source {
/// The repository URL (without the `git+` prefix).
git: Url,
/// The path to the directory with the `pyproject.toml`, if it's not in the archive root.
subdirectory: Option<PathBuf>,
subdirectory: Option<PortablePathBuf>,
// Only one of the three may be used; we'll validate this later and emit a custom error.
rev: Option<String>,
tag: Option<String>,
Expand All @@ -430,13 +430,13 @@ pub enum Source {
url: Url,
/// For source distributions, the path to the directory with the `pyproject.toml`, if it's
/// not in the archive root.
subdirectory: Option<PathBuf>,
subdirectory: Option<PortablePathBuf>,
},
/// The path to a dependency, either a wheel (a `.whl` file), source distribution (a `.zip` or
/// `.tar.gz` file), or source tree (i.e., a directory containing a `pyproject.toml` or
/// `setup.py` file in the root).
Path {
path: PathBuf,
path: PortablePathBuf,
/// `false` by default.
editable: Option<bool>,
},
Expand All @@ -454,12 +454,12 @@ pub enum Source {
/// A catch-all variant used to emit precise error messages when deserializing.
CatchAll {
git: String,
subdirectory: Option<PathBuf>,
subdirectory: Option<PortablePathBuf>,
rev: Option<String>,
tag: Option<String>,
branch: Option<String>,
url: String,
path: PathBuf,
path: PortablePathBuf,
index: String,
workspace: bool,
},
Expand Down Expand Up @@ -534,15 +534,17 @@ impl Source {
RequirementSource::Path { install_path, .. }
| RequirementSource::Directory { install_path, .. } => Source::Path {
editable,
path: relative_to(&install_path, root)
.or_else(|_| std::path::absolute(&install_path))
.map_err(SourceError::Absolute)?,
path: PortablePathBuf::from(
relative_to(&install_path, root)
.or_else(|_| std::path::absolute(&install_path))
.map_err(SourceError::Absolute)?,
),
},
RequirementSource::Url {
subdirectory, url, ..
} => Source::Url {
url: url.to_url(),
subdirectory,
subdirectory: subdirectory.map(PortablePathBuf::from),
},
RequirementSource::Git {
repository,
Expand All @@ -566,15 +568,15 @@ impl Source {
tag,
branch,
git: repository,
subdirectory,
subdirectory: subdirectory.map(PortablePathBuf::from),
}
} else {
Source::Git {
rev,
tag,
branch,
git: repository,
subdirectory,
subdirectory: subdirectory.map(PortablePathBuf::from),
}
}
}
Expand Down
13 changes: 7 additions & 6 deletions crates/uv/tests/edit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use assert_cmd::assert::OutputAssertExt;
use assert_fs::prelude::*;
use indoc::indoc;
use insta::assert_snapshot;
use std::path::Path;

use crate::common::{decode_token, packse_index_url};
use common::{uv_snapshot, TestContext};
Expand Down Expand Up @@ -2019,7 +2020,7 @@ fn add_path() -> Result<()> {
build-backend = "setuptools.build_meta"
"#})?;

let child = workspace.child("child");
let child = workspace.child("packages").child("child");
child.child("pyproject.toml").write_str(indoc! {r#"
[project]
name = "child"
Expand All @@ -2032,7 +2033,7 @@ fn add_path() -> Result<()> {
build-backend = "setuptools.build_meta"
"#})?;

uv_snapshot!(context.filters(), context.add().arg("./child").current_dir(workspace.path()), @r###"
uv_snapshot!(context.filters(), context.add().arg(Path::new("packages").join("child")).current_dir(workspace.path()), @r###"
success: true
exit_code: 0
----- stdout -----
Expand All @@ -2043,7 +2044,7 @@ fn add_path() -> Result<()> {
Resolved 2 packages in [TIME]
Prepared 2 packages in [TIME]
Installed 2 packages in [TIME]
+ child==0.1.0 (from file://[TEMP_DIR]/workspace/child)
+ child==0.1.0 (from file://[TEMP_DIR]/workspace/packages/child)
+ parent==0.1.0 (from file://[TEMP_DIR]/workspace)
"###);

Expand All @@ -2067,7 +2068,7 @@ fn add_path() -> Result<()> {
build-backend = "setuptools.build_meta"
[tool.uv.sources]
child = { path = "child" }
child = { path = "packages/child" }
"###
);
});
Expand All @@ -2089,7 +2090,7 @@ fn add_path() -> Result<()> {
[[package]]
name = "child"
version = "0.1.0"
source = { directory = "child" }
source = { directory = "packages/child" }
[[package]]
name = "parent"
Expand All @@ -2100,7 +2101,7 @@ fn add_path() -> Result<()> {
]
[package.metadata]
requires-dist = [{ name = "child", directory = "child" }]
requires-dist = [{ name = "child", directory = "packages/child" }]
"###
);
});
Expand Down
34 changes: 23 additions & 11 deletions uv.schema.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit e36cc99

Please sign in to comment.