Skip to content

Commit 0f75da6

Browse files
committed
Auto merge of #10582 - epage:pkgid, r=ehuss
Extend pkgid syntax with `@` support In addition to `foo:1.2.3`, we now support `[email protected]` for pkgids. We are also making it the default way of rendering pkgid's for the user. ### What does this PR try to resolve? With cargo-add in #10472, we've decided to only use ``@`` in it and to add it as an alternative to `:` in the rest of cargo. `cargo-add` originally used ``@`.` When preparing it for merge, I switched to `:` to be consistent with pkgids. When discussing this, it was felt ``@`` has precedence in too many tools to switch to `:` but that we should instead switch pkgid's to use ``@`,` in a backwards compatible way. #10472 served as the change proposal for this See also - https://internals.rust-lang.org/t/feedback-on-cargo-add-before-its-merged/16024/26?u=epage - https://rust-lang.zulipchat.com/#narrow/stream/246057-t-cargo/topic/Multiple.20ways.20of.20specifying.20versions ### How should we test and review this PR? The focus of the testing is on the parsers unit tests and on the end-to-end output. We are not explicitly testing end-to-end input in this PR, assuming the unit tests are sufficient. ### Additional information This only focuses on places we already accept pkgids. Looking into supporting `[email protected]` in `cargo install` and `cargo yank` is being left for a future PR.
2 parents acaf8e2 + 709f1be commit 0f75da6

17 files changed

+89
-61
lines changed

src/cargo/core/compiler/future_incompat.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ fn render_report(per_package_reports: &[FutureIncompatReportPackage]) -> BTreeMa
236236
let mut report: BTreeMap<String, String> = BTreeMap::new();
237237
for per_package in per_package_reports {
238238
let package_spec = format!(
239-
"{}:{}",
239+
"{}@{}",
240240
per_package.package_id.name(),
241241
per_package.package_id.version()
242242
);
@@ -415,10 +415,10 @@ You may want to consider updating them to a newer version to see if the issue ha
415415
let manifest = bcx.packages.get_one(*package_id).unwrap().manifest();
416416
format!(
417417
"
418-
- {name}
418+
- {package_spec}
419419
- Repository: {url}
420-
- Detailed warning command: `cargo report future-incompatibilities --id {id} --package {name}`",
421-
name = format!("{}:{}", package_id.name(), package_id.version()),
420+
- Detailed warning command: `cargo report future-incompatibilities --id {id} --package {package_spec}`",
421+
package_spec = format!("{}@{}", package_id.name(), package_id.version()),
422422
url = manifest
423423
.metadata()
424424
.repository

src/cargo/core/package_id_spec.rs

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,10 @@ impl PackageIdSpec {
4141
/// "https://crates.io/foo",
4242
/// "https://crates.io/foo#1.2.3",
4343
/// "https://crates.io/foo#bar:1.2.3",
44+
/// "https://crates.io/foo#[email protected]",
4445
/// "foo",
4546
/// "foo:1.2.3",
47+
4648
/// ];
4749
/// for spec in specs {
4850
/// assert!(PackageIdSpec::parse(spec).is_ok());
@@ -65,7 +67,7 @@ impl PackageIdSpec {
6567
);
6668
}
6769
}
68-
let mut parts = spec.splitn(2, ':');
70+
let mut parts = spec.splitn(2, [':', '@']);
6971
let name = parts.next().unwrap();
7072
let version = match parts.next() {
7173
Some(version) => Some(version.to_semver()?),
@@ -122,7 +124,7 @@ impl PackageIdSpec {
122124
})?;
123125
match frag {
124126
Some(fragment) => {
125-
let mut parts = fragment.splitn(2, ':');
127+
let mut parts = fragment.splitn(2, [':', '@']);
126128
let name_or_version = parts.next().unwrap();
127129
match parts.next() {
128130
Some(part) => {
@@ -268,7 +270,7 @@ impl PackageIdSpec {
268270
}
269271
for id in ids {
270272
if version_cnt[id.version()] == 1 {
271-
msg.push_str(&format!("\n {}:{}", spec.name(), id.version()));
273+
msg.push_str(&format!("\n {}@{}", spec.name(), id.version()));
272274
} else {
273275
msg.push_str(&format!("\n {}", PackageIdSpec::from_package_id(*id)));
274276
}
@@ -290,11 +292,11 @@ impl fmt::Display for PackageIdSpec {
290292
}
291293
None => {
292294
printed_name = true;
293-
write!(f, "{}", self.name)?
295+
write!(f, "{}", self.name)?;
294296
}
295297
}
296298
if let Some(ref v) = self.version {
297-
write!(f, "{}{}", if printed_name { ":" } else { "#" }, v)?;
299+
write!(f, "{}{}", if printed_name { "@" } else { "#" }, v)?;
298300
}
299301
Ok(())
300302
}
@@ -329,10 +331,11 @@ mod tests {
329331

330332
#[test]
331333
fn good_parsing() {
332-
fn ok(spec: &str, expected: PackageIdSpec) {
334+
#[track_caller]
335+
fn ok(spec: &str, expected: PackageIdSpec, expected_rendered: &str) {
333336
let parsed = PackageIdSpec::parse(spec).unwrap();
334337
assert_eq!(parsed, expected);
335-
assert_eq!(parsed.to_string(), spec);
338+
assert_eq!(parsed.to_string(), expected_rendered);
336339
}
337340

338341
ok(
@@ -342,6 +345,7 @@ mod tests {
342345
version: None,
343346
url: Some(Url::parse("https://crates.io/foo").unwrap()),
344347
},
348+
"https://crates.io/foo",
345349
);
346350
ok(
347351
"https://crates.io/foo#1.2.3",
@@ -350,6 +354,7 @@ mod tests {
350354
version: Some("1.2.3".to_semver().unwrap()),
351355
url: Some(Url::parse("https://crates.io/foo").unwrap()),
352356
},
357+
"https://crates.io/foo#1.2.3",
353358
);
354359
ok(
355360
"https://crates.io/foo#bar:1.2.3",
@@ -358,6 +363,16 @@ mod tests {
358363
version: Some("1.2.3".to_semver().unwrap()),
359364
url: Some(Url::parse("https://crates.io/foo").unwrap()),
360365
},
366+
"https://crates.io/foo#[email protected]",
367+
);
368+
ok(
369+
"https://crates.io/foo#[email protected]",
370+
PackageIdSpec {
371+
name: InternedString::new("bar"),
372+
version: Some("1.2.3".to_semver().unwrap()),
373+
url: Some(Url::parse("https://crates.io/foo").unwrap()),
374+
},
375+
"https://crates.io/foo#[email protected]",
361376
);
362377
ok(
363378
"foo",
@@ -366,6 +381,7 @@ mod tests {
366381
version: None,
367382
url: None,
368383
},
384+
"foo",
369385
);
370386
ok(
371387
"foo:1.2.3",
@@ -374,6 +390,16 @@ mod tests {
374390
version: Some("1.2.3".to_semver().unwrap()),
375391
url: None,
376392
},
393+
394+
);
395+
ok(
396+
397+
PackageIdSpec {
398+
name: InternedString::new("foo"),
399+
version: Some("1.2.3".to_semver().unwrap()),
400+
url: None,
401+
},
402+
377403
);
378404
}
379405

@@ -382,6 +408,9 @@ mod tests {
382408
assert!(PackageIdSpec::parse("baz:").is_err());
383409
assert!(PackageIdSpec::parse("baz:*").is_err());
384410
assert!(PackageIdSpec::parse("baz:1.0").is_err());
411+
assert!(PackageIdSpec::parse("baz@").is_err());
412+
assert!(PackageIdSpec::parse("baz@*").is_err());
413+
assert!(PackageIdSpec::parse("[email protected]").is_err());
385414
assert!(PackageIdSpec::parse("https://baz:1.0").is_err());
386415
assert!(PackageIdSpec::parse("https://#baz:1.0").is_err());
387416
}
@@ -397,5 +426,7 @@ mod tests {
397426
assert!(!PackageIdSpec::parse("foo").unwrap().matches(bar));
398427
assert!(PackageIdSpec::parse("foo:1.2.3").unwrap().matches(foo));
399428
assert!(!PackageIdSpec::parse("foo:1.2.2").unwrap().matches(foo));
429+
assert!(PackageIdSpec::parse("[email protected]").unwrap().matches(foo));
430+
assert!(!PackageIdSpec::parse("[email protected]").unwrap().matches(foo));
400431
}
401432
}

src/cargo/ops/registry.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -896,20 +896,17 @@ pub fn yank(
896896
let (mut registry, _, _) =
897897
registry(config, token, index.as_deref(), reg.as_deref(), true, true)?;
898898

899+
let package_spec = format!("{}@{}", name, version);
899900
if undo {
900-
config
901-
.shell()
902-
.status("Unyank", format!("{}:{}", name, version))?;
901+
config.shell().status("Unyank", package_spec)?;
903902
registry.unyank(&name, &version).with_context(|| {
904903
format!(
905904
"failed to undo a yank from the registry at {}",
906905
registry.host()
907906
)
908907
})?;
909908
} else {
910-
config
911-
.shell()
912-
.status("Yank", format!("{}:{}", name, version))?;
909+
config.shell().status("Yank", package_spec)?;
913910
registry
914911
.yank(&name, &version)
915912
.with_context(|| format!("failed to yank from the registry at {}", registry.host()))?;

src/doc/man/cargo-pkgid.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ following:
2727
SPEC Structure | Example SPEC
2828
---------------------------|--------------
2929
_name_ | `bitflags`
30-
_name_`:`_version_ | `bitflags:1.0.4`
30+
_name_`@`_version_ | `bitflags@1.0.4`
3131
_url_ | `https://github.com/rust-lang/cargo`
3232
_url_`#`_version_ | `https://github.com/rust-lang/cargo#0.33.0`
3333
_url_`#`_name_ | `https://github.com/rust-lang/crates.io-index#bitflags`
34-
_url_`#`_name_`:`_version_ | `https://github.com/rust-lang/cargo#crates-io:0.21.0`
34+
_url_`#`_name_`:`_version_ | `https://github.com/rust-lang/cargo#crates-io@0.21.0`
3535

3636
## OPTIONS
3737

@@ -75,7 +75,7 @@ Get the package ID for the given package instead of the current package.
7575

7676
2. Retrieve package specification for version 1.0.0 of `foo`:
7777

78-
cargo pkgid foo:1.0.0
78+
cargo pkgid foo@1.0.0
7979

8080
3. Retrieve package specification for `foo` from crates.io:
8181

src/doc/man/generated_txt/cargo-pkgid.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ DESCRIPTION
2626
+-----------------+--------------------------------------------------+
2727
| name | bitflags |
2828
+-----------------+--------------------------------------------------+
29-
| name:version | bitflags:1.0.4 |
29+
| name@version | bitflags@1.0.4 |
3030
+-----------------+--------------------------------------------------+
3131
| url | https://github.com/rust-lang/cargo |
3232
+-----------------+--------------------------------------------------+
@@ -36,7 +36,7 @@ DESCRIPTION
3636
| | https://github.com/rust-lang/crates.io-index#bitflags |
3737
+-----------------+--------------------------------------------------+
3838
| | |
39-
| url#name:version | https://github.com/rust-lang/cargo#crates-io:0.21.0 |
39+
| url#name:version | https://github.com/rust-lang/cargo#crates-io@0.21.0 |
4040
+-----------------+--------------------------------------------------+
4141

4242
OPTIONS
@@ -133,7 +133,7 @@ EXAMPLES
133133

134134
2. Retrieve package specification for version 1.0.0 of foo:
135135

136-
cargo pkgid foo:1.0.0
136+
cargo pkgid foo@1.0.0
137137

138138
3. Retrieve package specification for foo from crates.io:
139139

src/doc/src/commands/cargo-pkgid.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ following:
2727
SPEC Structure | Example SPEC
2828
---------------------------|--------------
2929
_name_ | `bitflags`
30-
_name_`:`_version_ | `bitflags:1.0.4`
30+
_name_`@`_version_ | `bitflags@1.0.4`
3131
_url_ | `https://github.com/rust-lang/cargo`
3232
_url_`#`_version_ | `https://github.com/rust-lang/cargo#0.33.0`
3333
_url_`#`_name_ | `https://github.com/rust-lang/crates.io-index#bitflags`
34-
_url_`#`_name_`:`_version_ | `https://github.com/rust-lang/cargo#crates-io:0.21.0`
34+
_url_`#`_name_`:`_version_ | `https://github.com/rust-lang/cargo#crates-io@0.21.0`
3535

3636
## OPTIONS
3737

@@ -159,7 +159,7 @@ details on environment variables that Cargo reads.
159159

160160
2. Retrieve package specification for version 1.0.0 of `foo`:
161161

162-
cargo pkgid foo:1.0.0
162+
cargo pkgid foo@1.0.0
163163

164164
3. Retrieve package specification for `foo` from crates.io:
165165

src/doc/src/reference/pkgid-spec.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ is a string which is used to uniquely refer to one package within a graph of
99
packages.
1010

1111
The specification may be fully qualified, such as
12-
`https://github.com/rust-lang/crates.io-index#regex:1.4.3` or it may be
12+
`https://github.com/rust-lang/crates.io-index#regex@1.4.3` or it may be
1313
abbreviated, such as `regex`. The abbreviated form may be used as long as it
1414
uniquely identifies a single package in the dependency graph. If there is
1515
ambiguity, additional qualifiers can be added to make it unique. For example,
1616
if there are two versions of the `regex` package in the graph, then it can be
17-
qualified with a version to make it unique, such as `regex:1.4.3`.
17+
qualified with a version to make it unique, such as `regex@1.4.3`.
1818

1919
#### Specification grammar
2020

@@ -23,7 +23,7 @@ The formal grammar for a Package Id Specification is:
2323
```notrust
2424
spec := pkgname
2525
| proto "://" hostname-and-path [ "#" ( pkgname | semver ) ]
26-
pkgname := name [ ":" semver ]
26+
pkgname := name [ ("@" | ":" ) semver ]
2727
2828
proto := "http" | "git" | ...
2929
```
@@ -40,17 +40,17 @@ The following are references to the `regex` package on `crates.io`:
4040
| Spec | Name | Version |
4141
|:------------------------------------------------------------|:-------:|:-------:|
4242
| `regex` | `regex` | `*` |
43-
| `regex:1.4.3` | `regex` | `1.4.3` |
43+
| `regex@1.4.3` | `regex` | `1.4.3` |
4444
| `https://github.com/rust-lang/crates.io-index#regex` | `regex` | `*` |
45-
| `https://github.com/rust-lang/crates.io-index#regex:1.4.3` | `regex` | `1.4.3` |
45+
| `https://github.com/rust-lang/crates.io-index#regex@1.4.3` | `regex` | `1.4.3` |
4646

4747
The following are some examples of specs for several different git dependencies:
4848

4949
| Spec | Name | Version |
5050
|:----------------------------------------------------------|:----------------:|:--------:|
5151
| `https://github.com/rust-lang/cargo#0.52.0` | `cargo` | `0.52.0` |
52-
| `https://github.com/rust-lang/cargo#cargo-platform:0.1.2` | <nobr>`cargo-platform`</nobr> | `0.1.2` |
53-
| `ssh://[email protected]/rust-lang/regex.git#regex:1.4.3` | `regex` | `1.4.3` |
52+
| `https://github.com/rust-lang/cargo#cargo-platform@0.1.2` | <nobr>`cargo-platform`</nobr> | `0.1.2` |
53+
| `ssh://[email protected]/rust-lang/regex.git#regex@1.4.3` | `regex` | `1.4.3` |
5454

5555
Local packages on the filesystem can use `file://` URLs to reference them:
5656

src/etc/man/cargo-pkgid.1

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ T}:T{
3636
\fBbitflags\fR
3737
T}
3838
T{
39-
\fIname\fR\fB:\fR\fIversion\fR
39+
\fIname\fR\fB@\fR\fIversion\fR
4040
T}:T{
41-
\fBbitflags:1.0.4\fR
41+
\fBbitflags@1.0.4\fR
4242
T}
4343
T{
4444
\fIurl\fR
@@ -58,7 +58,7 @@ T}
5858
T{
5959
\fIurl\fR\fB#\fR\fIname\fR\fB:\fR\fIversion\fR
6060
T}:T{
61-
\fBhttps://github.com/rust\-lang/cargo#crates\-io:0.21.0\fR
61+
\fBhttps://github.com/rust\-lang/cargo#crates\-io@0.21.0\fR
6262
T}
6363
.TE
6464
.sp
@@ -195,7 +195,7 @@ cargo pkgid foo
195195
.sp
196196
.RS 4
197197
.nf
198-
cargo pkgid foo:1.0.0
198+
cargo pkgid foo@1.0.0
199199
.fi
200200
.RE
201201
.RE

tests/testsuite/credential_process.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ fn yank() {
361361
.with_stderr(
362362
"\
363363
[UPDATING] [..]
364-
[YANK] foo:0.1.0
364+
[YANK] foo@0.1.0
365365
",
366366
)
367367
.run();

tests/testsuite/future_incompat_report.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ frequency = 'never'
139139
.env("RUSTFLAGS", "-Zfuture-incompat-test")
140140
.with_stderr_contains(FUTURE_OUTPUT)
141141
.with_stderr_contains("warning: the following packages contain code that will be rejected by a future version of Rust: foo v0.0.0 [..]")
142-
.with_stderr_contains(" - foo:0.0.0[..]")
142+
.with_stderr_contains(" - foo@0.0.0[..]")
143143
.run();
144144
}
145145
}
@@ -189,17 +189,17 @@ fn test_multi_crate() {
189189
p.cargo(command).arg("--future-incompat-report")
190190
.env("RUSTFLAGS", "-Zfuture-incompat-test")
191191
.with_stderr_contains("warning: the following packages contain code that will be rejected by a future version of Rust: first-dep v0.0.1, second-dep v0.0.2")
192-
.with_stderr_contains(" - first-dep:0.0.1")
193-
.with_stderr_contains(" - second-dep:0.0.2")
192+
.with_stderr_contains(" - first-dep@0.0.1")
193+
.with_stderr_contains(" - second-dep@0.0.2")
194194
.run();
195195

196-
p.cargo("report future-incompatibilities").arg("--package").arg("first-dep:0.0.1")
196+
p.cargo("report future-incompatibilities").arg("--package").arg("first-dep@0.0.1")
197197
.with_stdout_contains("The package `first-dep v0.0.1` currently triggers the following future incompatibility lints:")
198198
.with_stdout_contains(FUTURE_OUTPUT)
199199
.with_stdout_does_not_contain("[..]second-dep-0.0.2/src[..]")
200200
.run();
201201

202-
p.cargo("report future-incompatibilities").arg("--package").arg("second-dep:0.0.2")
202+
p.cargo("report future-incompatibilities").arg("--package").arg("second-dep@0.0.2")
203203
.with_stdout_contains("The package `second-dep v0.0.2` currently triggers the following future incompatibility lints:")
204204
.with_stdout_contains(FUTURE_OUTPUT)
205205
.with_stdout_does_not_contain("[..]first-dep-0.0.1/src[..]")

tests/testsuite/git.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1750,8 +1750,8 @@ fn update_ambiguous() {
17501750
is ambiguous.
17511751
Please re-run this command with `-p <spec>` where `<spec>` is one of the \
17521752
following:
1753-
bar:0.[..].0
1754-
bar:0.[..].0
1753+
bar@0.[..].0
1754+
bar@0.[..].0
17551755
",
17561756
)
17571757
.run();

0 commit comments

Comments
 (0)