use std::{cmp, fmt, hash};
+use std::collections::HashSet;
+
+use core::Shell;
+use core::interning::InternedString;
use ops::CompileMode;
+use util::CargoResult;
+use util::lev_distance::lev_distance;
use util::toml::{StringOrBool, TomlProfile, U32OrBool};
-use core::interning::InternedString;
/// Collection of all user profiles.
#[derive(Clone, Debug)]
self.dev.profile_for("", true, ProfileFor::Any)
}
}
+
+ /// Used to check for overrides for non-existing packages.
+ pub fn validate_packages(
+ &self,
+ shell: &mut Shell,
+ packages: &HashSet<&str>,
+ ) -> CargoResult<()> {
+ self.dev.validate_packages(shell, packages)?;
+ self.release.validate_packages(shell, packages)?;
+ self.test.validate_packages(shell, packages)?;
+ self.bench.validate_packages(shell, packages)?;
+ self.doc.validate_packages(shell, packages)?;
+ Ok(())
+ }
}
/// An object used for handling the profile override hierarchy.
}
profile
}
+
+ fn validate_packages(&self, shell: &mut Shell, packages: &HashSet<&str>) -> CargoResult<()> {
+ if let Some(ref toml) = self.toml {
+ if let Some(ref overrides) = toml.overrides {
+ for key in overrides.keys().filter(|k| k.as_str() != "*") {
+ if !packages.contains(key.as_str()) {
+ let suggestion = packages
+ .iter()
+ .map(|p| (lev_distance(key, p), p))
+ .filter(|&(d, _)| d < 4)
+ .min_by_key(|p| p.0)
+ .map(|p| p.1);
+ match suggestion {
+ Some(p) => shell.warn(format!(
+ "package `{}` for profile override not found\n\nDid you mean `{}`?",
+ key, p
+ ))?,
+ None => shell
+ .warn(format!("package `{}` for profile override not found", key))?,
+ };
+ }
+ }
+ }
+ }
+ Ok(())
+ }
}
fn merge_profile(profile: &mut Profile, toml: &TomlProfile) {
/// Returns true if the package is a member of the workspace.
pub fn is_member(&self, pkg: &Package) -> bool {
- // TODO: Implement this in a better way.
- // Maybe make it part of Package?
self.members().any(|p| p == pkg)
}
}
let profiles = ws.profiles();
+ let package_names = packages
+ .package_ids()
+ .map(|pid| pid.name().as_str())
+ .collect::<HashSet<_>>();
+ profiles.validate_packages(&mut config.shell(), &package_names)?;
+
let mut extra_compiler_args = None;
let units = generate_targets(
use std::env;
use cargotest::is_nightly;
-use cargotest::support::{execs, project};
+use cargotest::support::{basic_lib_manifest, execs, project};
use cargotest::ChannelChanger;
use hamcrest::assert_that;
"#,
)
.file("src/lib.rs", "")
- .file(
- "bar/Cargo.toml",
- r#"
- [package]
- name = "bar"
- version = "0.0.1"
- authors = []
- "#,
- )
+ .file("bar/Cargo.toml", &basic_lib_manifest("bar"))
.file("bar/src/lib.rs", "")
.build();
assert_that(
p.cargo("build -v").masquerade_as_nightly_cargo(),
execs().with_status(0).with_stderr(
-"[COMPILING] bar v0.0.1 ([..])
+"[COMPILING] bar [..]
[RUNNING] `rustc --crate-name bar [..] -C opt-level=3 [..]`
-[COMPILING] foo v0.0.1 ([..])
+[COMPILING] foo [..]
[RUNNING] `rustc --crate-name foo [..]`
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]",
)
// .with_stderr_does_not_contain("\
// `rustc --crate-name bar[..]-C opt-level=3"),
);
+}
+
+#[test]
+fn profile_override_bad_name() {
+ let p = project("foo")
+ .file(
+ "Cargo.toml",
+ r#"
+ cargo-features = ["profile-overrides"]
+
+ [package]
+ name = "foo"
+ version = "0.0.1"
+
+ [dependencies]
+ bar = {path = "bar"}
+
+ [profile.dev.overrides.bart]
+ opt-level = 3
+
+ [profile.dev.overrides.no-suggestion]
+ opt-level = 3
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .file("bar/Cargo.toml", &basic_lib_manifest("bar"))
+ .file("bar/src/lib.rs", "")
+ .build();
+
+ assert_that(
+ p.cargo("build").masquerade_as_nightly_cargo(),
+ execs().with_status(0).with_stderr_contains("\
+[WARNING] package `bart` for profile override not found
+Did you mean `bar`?
+[WARNING] package `no-suggestion` for profile override not found
+[COMPILING] [..]
+"));
}