diff --git a/crates/distribution-types/src/annotation.rs b/crates/distribution-types/src/annotation.rs index 54b107979..026135af4 100644 --- a/crates/distribution-types/src/annotation.rs +++ b/crates/distribution-types/src/annotation.rs @@ -1,9 +1,14 @@ -use serde::{Deserialize, Deserializer, Serialize}; +use std::collections::{BTreeMap, BTreeSet}; use std::path::PathBuf; + +use url::Url; + +use pep508_rs::VerbatimUrl; use uv_fs::Simplified; +use uv_normalize::PackageName; /// Source of a dependency, e.g., a `-r requirements.txt` file. -#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub enum SourceAnnotation { /// A `pyproject.toml` file. PyProject { @@ -18,16 +23,6 @@ pub enum SourceAnnotation { Requirement(PathBuf), } -impl<'de> Deserialize<'de> for SourceAnnotation { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let s = String::deserialize(deserializer)?; - Ok(SourceAnnotation::Requirement(PathBuf::from(s))) - } -} - impl std::fmt::Display for SourceAnnotation { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { @@ -50,3 +45,38 @@ impl std::fmt::Display for SourceAnnotation { } } } + +/// A collection of source annotations. +#[derive(Default, Debug, Clone)] +pub struct SourceAnnotations { + packages: BTreeMap>, + editables: BTreeMap>, +} + +impl SourceAnnotations { + /// Add a source annotation to the collection for the given package. + pub fn add(&mut self, package: &PackageName, annotation: SourceAnnotation) { + self.packages + .entry(package.clone()) + .or_default() + .insert(annotation); + } + + /// Add an source annotation to the collection for the given editable. + pub fn add_editable(&mut self, url: &VerbatimUrl, annotation: SourceAnnotation) { + self.editables + .entry(url.to_url()) + .or_default() + .insert(annotation); + } + + /// Return the source annotations for a given package. + pub fn get(&self, package: &PackageName) -> Option<&BTreeSet> { + self.packages.get(package) + } + + /// Return the source annotations for a given editable. + pub fn get_editable(&self, url: &VerbatimUrl) -> Option<&BTreeSet> { + self.editables.get(url.raw()) + } +} diff --git a/crates/distribution-types/src/requirement.rs b/crates/distribution-types/src/requirement.rs index 95f78d665..47d3b6ac6 100644 --- a/crates/distribution-types/src/requirement.rs +++ b/crates/distribution-types/src/requirement.rs @@ -63,7 +63,7 @@ impl Requirement { extras: requirement.extras, marker: requirement.marker, source, - path: requirement.path, + path: requirement.source, }) } } diff --git a/crates/pep508-rs/src/lib.rs b/crates/pep508-rs/src/lib.rs index b181baad2..d4b2e367d 100644 --- a/crates/pep508-rs/src/lib.rs +++ b/crates/pep508-rs/src/lib.rs @@ -149,14 +149,14 @@ pub struct Requirement { /// Those are a nested and/or tree. pub marker: Option, /// The source file containing the requirement. - pub path: Option, + pub source: Option, } impl Requirement { /// Set the source file containing the requirement. #[must_use] - pub fn with_source(self, path: Option) -> Self { - Self { path, ..self } + pub fn with_source(self, source: Option) -> Self { + Self { source, ..self } } } @@ -492,7 +492,7 @@ impl Requirement { extras, version_or_url, marker, - path, + source, } = self; Requirement { name, @@ -505,7 +505,7 @@ impl Requirement { Some(VersionOrUrl::Url(url)) => Some(VersionOrUrl::Url(U::from(url))), }, marker, - path, + source, } } } @@ -1029,7 +1029,7 @@ fn parse_pep508_requirement( extras, version_or_url: requirement_kind, marker, - path: None, + source: None, }) } @@ -1171,7 +1171,7 @@ mod tests { operator: MarkerOperator::LessThan, r_value: MarkerValue::QuotedString("2.7".to_string()), })), - path: None, + source: None, }; assert_eq!(requests, expected); } @@ -1397,7 +1397,7 @@ mod tests { extras: vec![], marker: None, version_or_url: Some(VersionOrUrl::Url(Url::parse(url).unwrap())), - path: None, + source: None, }; assert_eq!(pip_url, expected); } diff --git a/crates/pep508-rs/src/unnamed.rs b/crates/pep508-rs/src/unnamed.rs index aa7d9c5fe..36dcd26c5 100644 --- a/crates/pep508-rs/src/unnamed.rs +++ b/crates/pep508-rs/src/unnamed.rs @@ -31,7 +31,7 @@ pub struct UnnamedRequirement { /// Those are a nested and/or tree. pub marker: Option, /// The source file containing the requirement. - pub path: Option, + pub source: Option, } impl UnnamedRequirement { @@ -46,8 +46,8 @@ impl UnnamedRequirement { /// Set the source file containing the requirement. #[must_use] - pub fn with_source(self, path: Option) -> Self { - Self { path, ..self } + pub fn with_source(self, source: Option) -> Self { + Self { source, ..self } } } @@ -167,7 +167,7 @@ fn parse_unnamed_requirement( url, extras, marker, - path: None, + source: None, }) } diff --git a/crates/requirements-txt/src/lib.rs b/crates/requirements-txt/src/lib.rs index 14612de61..b44ad2e26 100644 --- a/crates/requirements-txt/src/lib.rs +++ b/crates/requirements-txt/src/lib.rs @@ -164,11 +164,13 @@ impl FindLink { #[derive(Debug, Clone, Eq, PartialEq)] pub struct EditableRequirement { + /// The underlying [`VerbatimUrl`] from the `requirements.txt` file or similar. pub url: VerbatimUrl, + /// The extras that should be included when resolving the editable requirements. pub extras: Vec, + /// The local path to the editable. pub path: PathBuf, - - /// Path of the original file (where existing) + /// The source file containing the requirement. pub source: Option, } @@ -1813,7 +1815,7 @@ mod test { extras: [], version_or_url: None, marker: None, - path: Some( + source: Some( "/subdir/sibling.txt", ), }, @@ -1878,7 +1880,7 @@ mod test { extras: [], version_or_url: None, marker: None, - path: Some( + source: Some( "/requirements.txt", ), }, @@ -2075,7 +2077,7 @@ mod test { extras: [], version_or_url: None, marker: None, - path: Some( + source: Some( "/./sibling.txt", ), }, @@ -2105,7 +2107,7 @@ mod test { ), ), marker: None, - path: Some( + source: Some( "/requirements.txt", ), }, @@ -2137,7 +2139,7 @@ mod test { ), ), marker: None, - path: Some( + source: Some( "/requirements.txt", ), }, @@ -2169,7 +2171,7 @@ mod test { ), ), marker: None, - path: Some( + source: Some( "/requirements.txt", ), }, @@ -2199,7 +2201,7 @@ mod test { ), ), marker: None, - path: Some( + source: Some( "/requirements.txt", ), }, diff --git a/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-basic.txt.snap b/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-basic.txt.snap index eabfd6187..aa9549525 100644 --- a/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-basic.txt.snap +++ b/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-basic.txt.snap @@ -24,7 +24,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/basic.txt", ), }, @@ -54,7 +54,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/basic.txt", ), }, @@ -84,7 +84,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/basic.txt", ), }, @@ -114,7 +114,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/basic.txt", ), }, @@ -144,7 +144,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/basic.txt", ), }, @@ -174,7 +174,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/basic.txt", ), }, diff --git a/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-constraints-a.txt.snap b/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-constraints-a.txt.snap index f01b19f11..bef1a11b8 100644 --- a/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-constraints-a.txt.snap +++ b/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-constraints-a.txt.snap @@ -24,7 +24,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/constraints-a.txt", ), }, @@ -54,7 +54,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/constraints-b.txt", ), }, @@ -76,7 +76,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/constraints-b.txt", ), }, diff --git a/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-constraints-b.txt.snap b/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-constraints-b.txt.snap index a30f9f50a..8cb30a4bf 100644 --- a/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-constraints-b.txt.snap +++ b/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-constraints-b.txt.snap @@ -24,7 +24,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/constraints-b.txt", ), }, @@ -54,7 +54,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/constraints-b.txt", ), }, diff --git a/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-editable.txt.snap b/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-editable.txt.snap index 46fca22fb..d19aafc7e 100644 --- a/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-editable.txt.snap +++ b/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-editable.txt.snap @@ -13,7 +13,7 @@ RequirementsTxt { extras: [], version_or_url: None, marker: None, - path: Some( + source: Some( "/editable.txt", ), }, @@ -59,7 +59,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/editable.txt", ), }, diff --git a/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-for-poetry.txt.snap b/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-for-poetry.txt.snap index 26bad24f6..eba1e0a78 100644 --- a/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-for-poetry.txt.snap +++ b/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-for-poetry.txt.snap @@ -24,7 +24,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/for-poetry.txt", ), }, @@ -54,7 +54,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/for-poetry.txt", ), }, @@ -73,7 +73,7 @@ RequirementsTxt { extras: [], version_or_url: None, marker: None, - path: Some( + source: Some( "/for-poetry.txt", ), }, @@ -111,7 +111,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/for-poetry.txt", ), }, diff --git a/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-include-a.txt.snap b/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-include-a.txt.snap index 0d6f8c146..5b1e68b12 100644 --- a/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-include-a.txt.snap +++ b/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-include-a.txt.snap @@ -13,7 +13,7 @@ RequirementsTxt { extras: [], version_or_url: None, marker: None, - path: Some( + source: Some( "/include-b.txt", ), }, @@ -43,7 +43,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/include-a.txt", ), }, diff --git a/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-include-b.txt.snap b/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-include-b.txt.snap index f60a2d6fb..8e8e003e6 100644 --- a/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-include-b.txt.snap +++ b/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-include-b.txt.snap @@ -13,7 +13,7 @@ RequirementsTxt { extras: [], version_or_url: None, marker: None, - path: Some( + source: Some( "/include-b.txt", ), }, diff --git a/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-poetry-with-hashes.txt.snap b/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-poetry-with-hashes.txt.snap index 096758411..4a684c8b7 100644 --- a/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-poetry-with-hashes.txt.snap +++ b/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-poetry-with-hashes.txt.snap @@ -51,7 +51,7 @@ RequirementsTxt { ], ), ), - path: Some( + source: Some( "/poetry-with-hashes.txt", ), }, @@ -110,7 +110,7 @@ RequirementsTxt { ], ), ), - path: Some( + source: Some( "/poetry-with-hashes.txt", ), }, @@ -180,7 +180,7 @@ RequirementsTxt { ], ), ), - path: Some( + source: Some( "/poetry-with-hashes.txt", ), }, @@ -239,7 +239,7 @@ RequirementsTxt { ], ), ), - path: Some( + source: Some( "/poetry-with-hashes.txt", ), }, @@ -299,7 +299,7 @@ RequirementsTxt { ], ), ), - path: Some( + source: Some( "/poetry-with-hashes.txt", ), }, diff --git a/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-small.txt.snap b/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-small.txt.snap index 089ccb3de..eadd880b8 100644 --- a/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-small.txt.snap +++ b/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-small.txt.snap @@ -24,7 +24,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/small.txt", ), }, @@ -54,7 +54,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/small.txt", ), }, diff --git a/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-whitespace.txt.snap b/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-whitespace.txt.snap index 0ba8a9c41..8d5fce028 100644 --- a/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-whitespace.txt.snap +++ b/crates/requirements-txt/src/snapshots/requirements_txt__test__line-endings-whitespace.txt.snap @@ -13,7 +13,7 @@ RequirementsTxt { extras: [], version_or_url: None, marker: None, - path: Some( + source: Some( "/whitespace.txt", ), }, @@ -59,7 +59,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/whitespace.txt", ), }, diff --git a/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-basic.txt.snap b/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-basic.txt.snap index eabfd6187..aa9549525 100644 --- a/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-basic.txt.snap +++ b/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-basic.txt.snap @@ -24,7 +24,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/basic.txt", ), }, @@ -54,7 +54,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/basic.txt", ), }, @@ -84,7 +84,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/basic.txt", ), }, @@ -114,7 +114,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/basic.txt", ), }, @@ -144,7 +144,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/basic.txt", ), }, @@ -174,7 +174,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/basic.txt", ), }, diff --git a/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-constraints-a.txt.snap b/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-constraints-a.txt.snap index f01b19f11..bef1a11b8 100644 --- a/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-constraints-a.txt.snap +++ b/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-constraints-a.txt.snap @@ -24,7 +24,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/constraints-a.txt", ), }, @@ -54,7 +54,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/constraints-b.txt", ), }, @@ -76,7 +76,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/constraints-b.txt", ), }, diff --git a/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-constraints-b.txt.snap b/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-constraints-b.txt.snap index a30f9f50a..8cb30a4bf 100644 --- a/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-constraints-b.txt.snap +++ b/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-constraints-b.txt.snap @@ -24,7 +24,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/constraints-b.txt", ), }, @@ -54,7 +54,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/constraints-b.txt", ), }, diff --git a/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-for-poetry.txt.snap b/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-for-poetry.txt.snap index 26bad24f6..eba1e0a78 100644 --- a/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-for-poetry.txt.snap +++ b/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-for-poetry.txt.snap @@ -24,7 +24,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/for-poetry.txt", ), }, @@ -54,7 +54,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/for-poetry.txt", ), }, @@ -73,7 +73,7 @@ RequirementsTxt { extras: [], version_or_url: None, marker: None, - path: Some( + source: Some( "/for-poetry.txt", ), }, @@ -111,7 +111,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/for-poetry.txt", ), }, diff --git a/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-include-a.txt.snap b/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-include-a.txt.snap index 0d6f8c146..5b1e68b12 100644 --- a/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-include-a.txt.snap +++ b/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-include-a.txt.snap @@ -13,7 +13,7 @@ RequirementsTxt { extras: [], version_or_url: None, marker: None, - path: Some( + source: Some( "/include-b.txt", ), }, @@ -43,7 +43,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/include-a.txt", ), }, diff --git a/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-include-b.txt.snap b/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-include-b.txt.snap index f60a2d6fb..8e8e003e6 100644 --- a/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-include-b.txt.snap +++ b/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-include-b.txt.snap @@ -13,7 +13,7 @@ RequirementsTxt { extras: [], version_or_url: None, marker: None, - path: Some( + source: Some( "/include-b.txt", ), }, diff --git a/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-poetry-with-hashes.txt.snap b/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-poetry-with-hashes.txt.snap index 096758411..4a684c8b7 100644 --- a/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-poetry-with-hashes.txt.snap +++ b/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-poetry-with-hashes.txt.snap @@ -51,7 +51,7 @@ RequirementsTxt { ], ), ), - path: Some( + source: Some( "/poetry-with-hashes.txt", ), }, @@ -110,7 +110,7 @@ RequirementsTxt { ], ), ), - path: Some( + source: Some( "/poetry-with-hashes.txt", ), }, @@ -180,7 +180,7 @@ RequirementsTxt { ], ), ), - path: Some( + source: Some( "/poetry-with-hashes.txt", ), }, @@ -239,7 +239,7 @@ RequirementsTxt { ], ), ), - path: Some( + source: Some( "/poetry-with-hashes.txt", ), }, @@ -299,7 +299,7 @@ RequirementsTxt { ], ), ), - path: Some( + source: Some( "/poetry-with-hashes.txt", ), }, diff --git a/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-small.txt.snap b/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-small.txt.snap index 089ccb3de..eadd880b8 100644 --- a/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-small.txt.snap +++ b/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-small.txt.snap @@ -24,7 +24,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/small.txt", ), }, @@ -54,7 +54,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/small.txt", ), }, diff --git a/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-unix-bare-url.txt.snap b/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-unix-bare-url.txt.snap index 6a848daf2..ef554ceef 100644 --- a/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-unix-bare-url.txt.snap +++ b/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-unix-bare-url.txt.snap @@ -25,7 +25,7 @@ RequirementsTxt { }, extras: [], marker: None, - path: Some( + source: Some( "/bare-url.txt", ), }, @@ -60,7 +60,7 @@ RequirementsTxt { ), ], marker: None, - path: Some( + source: Some( "/bare-url.txt", ), }, @@ -91,7 +91,7 @@ RequirementsTxt { }, extras: [], marker: None, - path: Some( + source: Some( "/bare-url.txt", ), }, diff --git a/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-whitespace.txt.snap b/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-whitespace.txt.snap index 0ba8a9c41..8d5fce028 100644 --- a/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-whitespace.txt.snap +++ b/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-whitespace.txt.snap @@ -13,7 +13,7 @@ RequirementsTxt { extras: [], version_or_url: None, marker: None, - path: Some( + source: Some( "/whitespace.txt", ), }, @@ -59,7 +59,7 @@ RequirementsTxt { ), ), marker: None, - path: Some( + source: Some( "/whitespace.txt", ), }, diff --git a/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-windows-bare-url.txt.snap b/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-windows-bare-url.txt.snap index 26a5c3b53..cfbd36cce 100644 --- a/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-windows-bare-url.txt.snap +++ b/crates/requirements-txt/src/snapshots/requirements_txt__test__parse-windows-bare-url.txt.snap @@ -25,7 +25,7 @@ RequirementsTxt { }, extras: [], marker: None, - path: Some( + source: Some( "/bare-url.txt", ), }, @@ -60,7 +60,7 @@ RequirementsTxt { ), ], marker: None, - path: Some( + source: Some( "/bare-url.txt", ), }, @@ -91,7 +91,7 @@ RequirementsTxt { }, extras: [], marker: None, - path: Some( + source: Some( "/bare-url.txt", ), }, diff --git a/crates/uv-dev/src/resolve_many.rs b/crates/uv-dev/src/resolve_many.rs index 95228cc43..3e10fd886 100644 --- a/crates/uv-dev/src/resolve_many.rs +++ b/crates/uv-dev/src/resolve_many.rs @@ -132,7 +132,7 @@ pub(crate) async fn resolve_many(args: ResolveManyArgs) -> Result<()> { extras: requirement.extras, version_or_url: Some(equals_version), marker: None, - path: requirement.path, + source: requirement.source, } } else { requirement diff --git a/crates/uv-requirements/src/unnamed.rs b/crates/uv-requirements/src/unnamed.rs index b00cbe729..ff6bd9e00 100644 --- a/crates/uv-requirements/src/unnamed.rs +++ b/crates/uv-requirements/src/unnamed.rs @@ -101,7 +101,7 @@ impl<'a, Context: BuildContext> NamedRequirementsResolver<'a, Context> { extras: requirement.extras, version_or_url: Some(VersionOrUrl::Url(requirement.url)), marker: requirement.marker, - path: requirement.path, + source: requirement.source, }); } @@ -120,7 +120,7 @@ impl<'a, Context: BuildContext> NamedRequirementsResolver<'a, Context> { extras: requirement.extras, version_or_url: Some(VersionOrUrl::Url(requirement.url)), marker: requirement.marker, - path: requirement.path, + source: requirement.source, }); } @@ -148,7 +148,7 @@ impl<'a, Context: BuildContext> NamedRequirementsResolver<'a, Context> { extras: requirement.extras, version_or_url: Some(VersionOrUrl::Url(requirement.url)), marker: requirement.marker, - path: requirement.path, + source: requirement.source, }); } @@ -170,7 +170,7 @@ impl<'a, Context: BuildContext> NamedRequirementsResolver<'a, Context> { extras: requirement.extras, version_or_url: Some(VersionOrUrl::Url(requirement.url)), marker: requirement.marker, - path: Some(project_path.clone()), + source: Some(project_path.clone()), }); } @@ -188,7 +188,7 @@ impl<'a, Context: BuildContext> NamedRequirementsResolver<'a, Context> { extras: requirement.extras, version_or_url: Some(VersionOrUrl::Url(requirement.url)), marker: requirement.marker, - path: Some(project_path.clone()), + source: Some(project_path.clone()), }); } } @@ -217,7 +217,7 @@ impl<'a, Context: BuildContext> NamedRequirementsResolver<'a, Context> { extras: requirement.extras, version_or_url: Some(VersionOrUrl::Url(requirement.url)), marker: requirement.marker, - path: requirement.path, + source: requirement.source, }); } } @@ -276,7 +276,7 @@ impl<'a, Context: BuildContext> NamedRequirementsResolver<'a, Context> { extras: requirement.extras, version_or_url: Some(VersionOrUrl::Url(requirement.url)), marker: requirement.marker, - path: requirement.path, + source: requirement.source, }) } } diff --git a/crates/uv-resolver/src/resolution.rs b/crates/uv-resolver/src/resolution.rs index b40de6190..93931e657 100644 --- a/crates/uv-resolver/src/resolution.rs +++ b/crates/uv-resolver/src/resolution.rs @@ -1,5 +1,5 @@ use std::borrow::Cow; -use std::collections::{BTreeMap, BTreeSet}; +use std::collections::BTreeSet; use std::hash::BuildHasherDefault; use std::rc::Rc; @@ -15,7 +15,7 @@ use rustc_hash::{FxHashMap, FxHashSet}; use distribution_types::{ Dist, DistributionMetadata, IndexUrl, LocalEditable, Name, ParsedUrlError, Requirement, - ResolvedDist, SourceAnnotation, Verbatim, VersionId, VersionOrUrlRef, + ResolvedDist, SourceAnnotations, Verbatim, VersionId, VersionOrUrlRef, }; use once_map::OnceMap; use pep440_rs::Version; @@ -545,20 +545,20 @@ pub struct DisplayResolutionGraph<'a> { /// package. annotation_style: AnnotationStyle, /// External sources for each package: requirements, constraints, and overrides. - sources: BTreeMap>, + sources: SourceAnnotations, } impl<'a> From<&'a ResolutionGraph> for DisplayResolutionGraph<'a> { fn from(resolution: &'a ResolutionGraph) -> Self { Self::new( resolution, - BTreeMap::default(), &[], false, false, true, false, AnnotationStyle::default(), + SourceAnnotations::default(), ) } } @@ -568,13 +568,13 @@ impl<'a> DisplayResolutionGraph<'a> { #[allow(clippy::fn_params_excessive_bools, clippy::too_many_arguments)] pub fn new( underlying: &'a ResolutionGraph, - sources: BTreeMap>, no_emit_packages: &'a [PackageName], show_hashes: bool, include_extras: bool, include_annotations: bool, include_index_annotation: bool, annotation_style: AnnotationStyle, + sources: SourceAnnotations, ) -> DisplayResolutionGraph<'a> { Self { resolution: underlying, @@ -726,15 +726,14 @@ impl std::fmt::Display for DisplayResolutionGraph<'_> { edges.sort_unstable_by_key(|package| package.name()); // Include all external sources (e.g., requirements files). - let source_name: String = match node { - Node::Editable(_package_name, local_editable) => { - local_editable.url.given().unwrap_or_default().to_string() + let default = BTreeSet::default(); + let source = match node { + Node::Editable(_, editable) => { + self.sources.get_editable(&editable.url).unwrap_or(&default) } - Node::Distribution(name, _, _) => name.to_string(), + Node::Distribution(name, _, _) => self.sources.get(name).unwrap_or(&default), }; - let source = self.sources.get(&source_name).cloned().unwrap_or_default(); - match self.annotation_style { AnnotationStyle::Line => { if !edges.is_empty() { @@ -742,7 +741,7 @@ impl std::fmt::Display for DisplayResolutionGraph<'_> { let deps = edges .into_iter() .map(|dependency| format!("{}", dependency.name())) - .chain(source.into_iter().map(|source| source.to_string())) + .chain(source.iter().map(std::string::ToString::to_string)) .collect::>() .join(", "); let comment = format!("# via {deps}").green().to_string(); @@ -766,8 +765,8 @@ impl std::fmt::Display for DisplayResolutionGraph<'_> { edges => { let separator = "\n"; let deps = source - .into_iter() - .map(|source| source.to_string()) + .iter() + .map(std::string::ToString::to_string) .chain( edges .iter() diff --git a/crates/uv/src/commands/pip_compile.rs b/crates/uv/src/commands/pip_compile.rs index a29a89318..f1561244f 100644 --- a/crates/uv/src/commands/pip_compile.rs +++ b/crates/uv/src/commands/pip_compile.rs @@ -1,5 +1,4 @@ use std::borrow::Cow; -use std::collections::{BTreeMap, BTreeSet}; use std::env; use std::fmt::Write; use std::io::stdout; @@ -17,7 +16,8 @@ use tempfile::tempdir_in; use tracing::debug; use distribution_types::{ - IndexLocations, LocalEditable, LocalEditables, ParsedUrlError, SourceAnnotation, Verbatim, + IndexLocations, LocalEditable, LocalEditables, ParsedUrlError, SourceAnnotation, + SourceAnnotations, Verbatim, }; use distribution_types::{Requirement, Requirements}; use install_wheel_rs::linker::LinkMode; @@ -354,61 +354,58 @@ pub(crate) async fn pip_compile( .resolve() .await?; - let mut sources: BTreeMap> = BTreeMap::new(); + // Generate a map from requirement to originating source file. + let mut sources = SourceAnnotations::default(); for requirement in &requirements { if let Some(path) = &requirement.path { if path.ends_with("pyproject.toml") { - sources - .entry(requirement.name.to_string()) - .or_default() - .insert(SourceAnnotation::PyProject { + sources.add( + &requirement.name, + SourceAnnotation::PyProject { path: path.clone(), project_name: project.as_ref().map(ToString::to_string), - }); + }, + ); } else { - sources - .entry(requirement.name.to_string()) - .or_default() - .insert(SourceAnnotation::Requirement(path.clone())); + sources.add( + &requirement.name, + SourceAnnotation::Requirement(path.clone()), + ); } } } for requirement in &constraints { if let Some(path) = &requirement.path { - sources - .entry(requirement.name.to_string()) - .or_default() - .insert(SourceAnnotation::Constraint(path.clone())); + sources.add( + &requirement.name, + SourceAnnotation::Constraint(path.clone()), + ); } } for requirement in &overrides { if let Some(path) = &requirement.path { - sources - .entry(requirement.name.to_string()) - .or_default() - .insert(SourceAnnotation::Override(path.clone())); + sources.add(&requirement.name, SourceAnnotation::Override(path.clone())); } } for editable in &editables { - let package_name = editable.url.given().unwrap_or_default().to_string(); if let Some(source) = &editable.source { if source.ends_with("pyproject.toml") { - sources - .entry(package_name) - .or_default() - .insert(SourceAnnotation::PyProject { + sources.add_editable( + editable.url(), + SourceAnnotation::PyProject { path: source.clone(), project_name: project.as_ref().map(ToString::to_string), - }); + }, + ); } else { - sources - .entry(package_name) - .or_default() - .insert(SourceAnnotation::Requirement(source.clone())); + sources.add_editable( + editable.url(), + SourceAnnotation::Requirement(source.clone()), + ); } } } @@ -654,13 +651,13 @@ pub(crate) async fn pip_compile( "{}", DisplayResolutionGraph::new( &resolution, - sources, &no_emit_packages, generate_hashes, include_extras, include_annotations, include_index_annotation, annotation_style, + sources, ) )?;