Make `augment_requirement` a method (#16592)

Fixing the pattern so we can be consistent in
https://github.com/astral-sh/uv/pull/16143#discussion_r2479028440
This commit is contained in:
konsti 2025-11-04 19:53:59 +01:00 committed by GitHub
parent 3068fa89e8
commit 148b694b6b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 79 additions and 84 deletions

View File

@ -1,9 +1,10 @@
use std::borrow::Cow;
use std::fmt::{Display, Formatter};
use uv_git_types::GitReference;
use uv_normalize::ExtraName;
use uv_pep508::{MarkerEnvironment, UnnamedRequirement};
use uv_pypi_types::Hashes;
use uv_pep508::{MarkerEnvironment, MarkerTree, UnnamedRequirement};
use uv_pypi_types::{Hashes, ParsedUrl};
use crate::{Requirement, RequirementSource, VerbatimParsedUrl};
@ -66,6 +67,80 @@ impl UnresolvedRequirement {
}
}
/// Augment a user-provided requirement by attaching any specification data that was provided
/// separately from the requirement itself (e.g., `--branch main`).
#[must_use]
pub fn augment_requirement(
self,
rev: Option<&str>,
tag: Option<&str>,
branch: Option<&str>,
marker: Option<MarkerTree>,
) -> Self {
#[allow(clippy::manual_map)]
let git_reference = if let Some(rev) = rev {
Some(GitReference::from_rev(rev.to_string()))
} else if let Some(tag) = tag {
Some(GitReference::Tag(tag.to_string()))
} else if let Some(branch) = branch {
Some(GitReference::Branch(branch.to_string()))
} else {
None
};
match self {
Self::Named(mut requirement) => Self::Named(Requirement {
marker: marker
.map(|marker| {
requirement.marker.and(marker);
requirement.marker
})
.unwrap_or(requirement.marker),
source: match requirement.source {
RequirementSource::Git {
git,
subdirectory,
url,
} => {
let git = if let Some(git_reference) = git_reference {
git.with_reference(git_reference)
} else {
git
};
RequirementSource::Git {
git,
subdirectory,
url,
}
}
_ => requirement.source,
},
..requirement
}),
Self::Unnamed(mut requirement) => Self::Unnamed(UnnamedRequirement {
marker: marker
.map(|marker| {
requirement.marker.and(marker);
requirement.marker
})
.unwrap_or(requirement.marker),
url: match requirement.url.parsed_url {
ParsedUrl::Git(mut git) => {
if let Some(git_reference) = git_reference {
git.url = git.url.with_reference(git_reference);
}
VerbatimParsedUrl {
parsed_url: ParsedUrl::Git(git),
verbatim: requirement.url.verbatim,
}
}
_ => requirement.url,
},
..requirement
}),
}
}
/// Returns the extras for the requirement.
pub fn extras(&self) -> &[ExtraName] {
match self {

View File

@ -28,11 +28,9 @@ use uv_distribution_types::{
};
use uv_fs::{LockedFile, Simplified};
use uv_git::GIT_STORE;
use uv_git_types::GitReference;
use uv_normalize::{DEV_DEPENDENCIES, DefaultExtras, DefaultGroups, ExtraName, PackageName};
use uv_pep508::{MarkerTree, UnnamedRequirement, VersionOrUrl};
use uv_pep508::{MarkerTree, VersionOrUrl};
use uv_preview::{Preview, PreviewFeatures};
use uv_pypi_types::{ParsedUrl, VerbatimParsedUrl};
use uv_python::{Interpreter, PythonDownloads, PythonEnvironment, PythonPreference, PythonRequest};
use uv_redacted::DisplaySafeUrl;
use uv_requirements::{NamedRequirementsResolver, RequirementsSource, RequirementsSpecification};
@ -369,8 +367,7 @@ pub(crate) async fn add(
let (mut requirements, unnamed): (Vec<_>, Vec<_>) = requirements
.into_iter()
.map(|spec| {
augment_requirement(
spec.requirement,
spec.requirement.augment_requirement(
rev.as_deref(),
tag.as_deref(),
branch.as_deref(),
@ -1191,83 +1188,6 @@ async fn lock_and_sync(
Ok(())
}
/// Augment a user-provided requirement by attaching any specification data that was provided
/// separately from the requirement itself (e.g., `--branch main`).
fn augment_requirement(
requirement: UnresolvedRequirement,
rev: Option<&str>,
tag: Option<&str>,
branch: Option<&str>,
marker: Option<MarkerTree>,
) -> UnresolvedRequirement {
match requirement {
UnresolvedRequirement::Named(mut requirement) => {
UnresolvedRequirement::Named(Requirement {
marker: marker
.map(|marker| {
requirement.marker.and(marker);
requirement.marker
})
.unwrap_or(requirement.marker),
source: match requirement.source {
RequirementSource::Git {
git,
subdirectory,
url,
} => {
let git = if let Some(rev) = rev {
git.with_reference(GitReference::from_rev(rev.to_string()))
} else if let Some(tag) = tag {
git.with_reference(GitReference::Tag(tag.to_string()))
} else if let Some(branch) = branch {
git.with_reference(GitReference::Branch(branch.to_string()))
} else {
git
};
RequirementSource::Git {
git,
subdirectory,
url,
}
}
_ => requirement.source,
},
..requirement
})
}
UnresolvedRequirement::Unnamed(mut requirement) => {
UnresolvedRequirement::Unnamed(UnnamedRequirement {
marker: marker
.map(|marker| {
requirement.marker.and(marker);
requirement.marker
})
.unwrap_or(requirement.marker),
url: match requirement.url.parsed_url {
ParsedUrl::Git(mut git) => {
let reference = if let Some(rev) = rev {
Some(GitReference::from_rev(rev.to_string()))
} else if let Some(tag) = tag {
Some(GitReference::Tag(tag.to_string()))
} else {
branch.map(|branch| GitReference::Branch(branch.to_string()))
};
if let Some(reference) = reference {
git.url = git.url.with_reference(reference);
}
VerbatimParsedUrl {
parsed_url: ParsedUrl::Git(git),
verbatim: requirement.url.verbatim,
}
}
_ => requirement.url,
},
..requirement
})
}
}
}
/// Resolves the source for a requirement and processes it into a PEP 508 compliant format.
fn resolve_requirement(
requirement: Requirement,