diff --git a/Cargo.lock b/Cargo.lock index c6353bc61..a2833c4fa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4585,6 +4585,7 @@ dependencies = [ "uv-extract", "uv-fs", "uv-git", + "uv-git-types", "uv-install-wheel", "uv-installer", "uv-normalize", @@ -5015,6 +5016,7 @@ dependencies = [ "uv-extract", "uv-fs", "uv-git", + "uv-git-types", "uv-metadata", "uv-normalize", "uv-pep440", @@ -5069,7 +5071,7 @@ dependencies = [ "uv-cache-key", "uv-distribution-filename", "uv-fs", - "uv-git", + "uv-git-types", "uv-normalize", "uv-pep440", "uv-pep508", @@ -5136,7 +5138,6 @@ dependencies = [ "fs-err 3.1.0", "reqwest", "reqwest-middleware", - "serde", "thiserror 2.0.11", "tokio", "tracing", @@ -5144,11 +5145,22 @@ dependencies = [ "uv-auth", "uv-cache-key", "uv-fs", + "uv-git-types", "uv-static", "uv-version", "which", ] +[[package]] +name = "uv-git-types" +version = "0.0.1" +dependencies = [ + "serde", + "thiserror 2.0.11", + "tracing", + "url", +] + [[package]] name = "uv-globfilter" version = "0.1.0" @@ -5228,7 +5240,7 @@ dependencies = [ "uv-distribution", "uv-distribution-types", "uv-fs", - "uv-git", + "uv-git-types", "uv-install-wheel", "uv-normalize", "uv-pep440", @@ -5420,7 +5432,7 @@ dependencies = [ "url", "uv-distribution-filename", "uv-fs", - "uv-git", + "uv-git-types", "uv-normalize", "uv-pep440", "uv-pep508", @@ -5507,6 +5519,7 @@ dependencies = [ "uv-distribution-types", "uv-fs", "uv-git", + "uv-git-types", "uv-normalize", "uv-pep508", "uv-pypi-types", @@ -5586,6 +5599,7 @@ dependencies = [ "uv-distribution-types", "uv-fs", "uv-git", + "uv-git-types", "uv-metadata", "uv-normalize", "uv-once-map", @@ -5808,7 +5822,7 @@ dependencies = [ "uv-cache-key", "uv-distribution-types", "uv-fs", - "uv-git", + "uv-git-types", "uv-macros", "uv-normalize", "uv-options-metadata", diff --git a/Cargo.toml b/Cargo.toml index 027a056ab..fbdaf7908 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,6 +39,7 @@ uv-distribution-types = { path = "crates/uv-distribution-types" } uv-extract = { path = "crates/uv-extract" } uv-fs = { path = "crates/uv-fs", features = ["serde", "tokio"] } uv-git = { path = "crates/uv-git" } +uv-git-types = { path = "crates/uv-git-types" } uv-globfilter = { path = "crates/uv-globfilter" } uv-install-wheel = { path = "crates/uv-install-wheel", default-features = false } uv-installer = { path = "crates/uv-installer" } diff --git a/crates/uv-distribution-types/Cargo.toml b/crates/uv-distribution-types/Cargo.toml index c2b5960af..39618e2d7 100644 --- a/crates/uv-distribution-types/Cargo.toml +++ b/crates/uv-distribution-types/Cargo.toml @@ -21,7 +21,7 @@ uv-cache-info = { workspace = true } uv-cache-key = { workspace = true } uv-distribution-filename = { workspace = true } uv-fs = { workspace = true } -uv-git = { workspace = true } +uv-git-types = { workspace = true } uv-normalize = { workspace = true } uv-pep440 = { workspace = true } uv-pep508 = { workspace = true } diff --git a/crates/uv-distribution-types/src/buildable.rs b/crates/uv-distribution-types/src/buildable.rs index de004393b..e633c81ad 100644 --- a/crates/uv-distribution-types/src/buildable.rs +++ b/crates/uv-distribution-types/src/buildable.rs @@ -3,7 +3,7 @@ use std::path::Path; use url::Url; use uv_distribution_filename::SourceDistExtension; -use uv_git::GitUrl; +use uv_git_types::GitUrl; use uv_pep440::{Version, VersionSpecifiers}; use uv_pep508::VerbatimUrl; diff --git a/crates/uv-distribution-types/src/lib.rs b/crates/uv-distribution-types/src/lib.rs index 1d2b0f442..bf098c73c 100644 --- a/crates/uv-distribution-types/src/lib.rs +++ b/crates/uv-distribution-types/src/lib.rs @@ -43,7 +43,7 @@ use uv_distribution_filename::{ DistExtension, SourceDistExtension, SourceDistFilename, WheelFilename, }; use uv_fs::normalize_absolute_path; -use uv_git::GitUrl; +use uv_git_types::GitUrl; use uv_normalize::PackageName; use uv_pep440::Version; use uv_pep508::{Pep508Url, VerbatimUrl}; diff --git a/crates/uv-distribution/Cargo.toml b/crates/uv-distribution/Cargo.toml index c6a3cfdc9..6207fea62 100644 --- a/crates/uv-distribution/Cargo.toml +++ b/crates/uv-distribution/Cargo.toml @@ -26,6 +26,7 @@ uv-distribution-types = { workspace = true } uv-extract = { workspace = true } uv-fs = { workspace = true, features = ["tokio"] } uv-git = { workspace = true } +uv-git-types = { workspace = true } uv-metadata = { workspace = true } uv-normalize = { workspace = true } uv-pep440 = { workspace = true } diff --git a/crates/uv-distribution/src/metadata/lowering.rs b/crates/uv-distribution/src/metadata/lowering.rs index ef6cf0a30..fc0243644 100644 --- a/crates/uv-distribution/src/metadata/lowering.rs +++ b/crates/uv-distribution/src/metadata/lowering.rs @@ -8,7 +8,7 @@ use url::Url; use uv_distribution_filename::DistExtension; use uv_distribution_types::{Index, IndexLocations, IndexName, Origin}; -use uv_git::GitReference; +use uv_git_types::GitReference; use uv_normalize::{ExtraName, GroupName, PackageName}; use uv_pep440::VersionSpecifiers; use uv_pep508::{looks_like_git_repository, MarkerTree, VerbatimUrl, VersionOrUrl}; diff --git a/crates/uv-distribution/src/source/mod.rs b/crates/uv-distribution/src/source/mod.rs index c3935272f..68c7e7a0b 100644 --- a/crates/uv-distribution/src/source/mod.rs +++ b/crates/uv-distribution/src/source/mod.rs @@ -36,7 +36,7 @@ use uv_distribution_types::{ }; use uv_extract::hash::Hasher; use uv_fs::{rename_with_retry, write_atomic}; -use uv_git::{GitHubRepository, GitOid}; +use uv_git_types::{GitHubRepository, GitOid}; use uv_metadata::read_archive_metadata; use uv_normalize::PackageName; use uv_pep440::{release_specifiers_to_ranges, Version}; diff --git a/crates/uv-git-types/Cargo.toml b/crates/uv-git-types/Cargo.toml new file mode 100644 index 000000000..98ef751c9 --- /dev/null +++ b/crates/uv-git-types/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "uv-git-types" +version = "0.0.1" +edition = { workspace = true } +rust-version = { workspace = true } +homepage = { workspace = true } +documentation = { workspace = true } +repository = { workspace = true } +authors = { workspace = true } +license = { workspace = true } + +[lib] +doctest = false + +[lints] +workspace = true + +[dependencies] +serde = { workspace = true } +thiserror = { workspace = true } +tracing = { workspace = true } +url = { workspace = true } diff --git a/crates/uv-git/src/github.rs b/crates/uv-git-types/src/github.rs similarity index 100% rename from crates/uv-git/src/github.rs rename to crates/uv-git-types/src/github.rs diff --git a/crates/uv-git-types/src/lib.rs b/crates/uv-git-types/src/lib.rs new file mode 100644 index 000000000..927e81869 --- /dev/null +++ b/crates/uv-git-types/src/lib.rs @@ -0,0 +1,125 @@ +pub use crate::github::GitHubRepository; +pub use crate::oid::{GitOid, OidParseError}; +pub use crate::reference::GitReference; +use url::Url; + +mod github; +mod oid; +mod reference; + +/// A URL reference to a Git repository. +#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Hash, Ord)] +pub struct GitUrl { + /// The URL of the Git repository, with any query parameters, fragments, and leading `git+` + /// removed. + repository: Url, + /// The reference to the commit to use, which could be a branch, tag or revision. + reference: GitReference, + /// The precise commit to use, if known. + precise: Option, +} + +impl GitUrl { + /// Create a new [`GitUrl`] from a repository URL and a reference. + pub fn from_reference(repository: Url, reference: GitReference) -> Self { + Self { + repository, + reference, + precise: None, + } + } + + /// Create a new [`GitUrl`] from a repository URL and a precise commit. + pub fn from_commit(repository: Url, reference: GitReference, precise: GitOid) -> Self { + Self { + repository, + reference, + precise: Some(precise), + } + } + + /// Set the precise [`GitOid`] to use for this Git URL. + #[must_use] + pub fn with_precise(mut self, precise: GitOid) -> Self { + self.precise = Some(precise); + self + } + + /// Set the [`GitReference`] to use for this Git URL. + #[must_use] + pub fn with_reference(mut self, reference: GitReference) -> Self { + self.reference = reference; + self + } + + /// Return the [`Url`] of the Git repository. + pub fn repository(&self) -> &Url { + &self.repository + } + + /// Return the reference to the commit to use, which could be a branch, tag or revision. + pub fn reference(&self) -> &GitReference { + &self.reference + } + + /// Return the precise commit, if known. + pub fn precise(&self) -> Option { + self.precise + } +} + +impl TryFrom for GitUrl { + type Error = OidParseError; + + /// Initialize a [`GitUrl`] source from a URL. + fn try_from(mut url: Url) -> Result { + // Remove any query parameters and fragments. + url.set_fragment(None); + url.set_query(None); + + // If the URL ends with a reference, like `https://git.example.com/MyProject.git@v1.0`, + // extract it. + let mut reference = GitReference::DefaultBranch; + if let Some((prefix, suffix)) = url + .path() + .rsplit_once('@') + .map(|(prefix, suffix)| (prefix.to_string(), suffix.to_string())) + { + reference = GitReference::from_rev(suffix); + url.set_path(&prefix); + } + + Ok(Self::from_reference(url, reference)) + } +} + +impl From for Url { + fn from(git: GitUrl) -> Self { + let mut url = git.repository; + + // If we have a precise commit, add `@` and the commit hash to the URL. + if let Some(precise) = git.precise { + url.set_path(&format!("{}@{}", url.path(), precise)); + } else { + // Otherwise, add the branch or tag name. + match git.reference { + GitReference::Branch(rev) + | GitReference::Tag(rev) + | GitReference::BranchOrTag(rev) + | GitReference::NamedRef(rev) + | GitReference::BranchOrTagOrCommit(rev) => { + url.set_path(&format!("{}@{}", url.path(), rev)); + } + GitReference::DefaultBranch => {} + } + } + + url + } +} + +impl std::fmt::Display for GitUrl { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.repository) + } +} diff --git a/crates/uv-git/src/oid.rs b/crates/uv-git-types/src/oid.rs similarity index 100% rename from crates/uv-git/src/oid.rs rename to crates/uv-git-types/src/oid.rs diff --git a/crates/uv-git-types/src/reference.rs b/crates/uv-git-types/src/reference.rs new file mode 100644 index 000000000..cb329cd7a --- /dev/null +++ b/crates/uv-git-types/src/reference.rs @@ -0,0 +1,80 @@ +use std::fmt::Display; +use std::str; + +/// A reference to commit or commit-ish. +#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub enum GitReference { + /// A specific branch. + Branch(String), + /// A specific tag. + Tag(String), + /// From a reference that's ambiguously a branch or tag. + BranchOrTag(String), + /// From a reference that's ambiguously a commit, branch, or tag. + BranchOrTagOrCommit(String), + /// From a named reference, like `refs/pull/493/head`. + NamedRef(String), + /// The default branch of the repository, the reference named `HEAD`. + DefaultBranch, +} + +impl GitReference { + /// Creates a [`GitReference`] from an arbitrary revision string, which could represent a + /// branch, tag, commit, or named ref. + pub fn from_rev(rev: String) -> Self { + if rev.starts_with("refs/") { + Self::NamedRef(rev) + } else if looks_like_commit_hash(&rev) { + Self::BranchOrTagOrCommit(rev) + } else { + Self::BranchOrTag(rev) + } + } + + /// Converts the [`GitReference`] to a `str`. + pub fn as_str(&self) -> Option<&str> { + match self { + Self::Tag(rev) => Some(rev), + Self::Branch(rev) => Some(rev), + Self::BranchOrTag(rev) => Some(rev), + Self::BranchOrTagOrCommit(rev) => Some(rev), + Self::NamedRef(rev) => Some(rev), + Self::DefaultBranch => None, + } + } + + /// Converts the [`GitReference`] to a `str` that can be used as a revision. + pub fn as_rev(&self) -> &str { + match self { + Self::Tag(rev) => rev, + Self::Branch(rev) => rev, + Self::BranchOrTag(rev) => rev, + Self::BranchOrTagOrCommit(rev) => rev, + Self::NamedRef(rev) => rev, + Self::DefaultBranch => "HEAD", + } + } + + /// Returns the kind of this reference. + pub fn kind_str(&self) -> &str { + match self { + Self::Branch(_) => "branch", + Self::Tag(_) => "tag", + Self::BranchOrTag(_) => "branch or tag", + Self::BranchOrTagOrCommit(_) => "branch, tag, or commit", + Self::NamedRef(_) => "ref", + Self::DefaultBranch => "default branch", + } + } +} + +impl Display for GitReference { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.as_str().unwrap_or("HEAD")) + } +} + +/// Whether a `rev` looks like a commit hash (ASCII hex digits). +fn looks_like_commit_hash(rev: &str) -> bool { + rev.len() >= 7 && rev.chars().all(|ch| ch.is_ascii_hexdigit()) +} diff --git a/crates/uv-git/Cargo.toml b/crates/uv-git/Cargo.toml index faa0cf008..600a19367 100644 --- a/crates/uv-git/Cargo.toml +++ b/crates/uv-git/Cargo.toml @@ -16,10 +16,11 @@ doctest = false workspace = true [dependencies] +uv-auth = { workspace = true } uv-cache-key = { workspace = true } uv-fs = { workspace = true, features = ["tokio"] } -uv-auth = { workspace = true } -uv-static = { workspace = true} +uv-git-types = { workspace = true } +uv-static = { workspace = true } uv-version = { workspace = true } anyhow = { workspace = true } @@ -28,7 +29,6 @@ dashmap = { workspace = true } fs-err = { workspace = true, features = ["tokio"] } reqwest = { workspace = true, features = ["blocking"] } reqwest-middleware = { workspace = true } -serde = { workspace = true } thiserror = { workspace = true } tokio = { workspace = true } tracing = { workspace = true } diff --git a/crates/uv-git/src/git.rs b/crates/uv-git/src/git.rs index f2953bf43..112393976 100644 --- a/crates/uv-git/src/git.rs +++ b/crates/uv-git/src/git.rs @@ -15,11 +15,10 @@ use tracing::{debug, warn}; use url::Url; use uv_fs::Simplified; +use uv_git_types::{GitHubRepository, GitOid, GitReference}; use uv_static::EnvVars; use uv_version::version; -use crate::{GitHubRepository, GitOid}; - /// A file indicates that if present, `git reset` has been done and a repo /// checkout is ready to go. See [`GitCheckout::reset`] for why we need this. const CHECKOUT_READY_LOCK: &str = ".ok"; @@ -48,79 +47,6 @@ enum RefspecStrategy { First, } -/// A reference to commit or commit-ish. -#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub enum GitReference { - /// A specific branch. - Branch(String), - /// A specific tag. - Tag(String), - /// From a reference that's ambiguously a branch or tag. - BranchOrTag(String), - /// From a reference that's ambiguously a commit, branch, or tag. - BranchOrTagOrCommit(String), - /// From a named reference, like `refs/pull/493/head`. - NamedRef(String), - /// The default branch of the repository, the reference named `HEAD`. - DefaultBranch, -} - -impl GitReference { - /// Creates a [`GitReference`] from an arbitrary revision string, which could represent a - /// branch, tag, commit, or named ref. - pub fn from_rev(rev: String) -> Self { - if rev.starts_with("refs/") { - Self::NamedRef(rev) - } else if looks_like_commit_hash(&rev) { - Self::BranchOrTagOrCommit(rev) - } else { - Self::BranchOrTag(rev) - } - } - - /// Converts the [`GitReference`] to a `str`. - pub fn as_str(&self) -> Option<&str> { - match self { - Self::Tag(rev) => Some(rev), - Self::Branch(rev) => Some(rev), - Self::BranchOrTag(rev) => Some(rev), - Self::BranchOrTagOrCommit(rev) => Some(rev), - Self::NamedRef(rev) => Some(rev), - Self::DefaultBranch => None, - } - } - - /// Converts the [`GitReference`] to a `str` that can be used as a revision. - pub fn as_rev(&self) -> &str { - match self { - Self::Tag(rev) => rev, - Self::Branch(rev) => rev, - Self::BranchOrTag(rev) => rev, - Self::BranchOrTagOrCommit(rev) => rev, - Self::NamedRef(rev) => rev, - Self::DefaultBranch => "HEAD", - } - } - - /// Returns the kind of this reference. - pub(crate) fn kind_str(&self) -> &str { - match self { - Self::Branch(_) => "branch", - Self::Tag(_) => "tag", - Self::BranchOrTag(_) => "branch or tag", - Self::BranchOrTagOrCommit(_) => "branch, tag, or commit", - Self::NamedRef(_) => "ref", - Self::DefaultBranch => "default branch", - } - } -} - -impl Display for GitReference { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.as_str().unwrap_or("HEAD")) - } -} - /// A Git reference (like a tag or branch) or a specific commit. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] enum ReferenceOrOid<'reference> { @@ -854,11 +780,6 @@ fn github_fast_path( }) } -/// Whether a `rev` looks like a commit hash (ASCII hex digits). -fn looks_like_commit_hash(rev: &str) -> bool { - rev.len() >= 7 && rev.chars().all(|ch| ch.is_ascii_hexdigit()) -} - /// Whether `rev` is a shorter hash of `oid`. fn is_short_hash_of(rev: &str, oid: GitOid) -> bool { let long_hash = oid.to_string(); diff --git a/crates/uv-git/src/lib.rs b/crates/uv-git/src/lib.rs index 9609b9116..89a9d1558 100644 --- a/crates/uv-git/src/lib.rs +++ b/crates/uv-git/src/lib.rs @@ -1,9 +1,5 @@ -use url::Url; - pub use crate::credentials::{store_credentials_from_url, GIT_STORE}; -pub use crate::git::{GitReference, GIT}; -pub use crate::github::GitHubRepository; -pub use crate::oid::{GitOid, OidParseError}; +pub use crate::git::GIT; pub use crate::resolver::{ GitResolver, GitResolverError, RepositoryReference, ResolvedRepositoryReference, }; @@ -11,124 +7,5 @@ pub use crate::source::{Fetch, GitSource, Reporter}; mod credentials; mod git; -mod github; -mod oid; mod resolver; mod source; - -/// A URL reference to a Git repository. -#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Hash, Ord)] -pub struct GitUrl { - /// The URL of the Git repository, with any query parameters, fragments, and leading `git+` - /// removed. - repository: Url, - /// The reference to the commit to use, which could be a branch, tag or revision. - reference: GitReference, - /// The precise commit to use, if known. - precise: Option, -} - -impl GitUrl { - /// Create a new [`GitUrl`] from a repository URL and a reference. - pub fn from_reference(repository: Url, reference: GitReference) -> Self { - Self { - repository, - reference, - precise: None, - } - } - - /// Create a new [`GitUrl`] from a repository URL and a precise commit. - pub fn from_commit(repository: Url, reference: GitReference, precise: GitOid) -> Self { - Self { - repository, - reference, - precise: Some(precise), - } - } - - /// Set the precise [`GitOid`] to use for this Git URL. - #[must_use] - pub fn with_precise(mut self, precise: GitOid) -> Self { - self.precise = Some(precise); - self - } - - /// Set the [`GitReference`] to use for this Git URL. - #[must_use] - pub fn with_reference(mut self, reference: GitReference) -> Self { - self.reference = reference; - self - } - - /// Return the [`Url`] of the Git repository. - pub fn repository(&self) -> &Url { - &self.repository - } - - /// Return the reference to the commit to use, which could be a branch, tag or revision. - pub fn reference(&self) -> &GitReference { - &self.reference - } - - /// Return the precise commit, if known. - pub fn precise(&self) -> Option { - self.precise - } -} - -impl TryFrom for GitUrl { - type Error = OidParseError; - - /// Initialize a [`GitUrl`] source from a URL. - fn try_from(mut url: Url) -> Result { - // Remove any query parameters and fragments. - url.set_fragment(None); - url.set_query(None); - - // If the URL ends with a reference, like `https://git.example.com/MyProject.git@v1.0`, - // extract it. - let mut reference = GitReference::DefaultBranch; - if let Some((prefix, suffix)) = url - .path() - .rsplit_once('@') - .map(|(prefix, suffix)| (prefix.to_string(), suffix.to_string())) - { - reference = GitReference::from_rev(suffix); - url.set_path(&prefix); - } - - Ok(Self::from_reference(url, reference)) - } -} - -impl From for Url { - fn from(git: GitUrl) -> Self { - let mut url = git.repository; - - // If we have a precise commit, add `@` and the commit hash to the URL. - if let Some(precise) = git.precise { - url.set_path(&format!("{}@{}", url.path(), precise)); - } else { - // Otherwise, add the branch or tag name. - match git.reference { - GitReference::Branch(rev) - | GitReference::Tag(rev) - | GitReference::BranchOrTag(rev) - | GitReference::NamedRef(rev) - | GitReference::BranchOrTagOrCommit(rev) => { - url.set_path(&format!("{}@{}", url.path(), rev)); - } - GitReference::DefaultBranch => {} - } - } - - url - } -} - -impl std::fmt::Display for GitUrl { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.repository) - } -} diff --git a/crates/uv-git/src/resolver.rs b/crates/uv-git/src/resolver.rs index 5e5be3d85..4bdf41443 100644 --- a/crates/uv-git/src/resolver.rs +++ b/crates/uv-git/src/resolver.rs @@ -3,17 +3,19 @@ use std::path::PathBuf; use std::str::FromStr; use std::sync::Arc; -use tracing::debug; - -use crate::{Fetch, GitHubRepository, GitOid, GitReference, GitSource, GitUrl, Reporter}; use dashmap::mapref::one::Ref; use dashmap::DashMap; use fs_err::tokio as fs; use reqwest_middleware::ClientWithMiddleware; +use tracing::debug; + use uv_cache_key::{cache_digest, RepositoryUrl}; use uv_fs::LockedFile; +use uv_git_types::{GitHubRepository, GitOid, GitReference, GitUrl}; use uv_version::version; +use crate::{Fetch, GitSource, Reporter}; + #[derive(Debug, thiserror::Error)] pub enum GitResolverError { #[error(transparent)] diff --git a/crates/uv-git/src/source.rs b/crates/uv-git/src/source.rs index 9cbefc60a..0a799237e 100644 --- a/crates/uv-git/src/source.rs +++ b/crates/uv-git/src/source.rs @@ -12,9 +12,10 @@ use tracing::{debug, instrument}; use url::Url; use uv_cache_key::{cache_digest, RepositoryUrl}; +use uv_git_types::{GitOid, GitUrl}; use crate::git::GitRemote; -use crate::{GitOid, GitUrl, GIT_STORE}; +use crate::GIT_STORE; /// A remote Git source that can be checked out locally. pub struct GitSource { @@ -65,10 +66,10 @@ impl GitSource { } /// Fetch the underlying Git repository at the given revision. - #[instrument(skip(self), fields(repository = %self.git.repository, rev = ?self.git.precise))] + #[instrument(skip(self), fields(repository = %self.git.repository(), rev = ?self.git.precise()))] pub fn fetch(self) -> Result { // Compute the canonical URL for the repository. - let canonical = RepositoryUrl::new(&self.git.repository); + let canonical = RepositoryUrl::new(self.git.repository()); // The path to the repo, within the Git database. let ident = cache_digest(&canonical); @@ -76,17 +77,17 @@ impl GitSource { // Authenticate the URL, if necessary. let remote = if let Some(credentials) = GIT_STORE.get(&canonical) { - Cow::Owned(credentials.apply(self.git.repository.clone())) + Cow::Owned(credentials.apply(self.git.repository().clone())) } else { - Cow::Borrowed(&self.git.repository) + Cow::Borrowed(self.git.repository()) }; let remote = GitRemote::new(&remote); - let (db, actual_rev, task) = match (self.git.precise, remote.db_at(&db_path).ok()) { + let (db, actual_rev, task) = match (self.git.precise(), remote.db_at(&db_path).ok()) { // If we have a locked revision, and we have a preexisting database // which has that revision, then no update needs to happen. (Some(rev), Some(db)) if db.contains(rev) => { - debug!("Using existing Git source `{}`", self.git.repository); + debug!("Using existing Git source `{}`", self.git.repository()); (db, rev, None) } @@ -95,17 +96,17 @@ impl GitSource { // situation that we have a locked revision but the database // doesn't have it. (locked_rev, db) => { - debug!("Updating Git source `{}`", self.git.repository); + debug!("Updating Git source `{}`", self.git.repository()); // Report the checkout operation to the reporter. let task = self.reporter.as_ref().map(|reporter| { - reporter.on_checkout_start(remote.url(), self.git.reference.as_rev()) + reporter.on_checkout_start(remote.url(), self.git.reference().as_rev()) }); let (db, actual_rev) = remote.checkout( &db_path, db, - &self.git.reference, + self.git.reference(), locked_rev.map(GitOid::from), &self.client, self.disable_ssl, diff --git a/crates/uv-installer/Cargo.toml b/crates/uv-installer/Cargo.toml index ae247c8ad..02ab10b43 100644 --- a/crates/uv-installer/Cargo.toml +++ b/crates/uv-installer/Cargo.toml @@ -23,7 +23,7 @@ uv-configuration = { workspace = true } uv-distribution = { workspace = true } uv-distribution-types = { workspace = true } uv-fs = { workspace = true } -uv-git = { workspace = true } +uv-git-types = { workspace = true } uv-install-wheel = { workspace = true, default-features = false } uv-normalize = { workspace = true } uv-pep440 = { workspace = true } diff --git a/crates/uv-installer/src/satisfies.rs b/crates/uv-installer/src/satisfies.rs index 6427e9d0d..f30b41017 100644 --- a/crates/uv-installer/src/satisfies.rs +++ b/crates/uv-installer/src/satisfies.rs @@ -7,7 +7,7 @@ use url::Url; use uv_cache_info::CacheInfo; use uv_cache_key::{CanonicalUrl, RepositoryUrl}; use uv_distribution_types::{InstalledDirectUrlDist, InstalledDist}; -use uv_git::GitOid; +use uv_git_types::GitOid; use uv_pypi_types::{DirInfo, DirectUrl, RequirementSource, VcsInfo, VcsKind}; #[derive(Debug, Copy, Clone)] diff --git a/crates/uv-pypi-types/Cargo.toml b/crates/uv-pypi-types/Cargo.toml index a3ecc4142..9c3f8336c 100644 --- a/crates/uv-pypi-types/Cargo.toml +++ b/crates/uv-pypi-types/Cargo.toml @@ -18,7 +18,7 @@ workspace = true [dependencies] uv-distribution-filename = { workspace = true } uv-fs = { workspace = true, features = ["serde"] } -uv-git = { workspace = true } +uv-git-types = { workspace = true } uv-normalize = { workspace = true } uv-pep440 = { workspace = true } uv-pep508 = { workspace = true } diff --git a/crates/uv-pypi-types/src/parsed_url.rs b/crates/uv-pypi-types/src/parsed_url.rs index b9d22ed2e..ca1d441b4 100644 --- a/crates/uv-pypi-types/src/parsed_url.rs +++ b/crates/uv-pypi-types/src/parsed_url.rs @@ -5,7 +5,7 @@ use thiserror::Error; use url::{ParseError, Url}; use uv_distribution_filename::{DistExtension, ExtensionError}; -use uv_git::{GitOid, GitReference, GitUrl, OidParseError}; +use uv_git_types::{GitOid, GitReference, GitUrl, OidParseError}; use uv_pep508::{ looks_like_git_repository, Pep508Url, UnnamedRequirementUrl, VerbatimUrl, VerbatimUrlError, }; diff --git a/crates/uv-pypi-types/src/requirement.rs b/crates/uv-pypi-types/src/requirement.rs index 3a9dee6c8..778f42c33 100644 --- a/crates/uv-pypi-types/src/requirement.rs +++ b/crates/uv-pypi-types/src/requirement.rs @@ -8,7 +8,7 @@ use url::Url; use uv_distribution_filename::DistExtension; use uv_fs::{relative_to, PortablePath, PortablePathBuf, CWD}; -use uv_git::{GitOid, GitReference, GitUrl}; +use uv_git_types::{GitOid, GitReference, GitUrl, OidParseError}; use uv_normalize::{ExtraName, GroupName, PackageName}; use uv_pep440::VersionSpecifiers; use uv_pep508::{ @@ -29,7 +29,7 @@ pub enum RequirementError { #[error(transparent)] UrlParseError(#[from] url::ParseError), #[error(transparent)] - OidParseError(#[from] uv_git::OidParseError), + OidParseError(#[from] OidParseError), } /// A representation of dependency on a package, an extension over a PEP 508's requirement. diff --git a/crates/uv-requirements/Cargo.toml b/crates/uv-requirements/Cargo.toml index d3fbf929b..ea71c6ce8 100644 --- a/crates/uv-requirements/Cargo.toml +++ b/crates/uv-requirements/Cargo.toml @@ -25,6 +25,7 @@ uv-distribution-filename = { workspace = true } uv-distribution-types = { workspace = true } uv-fs = { workspace = true } uv-git = { workspace = true } +uv-git-types = { workspace = true } uv-normalize = { workspace = true } uv-pep508 = { workspace = true } uv-pypi-types = { workspace = true } diff --git a/crates/uv-requirements/src/lib.rs b/crates/uv-requirements/src/lib.rs index a6bff1998..ad9f9ed39 100644 --- a/crates/uv-requirements/src/lib.rs +++ b/crates/uv-requirements/src/lib.rs @@ -6,7 +6,7 @@ pub use crate::specification::*; pub use crate::unnamed::*; use uv_distribution_types::{Dist, DistErrorKind, GitSourceDist, SourceDist}; -use uv_git::GitUrl; +use uv_git_types::GitUrl; use uv_pypi_types::{Requirement, RequirementSource}; mod extras; diff --git a/crates/uv-resolver/Cargo.toml b/crates/uv-resolver/Cargo.toml index 1bf906679..48c82b495 100644 --- a/crates/uv-resolver/Cargo.toml +++ b/crates/uv-resolver/Cargo.toml @@ -24,6 +24,7 @@ uv-distribution-filename = { workspace = true } uv-distribution-types = { workspace = true } uv-fs = { workspace = true, features = ["serde"] } uv-git = { workspace = true } +uv-git-types = { workspace = true } uv-metadata = { workspace = true } uv-normalize = { workspace = true } uv-once-map = { workspace = true } diff --git a/crates/uv-resolver/src/lock/mod.rs b/crates/uv-resolver/src/lock/mod.rs index 1bdbfc8fd..bb692f46d 100644 --- a/crates/uv-resolver/src/lock/mod.rs +++ b/crates/uv-resolver/src/lock/mod.rs @@ -31,7 +31,8 @@ use uv_distribution_types::{ RemoteSource, ResolvedDist, StaticMetadata, ToUrlError, UrlString, }; use uv_fs::{relative_to, PortablePath, PortablePathBuf}; -use uv_git::{GitOid, GitReference, RepositoryReference, ResolvedRepositoryReference}; +use uv_git::{RepositoryReference, ResolvedRepositoryReference}; +use uv_git_types::{GitOid, GitReference}; use uv_normalize::{ExtraName, GroupName, PackageName}; use uv_pep440::Version; use uv_pep508::{split_scheme, MarkerEnvironment, MarkerTree, VerbatimUrl, VerbatimUrlError}; @@ -2268,7 +2269,7 @@ impl Package { url.set_query(None); // Reconstruct the `GitUrl` from the `GitSource`. - let git_url = uv_git::GitUrl::from_commit( + let git_url = uv_git_types::GitUrl::from_commit( url, GitReference::from(git.kind.clone()), git.precise, @@ -4345,7 +4346,7 @@ fn normalize_requirement( // Reconstruct the PEP 508 URL from the underlying data. let url = Url::from(ParsedGitUrl { - url: uv_git::GitUrl::from_reference(repository.clone(), reference.clone()), + url: uv_git_types::GitUrl::from_reference(repository.clone(), reference.clone()), subdirectory: subdirectory.clone(), }); diff --git a/crates/uv-resolver/src/lock/requirements_txt.rs b/crates/uv-resolver/src/lock/requirements_txt.rs index 412143a97..1462c6a3e 100644 --- a/crates/uv-resolver/src/lock/requirements_txt.rs +++ b/crates/uv-resolver/src/lock/requirements_txt.rs @@ -13,7 +13,7 @@ use url::Url; use uv_configuration::{DevGroupsManifest, EditableMode, ExtrasSpecification, InstallOptions}; use uv_distribution_filename::{DistExtension, SourceDistExtension}; use uv_fs::Simplified; -use uv_git::GitReference; +use uv_git_types::GitReference; use uv_normalize::{ExtraName, PackageName}; use uv_pep508::MarkerTree; use uv_pypi_types::{ParsedArchiveUrl, ParsedGitUrl}; @@ -313,7 +313,7 @@ impl std::fmt::Display for RequirementsTxtExport<'_> { url.set_query(None); // Reconstruct the `GitUrl` from the `GitSource`. - let git_url = uv_git::GitUrl::from_commit( + let git_url = uv_git_types::GitUrl::from_commit( url, GitReference::from(git.kind.clone()), git.precise, diff --git a/crates/uv-workspace/Cargo.toml b/crates/uv-workspace/Cargo.toml index e63033bba..947c76b63 100644 --- a/crates/uv-workspace/Cargo.toml +++ b/crates/uv-workspace/Cargo.toml @@ -19,7 +19,7 @@ workspace = true uv-cache-key = { workspace = true } uv-distribution-types = { workspace = true } uv-fs = { workspace = true, features = ["tokio", "schemars"] } -uv-git = { workspace = true } +uv-git-types = { workspace = true } uv-macros = { workspace = true } uv-normalize = { workspace = true } uv-options-metadata = { workspace = true } diff --git a/crates/uv-workspace/src/pyproject.rs b/crates/uv-workspace/src/pyproject.rs index abe35dfbe..772f86248 100644 --- a/crates/uv-workspace/src/pyproject.rs +++ b/crates/uv-workspace/src/pyproject.rs @@ -19,7 +19,7 @@ use url::Url; use uv_distribution_types::{Index, IndexName}; use uv_fs::{relative_to, PortablePathBuf}; -use uv_git::GitReference; +use uv_git_types::GitReference; use uv_macros::OptionsMetadata; use uv_normalize::{ExtraName, GroupName, PackageName}; use uv_pep440::{Version, VersionSpecifiers}; diff --git a/crates/uv/Cargo.toml b/crates/uv/Cargo.toml index 1705ed34b..369d7bb3c 100644 --- a/crates/uv/Cargo.toml +++ b/crates/uv/Cargo.toml @@ -31,6 +31,7 @@ uv-distribution-types = { workspace = true } uv-extract = { workspace = true } uv-fs = { workspace = true } uv-git = { workspace = true } +uv-git-types = { workspace = true } uv-install-wheel = { workspace = true, default-features = false } uv-installer = { workspace = true } uv-normalize = { workspace = true } diff --git a/crates/uv/src/commands/project/add.rs b/crates/uv/src/commands/project/add.rs index 72d6c8c8f..ec608a22b 100644 --- a/crates/uv/src/commands/project/add.rs +++ b/crates/uv/src/commands/project/add.rs @@ -23,7 +23,8 @@ use uv_dispatch::BuildDispatch; use uv_distribution::DistributionDatabase; use uv_distribution_types::{Index, IndexName, IndexUrls, UnresolvedRequirement, VersionId}; use uv_fs::Simplified; -use uv_git::{GitReference, GIT_STORE}; +use uv_git::GIT_STORE; +use uv_git_types::GitReference; use uv_normalize::{PackageName, DEV_DEPENDENCIES}; use uv_pep508::{ExtraName, Requirement, UnnamedRequirement, VersionOrUrl}; use uv_pypi_types::{redact_credentials, ParsedUrl, RequirementSource, VerbatimParsedUrl};