Skip to content

Commit 8ed4cb1

Browse files
committed
Auto merge of #13335 - hi-rustin:rustin-patch-same-name, r=weihanglo
fix: use spec id instead of name to match package
2 parents 61debf8 + 7a13864 commit 8ed4cb1

File tree

2 files changed

+91
-23
lines changed

2 files changed

+91
-23
lines changed

src/cargo/ops/cargo_compile/packages.rs

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use std::collections::BTreeSet;
44

5-
use crate::core::Package;
5+
use crate::core::{Package, PackageIdSpecQuery};
66
use crate::core::{PackageIdSpec, Workspace};
77
use crate::util::restricted_names::is_glob_pattern;
88
use crate::util::CargoResult;
@@ -50,16 +50,24 @@ impl Packages {
5050
.map(|id| id.to_spec())
5151
.collect(),
5252
Packages::OptOut(opt_out) => {
53-
let (mut patterns, mut names) = opt_patterns_and_names(opt_out)?;
53+
let (mut patterns, mut ids) = opt_patterns_and_ids(opt_out)?;
5454
let specs = ws
5555
.members()
5656
.filter(|pkg| {
57-
!names.remove(pkg.name().as_str()) && !match_patterns(pkg, &mut patterns)
57+
let id = ids.iter().find(|id| id.matches(pkg.package_id())).cloned();
58+
if let Some(id) = &id {
59+
ids.remove(id);
60+
}
61+
!id.is_some() && !match_patterns(pkg, &mut patterns)
5862
})
5963
.map(Package::package_id)
6064
.map(|id| id.to_spec())
6165
.collect();
6266
let warn = |e| ws.config().shell().warn(e);
67+
let names = ids
68+
.into_iter()
69+
.map(|id| id.to_string())
70+
.collect::<BTreeSet<_>>();
6371
emit_package_not_found(ws, names, true).or_else(warn)?;
6472
emit_pattern_not_found(ws, patterns, true).or_else(warn)?;
6573
specs
@@ -68,11 +76,7 @@ impl Packages {
6876
vec![ws.current()?.package_id().to_spec()]
6977
}
7078
Packages::Packages(opt_in) => {
71-
let (mut patterns, packages) = opt_patterns_and_names(opt_in)?;
72-
let mut specs = packages
73-
.iter()
74-
.map(|p| PackageIdSpec::parse(p))
75-
.collect::<Result<Vec<_>, _>>()?;
79+
let (mut patterns, mut specs) = opt_patterns_and_ids(opt_in)?;
7680
if !patterns.is_empty() {
7781
let matched_pkgs = ws
7882
.members()
@@ -82,7 +86,7 @@ impl Packages {
8286
specs.extend(matched_pkgs);
8387
}
8488
emit_pattern_not_found(ws, patterns, false)?;
85-
specs
89+
specs.into_iter().collect()
8690
}
8791
Packages::Default => ws
8892
.default_members()
@@ -109,25 +113,41 @@ impl Packages {
109113
Packages::Default => ws.default_members().collect(),
110114
Packages::All => ws.members().collect(),
111115
Packages::OptOut(opt_out) => {
112-
let (mut patterns, mut names) = opt_patterns_and_names(opt_out)?;
116+
let (mut patterns, mut ids) = opt_patterns_and_ids(opt_out)?;
113117
let packages = ws
114118
.members()
115119
.filter(|pkg| {
116-
!names.remove(pkg.name().as_str()) && !match_patterns(pkg, &mut patterns)
120+
let id = ids.iter().find(|id| id.matches(pkg.package_id())).cloned();
121+
if let Some(id) = &id {
122+
ids.remove(id);
123+
}
124+
!id.is_some() && !match_patterns(pkg, &mut patterns)
117125
})
118126
.collect();
127+
let names = ids
128+
.into_iter()
129+
.map(|id| id.to_string())
130+
.collect::<BTreeSet<_>>();
119131
emit_package_not_found(ws, names, true)?;
120132
emit_pattern_not_found(ws, patterns, true)?;
121133
packages
122134
}
123135
Packages::Packages(opt_in) => {
124-
let (mut patterns, mut names) = opt_patterns_and_names(opt_in)?;
136+
let (mut patterns, mut ids) = opt_patterns_and_ids(opt_in)?;
125137
let packages = ws
126138
.members()
127139
.filter(|pkg| {
128-
names.remove(pkg.name().as_str()) || match_patterns(pkg, &mut patterns)
140+
let id = ids.iter().find(|id| id.matches(pkg.package_id())).cloned();
141+
if let Some(id) = &id {
142+
ids.remove(id);
143+
}
144+
id.is_some() || match_patterns(pkg, &mut patterns)
129145
})
130146
.collect();
147+
let names = ids
148+
.into_iter()
149+
.map(|id| id.to_string())
150+
.collect::<BTreeSet<_>>();
131151
emit_package_not_found(ws, names, false)?;
132152
emit_pattern_not_found(ws, patterns, false)?;
133153
packages
@@ -151,7 +171,7 @@ impl Packages {
151171
/// Emits "package not found" error.
152172
fn emit_package_not_found(
153173
ws: &Workspace<'_>,
154-
opt_names: BTreeSet<&str>,
174+
opt_names: BTreeSet<String>,
155175
opt_out: bool,
156176
) -> CargoResult<()> {
157177
if !opt_names.is_empty() {
@@ -188,20 +208,22 @@ fn emit_pattern_not_found(
188208
}
189209

190210
/// Given a list opt-in or opt-out package selection strings, generates two
191-
/// collections that represent glob patterns and package names respectively.
192-
fn opt_patterns_and_names(
211+
/// collections that represent glob patterns and package id specs respectively.
212+
fn opt_patterns_and_ids(
193213
opt: &[String],
194-
) -> CargoResult<(Vec<(glob::Pattern, bool)>, BTreeSet<&str>)> {
214+
) -> CargoResult<(Vec<(glob::Pattern, bool)>, BTreeSet<PackageIdSpec>)> {
195215
let mut opt_patterns = Vec::new();
196-
let mut opt_names = BTreeSet::new();
216+
let mut opt_ids = BTreeSet::new();
197217
for x in opt.iter() {
198-
if PackageIdSpec::parse(x).is_err() && is_glob_pattern(x) {
199-
opt_patterns.push((build_glob(x)?, false));
200-
} else {
201-
opt_names.insert(String::as_str(x));
218+
match PackageIdSpec::parse(x) {
219+
Ok(spec) => {
220+
opt_ids.insert(spec);
221+
}
222+
Err(_) if is_glob_pattern(x) => opt_patterns.push((build_glob(x)?, false)),
223+
Err(e) => return Err(e.into()),
202224
}
203225
}
204-
Ok((opt_patterns, opt_names))
226+
Ok((opt_patterns, opt_ids))
205227
}
206228

207229
/// Checks whether a package matches any of a list of glob patterns generated

tests/testsuite/run.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1566,3 +1566,49 @@ fn run_link_system_path_macos() {
15661566
p2.cargo("run").env(VAR, &libdir).run();
15671567
p2.cargo("test").env(VAR, &libdir).run();
15681568
}
1569+
1570+
#[cargo_test]
1571+
fn run_binary_with_same_name_as_dependency() {
1572+
let p = project()
1573+
.file(
1574+
"Cargo.toml",
1575+
r#"
1576+
[package]
1577+
name = "foo"
1578+
version = "0.5.0"
1579+
authors = []
1580+
1581+
[dependencies]
1582+
foo = { path = "foo" }
1583+
"#,
1584+
)
1585+
.file(
1586+
"src/main.rs",
1587+
r#"
1588+
fn main() {}
1589+
"#,
1590+
)
1591+
.file(
1592+
"foo/Cargo.toml",
1593+
r#"
1594+
[package]
1595+
name = "foo"
1596+
version = "0.1.0"
1597+
authors = []
1598+
1599+
[lib]
1600+
name = "foo"
1601+
path = "foo.rs"
1602+
"#,
1603+
)
1604+
.file("foo/foo.rs", "")
1605+
.build();
1606+
p.cargo("run").run();
1607+
p.cargo("check -p [email protected]").run();
1608+
p.cargo("run -p [email protected]").run();
1609+
p.cargo("run -p [email protected]").run();
1610+
p.cargo("run -p [email protected]")
1611+
.with_status(101)
1612+
.with_stderr("[ERROR] package(s) `[email protected]` not found in workspace `[..]`")
1613+
.run();
1614+
}

0 commit comments

Comments
 (0)