Skip to content

Commit

Permalink
Auto merge of #12938 - epage:source-refactor, r=weihanglo
Browse files Browse the repository at this point in the history
refactor(source): Prepare for new PackageIDSpec syntax

### What does this PR try to resolve?

This adds tests and refactors to prepare for #12933

### How should we test and review this PR?

### Additional information
  • Loading branch information
bors committed Nov 10, 2023
2 parents 746802c + 9f511b6 commit 6790a51
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 59 deletions.
112 changes: 108 additions & 4 deletions src/cargo/core/package_id_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,10 +180,13 @@ impl PackageIdSpec {
}
}

match self.url {
Some(ref u) => u == package_id.source_id().url(),
None => true,
if let Some(u) = &self.url {
if u != package_id.source_id().url() {
return false;
}
}

true
}

/// Checks a list of `PackageId`s to find 1 that matches this `PackageIdSpec`. If 0, 2, or
Expand Down Expand Up @@ -331,7 +334,10 @@ mod tests {
fn ok(spec: &str, expected: PackageIdSpec, expected_rendered: &str) {
let parsed = PackageIdSpec::parse(spec).unwrap();
assert_eq!(parsed, expected);
assert_eq!(parsed.to_string(), expected_rendered);
let rendered = parsed.to_string();
assert_eq!(rendered, expected_rendered);
let reparsed = PackageIdSpec::parse(&rendered).unwrap();
assert_eq!(reparsed, expected);
}

ok(
Expand Down Expand Up @@ -424,6 +430,98 @@ mod tests {
},
"foo@1.2",
);

// pkgid-spec.md
ok(
"regex",
PackageIdSpec {
name: String::from("regex"),
version: None,
url: None,
},
"regex",
);
ok(
"regex@1.4",
PackageIdSpec {
name: String::from("regex"),
version: Some("1.4".parse().unwrap()),
url: None,
},
"regex@1.4",
);
ok(
"regex@1.4.3",
PackageIdSpec {
name: String::from("regex"),
version: Some("1.4.3".parse().unwrap()),
url: None,
},
"regex@1.4.3",
);
ok(
"https://github.com/rust-lang/crates.io-index#regex",
PackageIdSpec {
name: String::from("regex"),
version: None,
url: Some(Url::parse("https://github.com/rust-lang/crates.io-index").unwrap()),
},
"https://github.com/rust-lang/crates.io-index#regex",
);
ok(
"https://github.com/rust-lang/crates.io-index#regex@1.4.3",
PackageIdSpec {
name: String::from("regex"),
version: Some("1.4.3".parse().unwrap()),
url: Some(Url::parse("https://github.com/rust-lang/crates.io-index").unwrap()),
},
"https://github.com/rust-lang/crates.io-index#regex@1.4.3",
);
ok(
"https://github.com/rust-lang/cargo#0.52.0",
PackageIdSpec {
name: String::from("cargo"),
version: Some("0.52.0".parse().unwrap()),
url: Some(Url::parse("https://github.com/rust-lang/cargo").unwrap()),
},
"https://github.com/rust-lang/cargo#0.52.0",
);
ok(
"https://github.com/rust-lang/cargo#cargo-platform@0.1.2",
PackageIdSpec {
name: String::from("cargo-platform"),
version: Some("0.1.2".parse().unwrap()),
url: Some(Url::parse("https://github.com/rust-lang/cargo").unwrap()),
},
"https://github.com/rust-lang/cargo#cargo-platform@0.1.2",
);
ok(
"ssh://git@github.com/rust-lang/regex.git#regex@1.4.3",
PackageIdSpec {
name: String::from("regex"),
version: Some("1.4.3".parse().unwrap()),
url: Some(Url::parse("ssh://git@github.com/rust-lang/regex.git").unwrap()),
},
"ssh://git@github.com/rust-lang/regex.git#regex@1.4.3",
);
ok(
"file:///path/to/my/project/foo",
PackageIdSpec {
name: String::from("foo"),
version: None,
url: Some(Url::parse("file:///path/to/my/project/foo").unwrap()),
},
"file:///path/to/my/project/foo",
);
ok(
"file:///path/to/my/project/foo#1.1.8",
PackageIdSpec {
name: String::from("foo"),
version: Some("1.1.8".parse().unwrap()),
url: Some(Url::parse("file:///path/to/my/project/foo").unwrap()),
},
"file:///path/to/my/project/foo#1.1.8",
);
}

#[test]
Expand All @@ -450,6 +548,12 @@ mod tests {
assert!(PackageIdSpec::parse("foo@1.2.3").unwrap().matches(foo));
assert!(!PackageIdSpec::parse("foo@1.2.2").unwrap().matches(foo));
assert!(PackageIdSpec::parse("foo@1.2").unwrap().matches(foo));
assert!(PackageIdSpec::parse("https://example.com#foo@1.2")
.unwrap()
.matches(foo));
assert!(!PackageIdSpec::parse("https://bob.com#foo@1.2")
.unwrap()
.matches(foo));

let meta = PackageId::new("meta", "1.2.3+hello", sid).unwrap();
assert!(PackageIdSpec::parse("meta").unwrap().matches(meta));
Expand Down
103 changes: 48 additions & 55 deletions src/cargo/core/source_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,17 +188,7 @@ impl SourceId {
match kind {
"git" => {
let mut url = url.into_url()?;
let mut reference = GitReference::DefaultBranch;
for (k, v) in url.query_pairs() {
match &k[..] {
// Map older 'ref' to branch.
"branch" | "ref" => reference = GitReference::Branch(v.into_owned()),

"rev" => reference = GitReference::Rev(v.into_owned()),
"tag" => reference = GitReference::Tag(v.into_owned()),
_ => {}
}
}
let reference = GitReference::from_query(url.query_pairs());
let precise = url.fragment().map(|s| s.to_owned());
url.set_fragment(None);
url.set_query(None);
Expand Down Expand Up @@ -752,6 +742,20 @@ impl PartialEq for SourceIdInner {
}
}

impl SourceKind {
pub(crate) fn protocol(&self) -> Option<&str> {
match self {
SourceKind::Path => Some("path"),
SourceKind::Git(_) => Some("git"),
SourceKind::Registry => Some("registry"),
// Sparse registry URL already includes the `sparse+` prefix
SourceKind::SparseRegistry => None,
SourceKind::LocalRegistry => Some("local-registry"),
SourceKind::Directory => Some("directory"),
}
}
}

/// Forwards to `Ord`
impl PartialOrd for SourceKind {
fn partial_cmp(&self, other: &SourceKind) -> Option<Ordering> {
Expand Down Expand Up @@ -848,57 +852,46 @@ pub struct SourceIdAsUrl<'a> {

impl<'a> fmt::Display for SourceIdAsUrl<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self.inner {
SourceIdInner {
kind: SourceKind::Path,
ref url,
..
} => write!(f, "path+{}", url),
SourceIdInner {
kind: SourceKind::Git(ref reference),
ref url,
ref precise,
..
} => {
write!(f, "git+{}", url)?;
if let Some(pretty) = reference.pretty_ref(self.encoded) {
write!(f, "?{}", pretty)?;
}
if let Some(precise) = precise.as_ref() {
write!(f, "#{}", precise)?;
}
Ok(())
}
SourceIdInner {
kind: SourceKind::Registry,
ref url,
..
} => {
write!(f, "registry+{url}")
if let Some(protocol) = self.inner.kind.protocol() {
write!(f, "{protocol}+")?;
}
write!(f, "{}", self.inner.url)?;
if let SourceIdInner {
kind: SourceKind::Git(ref reference),
ref precise,
..
} = *self.inner
{
if let Some(pretty) = reference.pretty_ref(self.encoded) {
write!(f, "?{}", pretty)?;
}
SourceIdInner {
kind: SourceKind::SparseRegistry,
ref url,
..
} => {
// Sparse registry URL already includes the `sparse+` prefix
write!(f, "{url}")
if let Some(precise) = precise.as_ref() {
write!(f, "#{}", precise)?;
}
SourceIdInner {
kind: SourceKind::LocalRegistry,
ref url,
..
} => write!(f, "local-registry+{}", url),
SourceIdInner {
kind: SourceKind::Directory,
ref url,
..
} => write!(f, "directory+{}", url),
}
Ok(())
}
}

impl GitReference {
pub fn from_query(
query_pairs: impl Iterator<Item = (impl AsRef<str>, impl AsRef<str>)>,
) -> Self {
let mut reference = GitReference::DefaultBranch;
for (k, v) in query_pairs {
let v = v.as_ref();
match k.as_ref() {
// Map older 'ref' to branch.
"branch" | "ref" => reference = GitReference::Branch(v.to_owned()),

"rev" => reference = GitReference::Rev(v.to_owned()),
"tag" => reference = GitReference::Tag(v.to_owned()),
_ => {}
}
}
reference
}

/// Returns a `Display`able view of this git reference, or None if using
/// the head of the default branch
pub fn pretty_ref(&self, url_encoded: bool) -> Option<PrettyRef<'_>> {
Expand Down

0 comments on commit 6790a51

Please sign in to comment.