Preserve parsed url in ResolvedDist -> Requirement (#3457)

Lose less information in the `ResolvedDist` -> `Requirement` conversion.
This commit is contained in:
konsti 2024-05-14 03:47:20 +02:00 committed by GitHub
parent a24124571a
commit b263fcff9c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 61 additions and 29 deletions

View file

@ -6,7 +6,7 @@ use url::Url;
use pep440_rs::VersionSpecifiers;
use pep508_rs::{MarkerEnvironment, MarkerTree, RequirementOrigin, VerbatimUrl, VersionOrUrl};
use uv_git::GitReference;
use uv_git::{GitReference, GitSha};
use uv_normalize::{ExtraName, PackageName};
use crate::{ParsedUrl, ParsedUrlError};
@ -102,6 +102,7 @@ impl Display for Requirement {
url: _,
repository,
reference,
precise: _,
subdirectory,
} => {
write!(f, " @ git+{repository}")?;
@ -158,6 +159,8 @@ pub enum RequirementSource {
repository: Url,
/// Optionally, the revision, tag, or branch to use.
reference: GitReference,
/// The precise commit to use, if known.
precise: Option<GitSha>,
/// The path to the source distribution if it is not in the repository root.
subdirectory: Option<PathBuf>,
/// The PEP 508 style url in the format
@ -192,6 +195,7 @@ impl RequirementSource {
url,
repository: git.url.repository().clone(),
reference: git.url.reference().clone(),
precise: git.url.precise(),
subdirectory: git.subdirectory,
},
ParsedUrl::Archive(archive) => RequirementSource::Url {

View file

@ -2,9 +2,7 @@ use rustc_hash::FxHashMap;
use uv_normalize::PackageName;
use crate::{
BuiltDist, Dist, Name, ParsedGitUrl, Requirement, RequirementSource, ResolvedDist, SourceDist,
};
use crate::{BuiltDist, Dist, Name, Requirement, RequirementSource, ResolvedDist, SourceDist};
/// A set of packages pinned at specific versions.
#[derive(Debug, Default, Clone)]
@ -88,7 +86,7 @@ impl From<&ResolvedDist> for Requirement {
RequirementSource::Url {
url: wheel.url.clone(),
location,
subdirectory: None,
subdirectory: wheel.subdirectory.clone(),
}
}
Dist::Built(BuiltDist::Path(wheel)) => RequirementSource::Path {
@ -108,19 +106,16 @@ impl From<&ResolvedDist> for Requirement {
RequirementSource::Url {
url: sdist.url.clone(),
location,
subdirectory: None,
}
}
Dist::Source(SourceDist::Git(sdist)) => {
let git_url = ParsedGitUrl::try_from(sdist.url.to_url())
.expect("urls must be valid at this point");
RequirementSource::Git {
url: sdist.url.clone(),
repository: git_url.url.repository().clone(),
reference: git_url.url.reference().clone(),
subdirectory: git_url.subdirectory,
subdirectory: sdist.subdirectory.clone(),
}
}
Dist::Source(SourceDist::Git(sdist)) => RequirementSource::Git {
url: sdist.url.clone(),
repository: sdist.git.repository().clone(),
reference: sdist.git.reference().clone(),
precise: sdist.git.precise(),
subdirectory: sdist.subdirectory.clone(),
},
Dist::Source(SourceDist::Path(sdist)) => RequirementSource::Path {
path: sdist.path.clone(),
url: sdist.url.clone(),
@ -129,7 +124,7 @@ impl From<&ResolvedDist> for Requirement {
Dist::Source(SourceDist::Directory(sdist)) => RequirementSource::Path {
path: sdist.path.clone(),
url: sdist.url.clone(),
editable: None,
editable: Some(sdist.editable),
},
},
ResolvedDist::Installed(dist) => RequirementSource::Registry {

View file

@ -312,12 +312,17 @@ impl<'a> Planner<'a> {
RequirementSource::Git {
repository,
reference,
precise,
subdirectory,
url,
} => {
let mut git = GitUrl::new(repository.clone(), reference.clone());
if let Some(precise) = precise {
git = git.with_precise(*precise);
}
let sdist = GitSourceDist {
name: requirement.name.clone(),
git: Box::new(GitUrl::new(repository.clone(), reference.clone())),
git: Box::new(git),
subdirectory: subdirectory.clone(),
url: url.clone(),
};

View file

@ -92,6 +92,7 @@ impl RequirementSatisfaction {
url: _,
repository: requested_repository,
reference: requested_reference,
precise: requested_precise,
subdirectory: requested_subdirectory,
} => {
let InstalledDist::Url(InstalledDirectUrlDist { direct_url, .. }) = &distribution
@ -130,10 +131,12 @@ impl RequirementSatisfaction {
return Ok(Self::Mismatch);
}
if installed_reference.as_deref() != requested_reference.as_str() {
if installed_reference.as_deref() != requested_reference.as_str()
&& installed_reference != &requested_precise.map(|git_sha| git_sha.to_string())
{
debug!(
"Reference mismatch: {:?} vs. {:?}",
installed_reference, requested_reference
"Reference mismatch: {:?} vs. {:?} and {:?}",
installed_reference, requested_reference, requested_precise
);
return Ok(Self::OutOfDate);
}
@ -160,17 +163,29 @@ impl RequirementSatisfaction {
return Ok(Self::Mismatch);
};
if requested_editable != installed_editable {
if requested_editable.unwrap_or_default() != installed_editable.unwrap_or_default()
{
trace!(
"Editable mismatch: {:?} vs. {:?}",
requested_editable.unwrap_or_default(),
installed_editable.unwrap_or_default()
);
return Ok(Self::Mismatch);
}
if !CanonicalUrl::parse(installed_url)
.is_ok_and(|installed_url| installed_url == CanonicalUrl::new(requested_url))
{
trace!(
"URL mismatch: {:?} vs. {:?}",
CanonicalUrl::parse(installed_url),
CanonicalUrl::new(requested_url)
);
return Ok(Self::Mismatch);
}
if !ArchiveTimestamp::up_to_date_with(path, ArchiveTarget::Install(distribution))? {
trace!("Out of date");
return Ok(Self::OutOfDate);
}

View file

@ -171,14 +171,21 @@ impl<'a, Context: BuildContext> LookaheadResolver<'a, Context> {
RequirementSource::Git {
repository,
reference,
precise,
subdirectory,
url,
} => Dist::Source(SourceDist::Git(GitSourceDist {
name: requirement.name,
git: Box::new(GitUrl::new(repository, reference)),
subdirectory,
url,
})),
} => {
let mut git_url = GitUrl::new(repository, reference);
if let Some(precise) = precise {
git_url = git_url.with_precise(precise);
}
Dist::Source(SourceDist::Git(GitSourceDist {
name: requirement.name,
git: Box::new(git_url),
subdirectory,
url,
}))
}
RequirementSource::Path {
path,
url,

View file

@ -468,6 +468,7 @@ pub(crate) fn lower_requirement(
url,
repository,
reference,
precise: None,
subdirectory: subdirectory.map(PathBuf::from),
}
}

View file

@ -104,12 +104,17 @@ impl Urls {
RequirementSource::Git {
repository,
reference,
precise,
subdirectory,
url,
} => {
let mut git_url = GitUrl::new(repository.clone(), reference.clone());
if let Some(precise) = precise {
git_url = git_url.with_precise(*precise);
}
let url = VerbatimParsedUrl {
parsed_url: ParsedUrl::Git(ParsedGitUrl {
url: GitUrl::new(repository.clone(), reference.clone()),
url: git_url,
subdirectory: subdirectory.clone(),
}),
verbatim: url.clone(),