diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index 1f8df9626aa..0a1d83c3086 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -22,7 +22,8 @@ //! previously compiled dependency //! -use std::collections::{HashMap, HashSet}; +use std::collections::{BTreeSet, HashMap, HashSet}; +use std::iter::FromIterator; use std::path::PathBuf; use std::sync::Arc; @@ -110,22 +111,33 @@ impl Packages { } pub fn to_package_id_specs(&self, ws: &Workspace<'_>) -> CargoResult> { - let specs = match *self { + let specs = match self { Packages::All => ws .members() .map(Package::package_id) .map(PackageIdSpec::from_package_id) .collect(), - Packages::OptOut(ref opt_out) => ws - .members() - .map(Package::package_id) - .map(PackageIdSpec::from_package_id) - .filter(|p| opt_out.iter().position(|x| *x == p.name()).is_none()) - .collect(), - Packages::Packages(ref packages) if packages.is_empty() => { + Packages::OptOut(opt_out) => { + let mut opt_out = BTreeSet::from_iter(opt_out.iter().cloned()); + let packages = ws + .members() + .filter(|pkg| !opt_out.remove(pkg.name().as_str())) + .map(Package::package_id) + .map(PackageIdSpec::from_package_id) + .collect(); + if !opt_out.is_empty() { + ws.config().shell().warn(format!( + "excluded package(s) {} not found in workspace `{}`", + opt_out.iter().map(|x| x.as_ref()).collect::>().join(", "), + ws.root().display(), + ))?; + } + packages + }, + Packages::Packages(packages) if packages.is_empty() => { vec![PackageIdSpec::from_package_id(ws.current()?.package_id())] } - Packages::Packages(ref packages) => packages + Packages::Packages(packages) => packages .iter() .map(|p| PackageIdSpec::parse(p)) .collect::>>()?, @@ -152,11 +164,11 @@ impl Packages { let packages: Vec<_> = match self { Packages::Default => ws.default_members().collect(), Packages::All => ws.members().collect(), - Packages::OptOut(ref opt_out) => ws + Packages::OptOut(opt_out) => ws .members() .filter(|pkg| !opt_out.iter().any(|name| pkg.name().as_str() == name)) .collect(), - Packages::Packages(ref pkgs) => pkgs + Packages::Packages(packages) => packages .iter() .map(|name| { ws.members() diff --git a/tests/testsuite/check.rs b/tests/testsuite/check.rs index 390293d0f8e..06cd2c2fc27 100644 --- a/tests/testsuite/check.rs +++ b/tests/testsuite/check.rs @@ -427,6 +427,20 @@ fn check_virtual_all_implied() { .run(); } +#[test] +fn exclude_warns_on_non_existing_package() { + let p = project().file("src/lib.rs", "").build(); + p.cargo("check --all --exclude bar") + .with_stdout("") + .with_stderr( + r#"[WARNING] excluded package(s) bar not found in workspace `[CWD]` +[CHECKING] foo v0.0.1 ([CWD]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +"#, + ) + .run(); +} + #[test] fn targets_selected_default() { let foo = project()