Skip to content

Commit

Permalink
Add support for path deps in git
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Dec 21, 2024
1 parent 6e8114a commit 3e61108
Show file tree
Hide file tree
Showing 46 changed files with 2,234 additions and 358 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions crates/uv-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ uv-configuration = { workspace = true }
uv-distribution-filename = { workspace = true }
uv-distribution-types = { workspace = true }
uv-fs = { workspace = true, features = ["tokio"] }
uv-git = { workspace = true }
uv-metadata = { workspace = true }
uv-normalize = { workspace = true }
uv-pep440 = { workspace = true }
Expand Down
3 changes: 3 additions & 0 deletions crates/uv-client/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@ pub enum ErrorKind {
#[error(transparent)]
JoinRelativeUrl(#[from] uv_pypi_types::JoinRelativeError),

#[error(transparent)]
Git(#[from] uv_git::GitResolverError),

#[error("Expected a file URL, but received: {0}")]
NonFileUrl(Url),

Expand Down
34 changes: 34 additions & 0 deletions crates/uv-client/src/registry_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use std::collections::BTreeMap;
use std::fmt::Debug;
use std::path::PathBuf;
use std::str::FromStr;
use std::sync::Arc;
use std::time::Duration;
use tracing::{info_span, instrument, trace, warn, Instrument};
use url::Url;
Expand All @@ -19,6 +20,7 @@ use uv_distribution_filename::{DistFilename, SourceDistFilename, WheelFilename};
use uv_distribution_types::{
BuiltDist, File, FileLocation, Index, IndexCapabilities, IndexUrl, IndexUrls, Name,
};
use uv_git::{GitResolver, Reporter};
use uv_metadata::{read_metadata_async_seek, read_metadata_async_stream};
use uv_normalize::PackageName;
use uv_pep440::Version;
Expand Down Expand Up @@ -446,7 +448,9 @@ impl RegistryClient {
pub async fn wheel_metadata(
&self,
built_dist: &BuiltDist,
git: &GitResolver,
capabilities: &IndexCapabilities,
reporter: Option<Arc<dyn Reporter>>,
) -> Result<ResolutionMetadata, Error> {
let metadata = match &built_dist {
BuiltDist::Registry(wheels) => {
Expand Down Expand Up @@ -539,6 +543,36 @@ impl RegistryClient {
)
})?
}
BuiltDist::GitPath(wheel) => {
// Fetch the Git repository.
let fetch = git
.fetch(
&wheel.git,
self.uncached_client(&wheel.url).clone(),
self.cache.bucket(CacheBucket::Git),
reporter,
)
.await
.map_err(ErrorKind::Git)?;

// Read the metadata.
let file = fs_err::tokio::File::open(fetch.path().join(&wheel.install_path))
.await
.map_err(ErrorKind::Io)?;
let reader = tokio::io::BufReader::new(file);
let contents = read_metadata_async_seek(&wheel.filename, reader)
.await
.map_err(|err| {
ErrorKind::Metadata(wheel.install_path.to_string_lossy().to_string(), err)
})?;
ResolutionMetadata::parse_metadata(&contents).map_err(|err| {
ErrorKind::MetadataParseError(
wheel.filename.clone(),
built_dist.to_string(),
Box::new(err),
)
})?
}
};

if metadata.name != *built_dist.name() {
Expand Down
7 changes: 6 additions & 1 deletion crates/uv-client/tests/it/remote_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use uv_cache::Cache;
use uv_client::RegistryClientBuilder;
use uv_distribution_filename::WheelFilename;
use uv_distribution_types::{BuiltDist, DirectUrlBuiltDist, IndexCapabilities};
use uv_git::GitResolver;
use uv_pep508::VerbatimUrl;

#[tokio::test]
Expand All @@ -24,8 +25,12 @@ async fn remote_metadata_with_and_without_cache() -> Result<()> {
location: Url::parse(url).unwrap(),
url: VerbatimUrl::from_str(url).unwrap(),
});
let resolver = GitResolver::default();
let capabilities = IndexCapabilities::default();
let metadata = client.wheel_metadata(&dist, &capabilities).await.unwrap();
let metadata = client
.wheel_metadata(&dist, &resolver, &capabilities, None)
.await
.unwrap();
assert_eq!(metadata.version.to_string(), "4.66.1");
}

Expand Down
1 change: 1 addition & 0 deletions crates/uv-dev/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ uv-client = { workspace = true }
uv-distribution-filename = { workspace = true }
uv-distribution-types = { workspace = true }
uv-extract = { workspace = true, optional = true }
uv-git = { workspace = true }
uv-installer = { workspace = true }
uv-macros = { workspace = true }
uv-options-metadata = { workspace = true }
Expand Down
4 changes: 4 additions & 0 deletions crates/uv-dev/src/wheel_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use uv_cache::{Cache, CacheArgs};
use uv_client::RegistryClientBuilder;
use uv_distribution_filename::WheelFilename;
use uv_distribution_types::{BuiltDist, DirectUrlBuiltDist, IndexCapabilities, RemoteSource};
use uv_git::GitResolver;
use uv_pep508::VerbatimUrl;
use uv_pypi_types::ParsedUrl;

Expand All @@ -21,6 +22,7 @@ pub(crate) struct WheelMetadataArgs {
pub(crate) async fn wheel_metadata(args: WheelMetadataArgs) -> Result<()> {
let cache = Cache::try_from(args.cache_args)?.init()?;
let client = RegistryClientBuilder::new(cache).build();
let resolver = GitResolver::default();
let capabilities = IndexCapabilities::default();

let filename = WheelFilename::from_str(&args.url.filename()?)?;
Expand All @@ -36,7 +38,9 @@ pub(crate) async fn wheel_metadata(args: WheelMetadataArgs) -> Result<()> {
location: archive.url,
url: args.url,
}),
&resolver,
&capabilities,
None,
)
.await?;
println!("{metadata:?}");
Expand Down
48 changes: 40 additions & 8 deletions crates/uv-distribution-types/src/buildable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ use uv_pep508::VerbatimUrl;

use uv_normalize::PackageName;

use crate::{DirectorySourceDist, GitSourceDist, Name, PathSourceDist, SourceDist};
use crate::{
DirectorySourceDist, GitDirectorySourceDist, GitPathSourceDist, Name, PathSourceDist,
SourceDist,
};

/// A reference to a source that can be built into a built distribution.
///
Expand Down Expand Up @@ -88,7 +91,8 @@ impl std::fmt::Display for BuildableSource<'_> {
#[derive(Debug, Clone)]
pub enum SourceUrl<'a> {
Direct(DirectSourceUrl<'a>),
Git(GitSourceUrl<'a>),
GitDirectory(GitDirectorySourceUrl<'a>),
GitPath(GitPathSourceUrl<'a>),
Path(PathSourceUrl<'a>),
Directory(DirectorySourceUrl<'a>),
}
Expand All @@ -98,7 +102,8 @@ impl SourceUrl<'_> {
pub fn url(&self) -> &Url {
match self {
Self::Direct(dist) => dist.url,
Self::Git(dist) => dist.url,
Self::GitDirectory(dist) => dist.url,
Self::GitPath(dist) => dist.url,
Self::Path(dist) => dist.url,
Self::Directory(dist) => dist.url,
}
Expand All @@ -122,7 +127,8 @@ impl std::fmt::Display for SourceUrl<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Direct(url) => write!(f, "{url}"),
Self::Git(url) => write!(f, "{url}"),
Self::GitDirectory(url) => write!(f, "{url}"),
Self::GitPath(url) => write!(f, "{url}"),
Self::Path(url) => write!(f, "{url}"),
Self::Directory(url) => write!(f, "{url}"),
}
Expand All @@ -143,22 +149,48 @@ impl std::fmt::Display for DirectSourceUrl<'_> {
}

#[derive(Debug, Clone)]
pub struct GitSourceUrl<'a> {
pub struct GitPathSourceUrl<'a> {
/// The URL with the revision and path fragment.
pub url: &'a VerbatimUrl,
pub git: &'a GitUrl,
pub path: Cow<'a, Path>,
pub ext: SourceDistExtension,
}

impl std::fmt::Display for GitPathSourceUrl<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{url}", url = self.url)
}
}

impl<'a> From<&'a GitPathSourceDist> for GitPathSourceUrl<'a> {
fn from(dist: &'a GitPathSourceDist) -> Self {
Self {
url: &dist.url,
git: &dist.git,
path: Cow::Borrowed(&dist.install_path),
ext: dist.ext,
}
}
}

#[derive(Debug, Clone)]
pub struct GitDirectorySourceUrl<'a> {
/// The URL with the revision and subdirectory fragment.
pub url: &'a VerbatimUrl,
pub git: &'a GitUrl,
/// The URL without the revision and subdirectory fragment.
pub subdirectory: Option<&'a Path>,
}

impl std::fmt::Display for GitSourceUrl<'_> {
impl std::fmt::Display for GitDirectorySourceUrl<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{url}", url = self.url)
}
}

impl<'a> From<&'a GitSourceDist> for GitSourceUrl<'a> {
fn from(dist: &'a GitSourceDist) -> Self {
impl<'a> From<&'a GitDirectorySourceDist> for GitDirectorySourceUrl<'a> {
fn from(dist: &'a GitDirectorySourceDist) -> Self {
Self {
url: &dist.url,
git: &dist.git,
Expand Down
20 changes: 19 additions & 1 deletion crates/uv-distribution-types/src/cached.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,15 @@ impl CachedDist {
editable: false,
r#virtual: false,
}),
Dist::Built(BuiltDist::GitPath(dist)) => Self::Url(CachedDirectUrlDist {
filename,
url: dist.url,
hashes,
cache_info,
path,
editable: false,
r#virtual: false,
}),
Dist::Source(SourceDist::Registry(_dist)) => Self::Registry(CachedRegistryDist {
filename,
path,
Expand All @@ -90,7 +99,16 @@ impl CachedDist {
editable: false,
r#virtual: false,
}),
Dist::Source(SourceDist::Git(dist)) => Self::Url(CachedDirectUrlDist {
Dist::Source(SourceDist::GitDirectory(dist)) => Self::Url(CachedDirectUrlDist {
filename,
url: dist.url,
hashes,
cache_info,
path,
editable: false,
r#virtual: false,
}),
Dist::Source(SourceDist::GitPath(dist)) => Self::Url(CachedDirectUrlDist {
filename,
url: dist.url,
hashes,
Expand Down
4 changes: 4 additions & 0 deletions crates/uv-distribution-types/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::path::PathBuf;
use url::Url;

use uv_normalize::PackageName;
Expand All @@ -16,6 +17,9 @@ pub enum Error {
#[error("Could not extract path segments from URL: {0}")]
MissingPathSegments(String),

#[error("Could not extract wheel filename from path: {}", _0.display())]
MissingWheelFilename(PathBuf),

#[error("Distribution not found at: {0}")]
NotFound(Url),

Expand Down
12 changes: 12 additions & 0 deletions crates/uv-distribution-types/src/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,15 @@ pub trait Hashed {
}
}
}

impl Hashed for Vec<HashDigest> {
fn hashes(&self) -> &[HashDigest] {
self
}
}

impl Hashed for &[HashDigest] {
fn hashes(&self) -> &[HashDigest] {
self
}
}
Loading

0 comments on commit 3e61108

Please sign in to comment.