Skip to content

Commit 7a59f0b

Browse files
epageHezuikn
authored andcommitted
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. With cargo-add in rust-lang#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. See also https://internals.rust-lang.org/t/feedback-on-cargo-add-before-its-merged/16024/26?u=epage
1 parent eedeeff commit 7a59f0b

File tree

12 files changed

+69
-41
lines changed

12 files changed

+69
-41
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()))?;

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();

tests/testsuite/pkgid.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ fn simple() {
2929
.run();
3030

3131
p.cargo("pkgid bar")
32-
.with_stdout("https://github.com/rust-lang/crates.io-index#bar:0.1.0")
32+
.with_stdout("https://github.com/rust-lang/crates.io-index#bar@0.1.0")
3333
.run();
3434
}
3535

@@ -67,7 +67,7 @@ fn suggestion_bad_pkgid() {
6767
error: package ID specification `https://example.com/crates-io` did not match any packages
6868
Did you mean one of these?
6969
70-
crates-io:0.1.0
70+
crates-io@0.1.0
7171
",
7272
)
7373
.run();
@@ -89,11 +89,11 @@ error: package ID specification `crates_io` did not match any packages
8989
.with_status(101)
9090
.with_stderr(
9191
"\
92-
error: package ID specification `two-ver:0.3.0` did not match any packages
92+
error: package ID specification `two-ver@0.3.0` did not match any packages
9393
Did you mean one of these?
9494
95-
two-ver:0.1.0
96-
two-ver:0.2.0
95+
two-ver@0.1.0
96+
two-ver@0.2.0
9797
",
9898
)
9999
.run();

tests/testsuite/profile_config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ fn profile_config_override_spec_multiple() {
168168
.with_stderr(
169169
"\
170170
[ERROR] multiple package overrides in profile `dev` match package `bar v0.5.0 ([..])`
171-
found package specs: bar, bar:0.5.0",
171+
found package specs: bar, bar@0.5.0",
172172
)
173173
.run();
174174
}

tests/testsuite/profile_overrides.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ fn profile_override_warnings() {
7171
p.cargo("build")
7272
.with_stderr_contains(
7373
"\
74-
[WARNING] profile package spec `bar:1.2.3` in profile `dev` \
74+
[WARNING] profile package spec `bar@1.2.3` in profile `dev` \
7575
has a version or URL that does not match any of the packages: \
7676
bar v0.5.0 ([..]/foo/bar)
7777
[WARNING] profile package spec `bart` in profile `dev` did not match any packages
@@ -262,7 +262,7 @@ fn profile_override_spec_multiple() {
262262
.with_stderr_contains(
263263
"\
264264
[ERROR] multiple package overrides in profile `dev` match package `bar v0.5.0 ([..])`
265-
found package specs: bar, bar:0.5.0",
265+
found package specs: bar, bar@0.5.0",
266266
)
267267
.run();
268268
}

tests/testsuite/replace.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@ fn override_wrong_name() {
645645
[ERROR] failed to get `baz` as a dependency of package `foo v0.0.1 ([..])`
646646
647647
Caused by:
648-
no matching package for override `[..]baz:0.1.0` found
648+
no matching package for override `[..]baz@0.1.0` found
649649
location searched: file://[..]
650650
version required: =0.1.0
651651
",
@@ -729,7 +729,7 @@ fn override_wrong_version() {
729729
error: failed to parse manifest at `[..]`
730730
731731
Caused by:
732-
replacements cannot specify a version requirement, but found one for `[..]bar:0.1.0`
732+
replacements cannot specify a version requirement, but found one for `[..]bar@0.1.0`
733733
",
734734
)
735735
.run();
@@ -826,8 +826,8 @@ fn test_override_dep() {
826826
"\
827827
error: There are multiple `bar` packages in your project, and the [..]
828828
Please re-run this command with [..]
829-
[..]#bar:0.1.0
830-
[..]#bar:0.1.0
829+
[..]#bar@0.1.0
830+
[..]#bar@0.1.0
831831
",
832832
)
833833
.run();
@@ -1082,7 +1082,7 @@ fn overriding_nonexistent_no_spurious() {
10821082
p.cargo("build")
10831083
.with_stderr(
10841084
"\
1085-
[WARNING] package replacement is not used: [..]baz:0.1.0
1085+
[WARNING] package replacement is not used: [..]baz@0.1.0
10861086
[FINISHED] [..]
10871087
",
10881088
)

tests/testsuite/tree.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,8 +1569,8 @@ fn ambiguous_name() {
15691569
"\
15701570
error: There are multiple `dep` packages in your project, and the specification `dep` is ambiguous.
15711571
Please re-run this command with `-p <spec>` where `<spec>` is one of the following:
1572-
dep:1.0.0
1573-
dep:2.0.0
1572+
dep@1.0.0
1573+
dep@2.0.0
15741574
",
15751575
)
15761576
.with_status(101)

tests/testsuite/yank.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ fn simple() {
3838
.with_status(101)
3939
.with_stderr(
4040
" Updating `[..]` index
41-
Unyank foo:0.0.1
41+
Unyank foo@0.0.1
4242
error: failed to undo a yank from the registry at file:///[..]
4343
4444
Caused by:

0 commit comments

Comments
 (0)