Ignore workspace.default-members when running cargo install on root package of a non-virtual workspace

This commit is contained in:
Ted Kaminski 2022-09-09 19:57:45 +00:00
parent 1cd6d3803d
commit 7dc8be5414
6 changed files with 63 additions and 15 deletions

View File

@ -6,10 +6,11 @@ use cargo_util::ProcessBuilder;
use serde::ser;
use std::cell::RefCell;
use std::path::PathBuf;
use std::sync::Arc;
use std::thread::available_parallelism;
/// Configuration information for a rustc build.
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct BuildConfig {
/// The requested kind of compilation for this session
pub requested_kinds: Vec<CompileKind>,
@ -33,7 +34,7 @@ pub struct BuildConfig {
pub primary_unit_rustc: Option<ProcessBuilder>,
/// A thread used by `cargo fix` to receive messages on a socket regarding
/// the success/failure of applying fixes.
pub rustfix_diagnostic_server: RefCell<Option<RustfixDiagnosticServer>>,
pub rustfix_diagnostic_server: Arc<RefCell<Option<RustfixDiagnosticServer>>>,
/// The directory to copy final artifacts to. Note that even if `out_dir` is
/// set, a copy of artifacts still could be found a `target/(debug\release)`
/// as usual.
@ -100,7 +101,7 @@ impl BuildConfig {
build_plan: false,
unit_graph: false,
primary_unit_rustc: None,
rustfix_diagnostic_server: RefCell::new(None),
rustfix_diagnostic_server: Arc::new(RefCell::new(None)),
export_dir: None,
future_incompat_report: false,
timing_outputs: Vec::new(),

View File

@ -34,7 +34,7 @@ pub enum FilterRule {
///
/// [`generate_root_units`]: super::UnitGenerator::generate_root_units
/// [`Packages`]: crate::ops::Packages
#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum CompileFilter {
/// The default set of Cargo targets.
Default {

View File

@ -68,7 +68,7 @@ pub use packages::Packages;
/// of it as `CompileOptions` are high-level settings requested on the
/// command-line, and `BuildConfig` are low-level settings for actually
/// driving `rustc`.
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct CompileOptions {
/// Configuration information for a rustc build
pub build_config: BuildConfig,

View File

@ -13,7 +13,7 @@ use anyhow::{bail, Context as _};
///
/// Generally, it represents the combination of all `-p` flag. When working within
/// a workspace, `--exclude` and `--workspace` flags also contribute to it.
#[derive(PartialEq, Eq, Debug)]
#[derive(PartialEq, Eq, Debug, Clone)]
pub enum Packages {
/// Packages selected by default. Usually means no flag provided.
Default,

View File

@ -5,8 +5,8 @@ use std::{env, fs};
use crate::core::compiler::{CompileKind, DefaultExecutor, Executor, UnitOutput};
use crate::core::{Dependency, Edition, Package, PackageId, Source, SourceId, Workspace};
use crate::ops::CompileFilter;
use crate::ops::{common_for_install_and_uninstall::*, FilterRule};
use crate::ops::{CompileFilter, Packages};
use crate::sources::{GitSource, PathSource, SourceConfigMap};
use crate::util::errors::CargoResult;
use crate::util::{Config, Filesystem, Rustc, ToSemver, VersionReqExt};
@ -37,7 +37,7 @@ impl Drop for Transaction {
struct InstallablePackage<'cfg, 'a> {
config: &'cfg Config,
opts: &'a ops::CompileOptions,
opts: ops::CompileOptions,
root: Filesystem,
source_id: SourceId,
vers: Option<&'a str>,
@ -60,7 +60,7 @@ impl<'cfg, 'a> InstallablePackage<'cfg, 'a> {
source_id: SourceId,
from_cwd: bool,
vers: Option<&'a str>,
opts: &'a ops::CompileOptions,
original_opts: &'a ops::CompileOptions,
force: bool,
no_track: bool,
needs_update_if_source_is_index: bool,
@ -145,7 +145,7 @@ impl<'cfg, 'a> InstallablePackage<'cfg, 'a> {
dep.clone(),
&mut source,
config,
opts,
original_opts,
&root,
&dst,
force,
@ -167,7 +167,14 @@ impl<'cfg, 'a> InstallablePackage<'cfg, 'a> {
}
};
let (ws, rustc, target) = make_ws_rustc_target(config, opts, &source_id, pkg.clone())?;
// When we build this package, we want to build the *specified* package only,
// and avoid building e.g. workspace default-members instead. Do so by constructing
// specialized compile options specific to the identified package.
// See test `path_install_workspace_root_despite_default_members`.
let mut opts = original_opts.clone();
opts.spec = Packages::Packages(vec![pkg.name().to_string()]);
let (ws, rustc, target) = make_ws_rustc_target(config, &opts, &source_id, pkg.clone())?;
// If we're installing in --locked mode and there's no `Cargo.lock` published
// ie. the bin was published before https://github.com/rust-lang/cargo/pull/7026
if config.locked() && !ws.root().join("Cargo.lock").exists() {
@ -235,7 +242,7 @@ impl<'cfg, 'a> InstallablePackage<'cfg, 'a> {
// Check for conflicts.
ip.no_track_duplicates(&dst)?;
} else if is_installed(
&ip.pkg, config, opts, &ip.rustc, &ip.target, &ip.root, &dst, force,
&ip.pkg, config, &ip.opts, &ip.rustc, &ip.target, &ip.root, &dst, force,
)? {
let msg = format!(
"package `{}` is already installed, use --force to override",
@ -297,7 +304,7 @@ impl<'cfg, 'a> InstallablePackage<'cfg, 'a> {
self.check_yanked_install()?;
let exec: Arc<dyn Executor> = Arc::new(DefaultExecutor);
let compile = ops::compile_ws(&self.ws, self.opts, &exec).with_context(|| {
let compile = ops::compile_ws(&self.ws, &self.opts, &exec).with_context(|| {
if let Some(td) = td_opt.take() {
// preserve the temporary directory, so the user can inspect it
td.into_path();
@ -372,7 +379,7 @@ impl<'cfg, 'a> InstallablePackage<'cfg, 'a> {
&dst,
&self.pkg,
self.force,
self.opts,
&self.opts,
&self.target,
&self.rustc.verbose_version,
)?;
@ -439,7 +446,7 @@ impl<'cfg, 'a> InstallablePackage<'cfg, 'a> {
&self.pkg,
&successful_bins,
self.vers.map(|s| s.to_string()),
self.opts,
&self.opts,
&self.target,
&self.rustc.verbose_version,
);

View File

@ -1292,6 +1292,46 @@ fn use_path_workspace() {
assert_eq!(lock, lock2, "different lockfiles");
}
#[cargo_test]
fn path_install_workspace_root_despite_default_members() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "ws-root"
version = "0.1.0"
authors = []
[workspace]
members = ["ws-member"]
default-members = ["ws-member"]
"#,
)
.file("src/main.rs", "fn main() {}")
.file(
"ws-member/Cargo.toml",
r#"
[package]
name = "ws-member"
version = "0.1.0"
authors = []
"#,
)
.file("ws-member/src/main.rs", "fn main() {}")
.build();
p.cargo("install --path")
.arg(p.root())
.arg("ws-root")
.with_stderr_contains(
"[INSTALLED] package `ws-root v0.1.0 ([..])` (executable `ws-root[EXE]`)",
)
// Particularly avoid "Installed package `ws-root v0.1.0 ([..]])` (executable `ws-member`)":
.with_stderr_does_not_contain("ws-member")
.run();
}
#[cargo_test]
fn dev_dependencies_no_check() {
Package::new("foo", "1.0.0").publish();