Skip to content

Commit 08889ee

Browse files
committed
Ignore workspace.default-members when running cargo install on root package of a non-virtual workspace
1 parent 9467f81 commit 08889ee

File tree

3 files changed

+62
-0
lines changed

3 files changed

+62
-0
lines changed

src/cargo/core/workspace.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,23 @@ impl<'cfg> Workspace<'cfg> {
552552
})
553553
}
554554

555+
/// Reset "default build" behavior for non-virtual workspaces, so that a build in
556+
/// the workspace root would build the root package, not the packages specified
557+
/// in `workspace.default-members`.
558+
pub fn ignore_default_members(&mut self) -> &mut Workspace<'cfg> {
559+
// If we're building a virtual workspace, then there is no root package to build
560+
if self.is_virtual() {
561+
return self;
562+
}
563+
// If we're not building the root package, then the default members do not matter
564+
if self.current_manifest != self.root_manifest() {
565+
return self;
566+
}
567+
568+
self.default_members = vec![self.current_manifest.clone()];
569+
self
570+
}
571+
555572
/// Returns true if the package is a member of the workspace.
556573
pub fn is_member(&self, pkg: &Package) -> bool {
557574
self.member_ids.contains(&pkg.package_id())

src/cargo/ops/cargo_install.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,11 @@ fn make_ws_rustc_target<'cfg>(
734734
ws.set_ignore_lock(config.lock_update_allowed());
735735
ws.set_require_optional_deps(false);
736736

737+
// `cargo install` effectively does `cargo build` in `pkg`. But when this is the root
738+
// of a non-virtual workspace, that would accidentally build `workspace.default-members`
739+
// instead of `pkg` (possibly not even including `pkg` at all!)
740+
ws.ignore_default_members();
741+
737742
let rustc = config.load_global_rustc(Some(&ws))?;
738743
let target = match &opts.build_config.single_requested_kind()? {
739744
CompileKind::Host => rustc.host.as_str().to_owned(),

tests/testsuite/install.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,6 +1294,46 @@ fn use_path_workspace() {
12941294
assert_eq!(lock, lock2, "different lockfiles");
12951295
}
12961296

1297+
#[cargo_test]
1298+
fn path_install_workspace_root_despite_default_members() {
1299+
let p = project()
1300+
.file(
1301+
"Cargo.toml",
1302+
r#"
1303+
[package]
1304+
name = "ws-root"
1305+
version = "0.1.0"
1306+
authors = []
1307+
1308+
[workspace]
1309+
members = ["ws-member"]
1310+
default-members = ["ws-member"]
1311+
"#,
1312+
)
1313+
.file("src/main.rs", "fn main() {}")
1314+
.file(
1315+
"ws-member/Cargo.toml",
1316+
r#"
1317+
[package]
1318+
name = "ws-member"
1319+
version = "0.1.0"
1320+
authors = []
1321+
"#,
1322+
)
1323+
.file("ws-member/src/main.rs", "fn main() {}")
1324+
.build();
1325+
1326+
p.cargo("install --path")
1327+
.arg(p.root())
1328+
.arg("ws-root")
1329+
.with_stderr_contains(
1330+
"[INSTALLED] package `ws-root v0.1.0 ([..])` (executable `ws-root[EXE]`)",
1331+
)
1332+
// Particularly avoid "Installed package `ws-root v0.1.0 ([..]])` (executable `ws-member`)":
1333+
.with_stderr_does_not_contain("ws-member")
1334+
.run();
1335+
}
1336+
12971337
#[cargo_test]
12981338
fn dev_dependencies_no_check() {
12991339
Package::new("foo", "1.0.0").publish();

0 commit comments

Comments
 (0)