Skip to content

Commit 7dc8be5

Browse files
committed
Ignore workspace.default-members when running cargo install on root package of a non-virtual workspace
1 parent 1cd6d38 commit 7dc8be5

File tree

6 files changed

+63
-15
lines changed

6 files changed

+63
-15
lines changed

src/cargo/core/compiler/build_config.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ use cargo_util::ProcessBuilder;
66
use serde::ser;
77
use std::cell::RefCell;
88
use std::path::PathBuf;
9+
use std::sync::Arc;
910
use std::thread::available_parallelism;
1011

1112
/// Configuration information for a rustc build.
12-
#[derive(Debug)]
13+
#[derive(Debug, Clone)]
1314
pub struct BuildConfig {
1415
/// The requested kind of compilation for this session
1516
pub requested_kinds: Vec<CompileKind>,
@@ -33,7 +34,7 @@ pub struct BuildConfig {
3334
pub primary_unit_rustc: Option<ProcessBuilder>,
3435
/// A thread used by `cargo fix` to receive messages on a socket regarding
3536
/// the success/failure of applying fixes.
36-
pub rustfix_diagnostic_server: RefCell<Option<RustfixDiagnosticServer>>,
37+
pub rustfix_diagnostic_server: Arc<RefCell<Option<RustfixDiagnosticServer>>>,
3738
/// The directory to copy final artifacts to. Note that even if `out_dir` is
3839
/// set, a copy of artifacts still could be found a `target/(debug\release)`
3940
/// as usual.
@@ -100,7 +101,7 @@ impl BuildConfig {
100101
build_plan: false,
101102
unit_graph: false,
102103
primary_unit_rustc: None,
103-
rustfix_diagnostic_server: RefCell::new(None),
104+
rustfix_diagnostic_server: Arc::new(RefCell::new(None)),
104105
export_dir: None,
105106
future_incompat_report: false,
106107
timing_outputs: Vec::new(),

src/cargo/ops/cargo_compile/compile_filter.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub enum FilterRule {
3434
///
3535
/// [`generate_root_units`]: super::UnitGenerator::generate_root_units
3636
/// [`Packages`]: crate::ops::Packages
37-
#[derive(Debug)]
37+
#[derive(Debug, Clone)]
3838
pub enum CompileFilter {
3939
/// The default set of Cargo targets.
4040
Default {

src/cargo/ops/cargo_compile/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ pub use packages::Packages;
6868
/// of it as `CompileOptions` are high-level settings requested on the
6969
/// command-line, and `BuildConfig` are low-level settings for actually
7070
/// driving `rustc`.
71-
#[derive(Debug)]
71+
#[derive(Debug, Clone)]
7272
pub struct CompileOptions {
7373
/// Configuration information for a rustc build
7474
pub build_config: BuildConfig,

src/cargo/ops/cargo_compile/packages.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use anyhow::{bail, Context as _};
1313
///
1414
/// Generally, it represents the combination of all `-p` flag. When working within
1515
/// a workspace, `--exclude` and `--workspace` flags also contribute to it.
16-
#[derive(PartialEq, Eq, Debug)]
16+
#[derive(PartialEq, Eq, Debug, Clone)]
1717
pub enum Packages {
1818
/// Packages selected by default. Usually means no flag provided.
1919
Default,

src/cargo/ops/cargo_install.rs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use std::{env, fs};
55

66
use crate::core::compiler::{CompileKind, DefaultExecutor, Executor, UnitOutput};
77
use crate::core::{Dependency, Edition, Package, PackageId, Source, SourceId, Workspace};
8-
use crate::ops::CompileFilter;
98
use crate::ops::{common_for_install_and_uninstall::*, FilterRule};
9+
use crate::ops::{CompileFilter, Packages};
1010
use crate::sources::{GitSource, PathSource, SourceConfigMap};
1111
use crate::util::errors::CargoResult;
1212
use crate::util::{Config, Filesystem, Rustc, ToSemver, VersionReqExt};
@@ -37,7 +37,7 @@ impl Drop for Transaction {
3737

3838
struct InstallablePackage<'cfg, 'a> {
3939
config: &'cfg Config,
40-
opts: &'a ops::CompileOptions,
40+
opts: ops::CompileOptions,
4141
root: Filesystem,
4242
source_id: SourceId,
4343
vers: Option<&'a str>,
@@ -60,7 +60,7 @@ impl<'cfg, 'a> InstallablePackage<'cfg, 'a> {
6060
source_id: SourceId,
6161
from_cwd: bool,
6262
vers: Option<&'a str>,
63-
opts: &'a ops::CompileOptions,
63+
original_opts: &'a ops::CompileOptions,
6464
force: bool,
6565
no_track: bool,
6666
needs_update_if_source_is_index: bool,
@@ -145,7 +145,7 @@ impl<'cfg, 'a> InstallablePackage<'cfg, 'a> {
145145
dep.clone(),
146146
&mut source,
147147
config,
148-
opts,
148+
original_opts,
149149
&root,
150150
&dst,
151151
force,
@@ -167,7 +167,14 @@ impl<'cfg, 'a> InstallablePackage<'cfg, 'a> {
167167
}
168168
};
169169

170-
let (ws, rustc, target) = make_ws_rustc_target(config, opts, &source_id, pkg.clone())?;
170+
// When we build this package, we want to build the *specified* package only,
171+
// and avoid building e.g. workspace default-members instead. Do so by constructing
172+
// specialized compile options specific to the identified package.
173+
// See test `path_install_workspace_root_despite_default_members`.
174+
let mut opts = original_opts.clone();
175+
opts.spec = Packages::Packages(vec![pkg.name().to_string()]);
176+
177+
let (ws, rustc, target) = make_ws_rustc_target(config, &opts, &source_id, pkg.clone())?;
171178
// If we're installing in --locked mode and there's no `Cargo.lock` published
172179
// ie. the bin was published before https://github.com/rust-lang/cargo/pull/7026
173180
if config.locked() && !ws.root().join("Cargo.lock").exists() {
@@ -235,7 +242,7 @@ impl<'cfg, 'a> InstallablePackage<'cfg, 'a> {
235242
// Check for conflicts.
236243
ip.no_track_duplicates(&dst)?;
237244
} else if is_installed(
238-
&ip.pkg, config, opts, &ip.rustc, &ip.target, &ip.root, &dst, force,
245+
&ip.pkg, config, &ip.opts, &ip.rustc, &ip.target, &ip.root, &dst, force,
239246
)? {
240247
let msg = format!(
241248
"package `{}` is already installed, use --force to override",
@@ -297,7 +304,7 @@ impl<'cfg, 'a> InstallablePackage<'cfg, 'a> {
297304
self.check_yanked_install()?;
298305

299306
let exec: Arc<dyn Executor> = Arc::new(DefaultExecutor);
300-
let compile = ops::compile_ws(&self.ws, self.opts, &exec).with_context(|| {
307+
let compile = ops::compile_ws(&self.ws, &self.opts, &exec).with_context(|| {
301308
if let Some(td) = td_opt.take() {
302309
// preserve the temporary directory, so the user can inspect it
303310
td.into_path();
@@ -372,7 +379,7 @@ impl<'cfg, 'a> InstallablePackage<'cfg, 'a> {
372379
&dst,
373380
&self.pkg,
374381
self.force,
375-
self.opts,
382+
&self.opts,
376383
&self.target,
377384
&self.rustc.verbose_version,
378385
)?;
@@ -439,7 +446,7 @@ impl<'cfg, 'a> InstallablePackage<'cfg, 'a> {
439446
&self.pkg,
440447
&successful_bins,
441448
self.vers.map(|s| s.to_string()),
442-
self.opts,
449+
&self.opts,
443450
&self.target,
444451
&self.rustc.verbose_version,
445452
);

tests/testsuite/install.rs

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

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

0 commit comments

Comments
 (0)