mirror of
https://github.com/rust-lang/cargo
synced 2024-10-14 03:32:39 +00:00
Auto merge of #5873 - ehuss:ws-filters, r=alexcrichton
Change target filters in workspaces. This changes it so that filters like `--bin`, `--test`, `--example`, `--bench`, `--lib` will work in a workspace. Today, these filters require that they match *every* package in a workspace which makes them not very useful. This change makes it so that they only must match at least one package. Closes #5819.
This commit is contained in:
commit
ebaf2125d1
|
@ -22,7 +22,7 @@
|
|||
//! previously compiled dependency
|
||||
//!
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -398,7 +398,7 @@ impl CompileFilter {
|
|||
}
|
||||
|
||||
// this selects targets for "cargo run". for logic to select targets for
|
||||
// other subcommands, see generate_targets and generate_default_targets
|
||||
// other subcommands, see generate_targets and filter_default_targets
|
||||
pub fn target_run(&self, target: &Target) -> bool {
|
||||
match *self {
|
||||
CompileFilter::Default { .. } => true,
|
||||
|
@ -443,8 +443,6 @@ fn generate_targets<'a>(
|
|||
resolve: &Resolve,
|
||||
build_config: &BuildConfig,
|
||||
) -> CargoResult<Vec<Unit<'a>>> {
|
||||
let mut units = Vec::new();
|
||||
|
||||
// Helper for creating a Unit struct.
|
||||
let new_unit = |pkg: &'a Package, target: &'a Target, target_mode: CompileMode| {
|
||||
let profile_for = if build_config.mode.is_any_test() {
|
||||
|
@ -520,30 +518,28 @@ fn generate_targets<'a>(
|
|||
}
|
||||
};
|
||||
|
||||
for pkg in packages {
|
||||
let features = resolve_all_features(resolve, pkg.package_id());
|
||||
// Create a list of proposed targets. The `bool` value indicates
|
||||
// whether or not all required features *must* be present. If false,
|
||||
// and the features are not available, then it will be silently
|
||||
// skipped. Generally, targets specified by name (`--bin foo`) are
|
||||
// required, all others can be silently skipped if features are
|
||||
// missing.
|
||||
let mut proposals: Vec<(Unit<'a>, bool)> = Vec::new();
|
||||
// Create a list of proposed targets. The `bool` value indicates
|
||||
// whether or not all required features *must* be present. If false,
|
||||
// and the features are not available, then it will be silently
|
||||
// skipped. Generally, targets specified by name (`--bin foo`) are
|
||||
// required, all others can be silently skipped if features are
|
||||
// missing.
|
||||
let mut proposals: Vec<(&Package, &Target, bool, CompileMode)> = Vec::new();
|
||||
|
||||
match *filter {
|
||||
CompileFilter::Default {
|
||||
required_features_filterable,
|
||||
} => {
|
||||
let default_units = generate_default_targets(pkg.targets(), build_config.mode)
|
||||
.iter()
|
||||
.map(|t| {
|
||||
(
|
||||
new_unit(pkg, t, build_config.mode),
|
||||
!required_features_filterable,
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
proposals.extend(default_units);
|
||||
match *filter {
|
||||
CompileFilter::Default {
|
||||
required_features_filterable,
|
||||
} => {
|
||||
for pkg in packages {
|
||||
let default = filter_default_targets(pkg.targets(), build_config.mode);
|
||||
proposals.extend(default.into_iter().map(|target| {
|
||||
(
|
||||
*pkg,
|
||||
target,
|
||||
!required_features_filterable,
|
||||
build_config.mode,
|
||||
)
|
||||
}));
|
||||
if build_config.mode == CompileMode::Test {
|
||||
// Include doctest for lib.
|
||||
if let Some(t) = pkg
|
||||
|
@ -551,107 +547,134 @@ fn generate_targets<'a>(
|
|||
.iter()
|
||||
.find(|t| t.is_lib() && t.doctested() && t.doctestable())
|
||||
{
|
||||
proposals.push((new_unit(pkg, t, CompileMode::Doctest), false));
|
||||
proposals.push((pkg, t, false, CompileMode::Doctest));
|
||||
}
|
||||
}
|
||||
}
|
||||
CompileFilter::Only {
|
||||
all_targets,
|
||||
lib,
|
||||
ref bins,
|
||||
ref examples,
|
||||
ref tests,
|
||||
ref benches,
|
||||
} => {
|
||||
if lib {
|
||||
if let Some(target) = pkg.targets().iter().find(|t| t.is_lib()) {
|
||||
}
|
||||
CompileFilter::Only {
|
||||
all_targets,
|
||||
lib,
|
||||
ref bins,
|
||||
ref examples,
|
||||
ref tests,
|
||||
ref benches,
|
||||
} => {
|
||||
if lib {
|
||||
let mut libs = Vec::new();
|
||||
for pkg in packages {
|
||||
for target in pkg.targets().iter().filter(|t| t.is_lib()) {
|
||||
if build_config.mode == CompileMode::Doctest && !target.doctestable() {
|
||||
bail!(
|
||||
ws.config()
|
||||
.shell()
|
||||
.warn(format!(
|
||||
"doc tests are not supported for crate type(s) `{}` in package `{}`",
|
||||
target.rustc_crate_types().join(", "),
|
||||
pkg.name()
|
||||
);
|
||||
))?;
|
||||
} else {
|
||||
libs.push((*pkg, target, false, build_config.mode));
|
||||
}
|
||||
proposals.push((new_unit(pkg, target, build_config.mode), false));
|
||||
} else if !all_targets {
|
||||
bail!("no library targets found in package `{}`", pkg.name())
|
||||
}
|
||||
}
|
||||
// If --tests was specified, add all targets that would be
|
||||
// generated by `cargo test`.
|
||||
let test_filter = match *tests {
|
||||
FilterRule::All => Target::tested,
|
||||
FilterRule::Just(_) => Target::is_test,
|
||||
};
|
||||
let test_mode = match build_config.mode {
|
||||
CompileMode::Build => CompileMode::Test,
|
||||
CompileMode::Check { .. } => CompileMode::Check { test: true },
|
||||
_ => build_config.mode,
|
||||
};
|
||||
// If --benches was specified, add all targets that would be
|
||||
// generated by `cargo bench`.
|
||||
let bench_filter = match *benches {
|
||||
FilterRule::All => Target::benched,
|
||||
FilterRule::Just(_) => Target::is_bench,
|
||||
};
|
||||
let bench_mode = match build_config.mode {
|
||||
CompileMode::Build => CompileMode::Bench,
|
||||
CompileMode::Check { .. } => CompileMode::Check { test: true },
|
||||
_ => build_config.mode,
|
||||
};
|
||||
|
||||
proposals.extend(
|
||||
list_rule_targets(pkg, bins, "bin", Target::is_bin)?
|
||||
.into_iter()
|
||||
.map(|(t, required)| (new_unit(pkg, t, build_config.mode), required))
|
||||
.chain(
|
||||
list_rule_targets(pkg, examples, "example", Target::is_example)?
|
||||
.into_iter()
|
||||
.map(|(t, required)| {
|
||||
(new_unit(pkg, t, build_config.mode), required)
|
||||
}),
|
||||
)
|
||||
.chain(
|
||||
list_rule_targets(pkg, tests, "test", test_filter)?
|
||||
.into_iter()
|
||||
.map(|(t, required)| (new_unit(pkg, t, test_mode), required)),
|
||||
)
|
||||
.chain(
|
||||
list_rule_targets(pkg, benches, "bench", bench_filter)?
|
||||
.into_iter()
|
||||
.map(|(t, required)| (new_unit(pkg, t, bench_mode), required)),
|
||||
)
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
if !all_targets && libs.is_empty() {
|
||||
let names = packages.iter().map(|pkg| pkg.name()).collect::<Vec<_>>();
|
||||
if names.len() == 1 {
|
||||
bail!("no library targets found in package `{}`", names[0]);
|
||||
} else {
|
||||
bail!("no library targets found in packages: {}", names.join(", "));
|
||||
}
|
||||
}
|
||||
proposals.extend(libs);
|
||||
}
|
||||
}
|
||||
|
||||
// Only include targets that are libraries or have all required
|
||||
// features available.
|
||||
for (unit, required) in proposals {
|
||||
let unavailable_features = match unit.target.required_features() {
|
||||
Some(rf) => rf.iter().filter(|f| !features.contains(*f)).collect(),
|
||||
None => Vec::new(),
|
||||
// If --tests was specified, add all targets that would be
|
||||
// generated by `cargo test`.
|
||||
let test_filter = match *tests {
|
||||
FilterRule::All => Target::tested,
|
||||
FilterRule::Just(_) => Target::is_test,
|
||||
};
|
||||
if unit.target.is_lib() || unavailable_features.is_empty() {
|
||||
units.push(unit);
|
||||
} else if required {
|
||||
let required_features = unit.target.required_features().unwrap();
|
||||
let quoted_required_features: Vec<String> = required_features
|
||||
.iter()
|
||||
.map(|s| format!("`{}`", s))
|
||||
.collect();
|
||||
bail!(
|
||||
"target `{}` requires the features: {}\n\
|
||||
Consider enabling them by passing e.g. `--features=\"{}\"`",
|
||||
unit.target.name(),
|
||||
quoted_required_features.join(", "),
|
||||
required_features.join(" ")
|
||||
);
|
||||
}
|
||||
// else, silently skip target.
|
||||
let test_mode = match build_config.mode {
|
||||
CompileMode::Build => CompileMode::Test,
|
||||
CompileMode::Check { .. } => CompileMode::Check { test: true },
|
||||
_ => build_config.mode,
|
||||
};
|
||||
// If --benches was specified, add all targets that would be
|
||||
// generated by `cargo bench`.
|
||||
let bench_filter = match *benches {
|
||||
FilterRule::All => Target::benched,
|
||||
FilterRule::Just(_) => Target::is_bench,
|
||||
};
|
||||
let bench_mode = match build_config.mode {
|
||||
CompileMode::Build => CompileMode::Bench,
|
||||
CompileMode::Check { .. } => CompileMode::Check { test: true },
|
||||
_ => build_config.mode,
|
||||
};
|
||||
|
||||
proposals.extend(list_rule_targets(
|
||||
packages,
|
||||
bins,
|
||||
"bin",
|
||||
Target::is_bin,
|
||||
build_config.mode,
|
||||
)?);
|
||||
proposals.extend(list_rule_targets(
|
||||
packages,
|
||||
examples,
|
||||
"example",
|
||||
Target::is_example,
|
||||
build_config.mode,
|
||||
)?);
|
||||
proposals.extend(list_rule_targets(
|
||||
packages,
|
||||
tests,
|
||||
"test",
|
||||
test_filter,
|
||||
test_mode,
|
||||
)?);
|
||||
proposals.extend(list_rule_targets(
|
||||
packages,
|
||||
benches,
|
||||
"bench",
|
||||
bench_filter,
|
||||
bench_mode,
|
||||
)?);
|
||||
}
|
||||
}
|
||||
|
||||
// Only include targets that are libraries or have all required
|
||||
// features available.
|
||||
let mut features_map = HashMap::new();
|
||||
let mut units = Vec::new();
|
||||
for (pkg, target, required, mode) in proposals {
|
||||
let unavailable_features = match target.required_features() {
|
||||
Some(rf) => {
|
||||
let features = features_map
|
||||
.entry(pkg)
|
||||
.or_insert_with(|| resolve_all_features(resolve, pkg.package_id()));
|
||||
rf.iter().filter(|f| !features.contains(*f)).collect()
|
||||
}
|
||||
None => Vec::new(),
|
||||
};
|
||||
if target.is_lib() || unavailable_features.is_empty() {
|
||||
let unit = new_unit(pkg, target, mode);
|
||||
units.push(unit);
|
||||
} else if required {
|
||||
let required_features = target.required_features().unwrap();
|
||||
let quoted_required_features: Vec<String> = required_features
|
||||
.iter()
|
||||
.map(|s| format!("`{}`", s))
|
||||
.collect();
|
||||
bail!(
|
||||
"target `{}` in package `{}` requires the features: {}\n\
|
||||
Consider enabling them by passing e.g. `--features=\"{}\"`",
|
||||
target.name(),
|
||||
pkg.name(),
|
||||
quoted_required_features.join(", "),
|
||||
required_features.join(" ")
|
||||
);
|
||||
}
|
||||
// else, silently skip target.
|
||||
}
|
||||
Ok(units)
|
||||
}
|
||||
|
||||
|
@ -674,7 +697,7 @@ fn resolve_all_features(
|
|||
|
||||
/// Given a list of all targets for a package, filters out only the targets
|
||||
/// that are automatically included when the user doesn't specify any targets.
|
||||
fn generate_default_targets(targets: &[Target], mode: CompileMode) -> Vec<&Target> {
|
||||
fn filter_default_targets(targets: &[Target], mode: CompileMode) -> Vec<&Target> {
|
||||
match mode {
|
||||
CompileMode::Bench => targets.iter().filter(|t| t.benched()).collect(),
|
||||
CompileMode::Test => targets
|
||||
|
@ -701,58 +724,78 @@ fn generate_default_targets(targets: &[Target], mode: CompileMode) -> Vec<&Targe
|
|||
}
|
||||
|
||||
/// Returns a list of targets based on command-line target selection flags.
|
||||
/// The return value is a list of `(Target, bool)` pairs. The `bool` value
|
||||
/// indicates whether or not all required features *must* be present.
|
||||
/// The return value is a list of `(Package, Target, bool, CompileMode)`
|
||||
/// tuples. The `bool` value indicates whether or not all required features
|
||||
/// *must* be present.
|
||||
fn list_rule_targets<'a>(
|
||||
pkg: &'a Package,
|
||||
packages: &[&'a Package],
|
||||
rule: &FilterRule,
|
||||
target_desc: &'static str,
|
||||
is_expected_kind: fn(&Target) -> bool,
|
||||
) -> CargoResult<Vec<(&'a Target, bool)>> {
|
||||
mode: CompileMode,
|
||||
) -> CargoResult<Vec<(&'a Package, &'a Target, bool, CompileMode)>> {
|
||||
let mut result = Vec::new();
|
||||
match *rule {
|
||||
FilterRule::All => Ok(pkg.targets()
|
||||
.iter()
|
||||
.filter(|t| is_expected_kind(t))
|
||||
.map(|t| (t, false))
|
||||
.collect()),
|
||||
FilterRule::Just(ref names) => names
|
||||
.iter()
|
||||
.map(|name| find_target(pkg, name, target_desc, is_expected_kind))
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Find the target for a specifically named target.
|
||||
fn find_target<'a>(
|
||||
pkg: &'a Package,
|
||||
target_name: &str,
|
||||
target_desc: &'static str,
|
||||
is_expected_kind: fn(&Target) -> bool,
|
||||
) -> CargoResult<(&'a Target, bool)> {
|
||||
match pkg.targets()
|
||||
.iter()
|
||||
.find(|t| t.name() == target_name && is_expected_kind(t))
|
||||
{
|
||||
// When a target is specified by name, required features *must* be
|
||||
// available.
|
||||
Some(t) => Ok((t, true)),
|
||||
None => {
|
||||
let suggestion = pkg.targets()
|
||||
.iter()
|
||||
.filter(|t| is_expected_kind(t))
|
||||
.map(|t| (lev_distance(target_name, t.name()), t))
|
||||
.filter(|&(d, _)| d < 4)
|
||||
.min_by_key(|t| t.0)
|
||||
.map(|t| t.1);
|
||||
match suggestion {
|
||||
Some(s) => bail!(
|
||||
"no {} target named `{}`\n\nDid you mean `{}`?",
|
||||
FilterRule::All => {
|
||||
for pkg in packages {
|
||||
for target in pkg.targets() {
|
||||
if is_expected_kind(target) {
|
||||
result.push((*pkg, target, false, mode));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
FilterRule::Just(ref names) => {
|
||||
for name in names {
|
||||
result.extend(find_named_targets(
|
||||
packages,
|
||||
name,
|
||||
target_desc,
|
||||
target_name,
|
||||
s.name()
|
||||
),
|
||||
None => bail!("no {} target named `{}`", target_desc, target_name),
|
||||
is_expected_kind,
|
||||
mode,
|
||||
)?);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Find the targets for a specifically named target.
|
||||
fn find_named_targets<'a>(
|
||||
packages: &[&'a Package],
|
||||
target_name: &str,
|
||||
target_desc: &'static str,
|
||||
is_expected_kind: fn(&Target) -> bool,
|
||||
mode: CompileMode,
|
||||
) -> CargoResult<Vec<(&'a Package, &'a Target, bool, CompileMode)>> {
|
||||
let mut result = Vec::new();
|
||||
for pkg in packages {
|
||||
for target in pkg.targets() {
|
||||
if target.name() == target_name && is_expected_kind(target) {
|
||||
result.push((*pkg, target, true, mode));
|
||||
}
|
||||
}
|
||||
}
|
||||
if result.is_empty() {
|
||||
let suggestion = packages
|
||||
.iter()
|
||||
.flat_map(|pkg| {
|
||||
pkg.targets()
|
||||
.iter()
|
||||
.filter(|target| is_expected_kind(target))
|
||||
}).map(|target| (lev_distance(target_name, target.name()), target))
|
||||
.filter(|&(d, _)| d < 4)
|
||||
.min_by_key(|t| t.0)
|
||||
.map(|t| t.1);
|
||||
match suggestion {
|
||||
Some(s) => bail!(
|
||||
"no {} target named `{}`\n\nDid you mean `{}`?",
|
||||
target_desc,
|
||||
target_name,
|
||||
s.name()
|
||||
),
|
||||
None => bail!("no {} target named `{}`", target_desc, target_name),
|
||||
}
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
|
|
|
@ -4798,3 +4798,71 @@ fn invalid_jobs() {
|
|||
.with_stderr("error: Invalid value: could not parse `over9000` as a number"),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn target_filters_workspace() {
|
||||
let ws = project()
|
||||
.at("ws")
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
[workspace]
|
||||
members = ["a", "b"]
|
||||
"#,
|
||||
).file("a/Cargo.toml", &basic_lib_manifest("a"))
|
||||
.file("a/src/lib.rs", "")
|
||||
.file("a/examples/ex1.rs", "fn main() {}")
|
||||
.file("b/Cargo.toml", &basic_bin_manifest("b"))
|
||||
.file("b/src/main.rs", "fn main() {}")
|
||||
.file("b/examples/ex1.rs", "fn main() {}")
|
||||
.build();
|
||||
|
||||
assert_that(
|
||||
ws.cargo("build -v --example ex"),
|
||||
execs().with_status(101).with_stderr(
|
||||
"\
|
||||
[ERROR] no example target named `ex`
|
||||
|
||||
Did you mean `ex1`?",
|
||||
),
|
||||
);
|
||||
|
||||
assert_that(
|
||||
ws.cargo("build -v --lib"),
|
||||
execs()
|
||||
.with_status(0)
|
||||
.with_stderr_contains("[RUNNING] `rustc [..]a/src/lib.rs[..]"),
|
||||
);
|
||||
|
||||
assert_that(
|
||||
ws.cargo("build -v --example ex1"),
|
||||
execs()
|
||||
.with_status(0)
|
||||
.with_stderr_contains("[RUNNING] `rustc [..]a/examples/ex1.rs[..]")
|
||||
.with_stderr_contains("[RUNNING] `rustc [..]b/examples/ex1.rs[..]"),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn target_filters_workspace_not_found() {
|
||||
let ws = project()
|
||||
.at("ws")
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
[workspace]
|
||||
members = ["a", "b"]
|
||||
"#,
|
||||
).file("a/Cargo.toml", &basic_bin_manifest("a"))
|
||||
.file("a/src/main.rs", "fn main() {}")
|
||||
.file("b/Cargo.toml", &basic_bin_manifest("b"))
|
||||
.file("b/src/main.rs", "fn main() {}")
|
||||
.build();
|
||||
|
||||
assert_that(
|
||||
ws.cargo("build -v --lib"),
|
||||
execs().with_status(101).with_stderr(
|
||||
"[ERROR] no library targets found in packages: a, b",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ fn build_bin_default_features() {
|
|||
.arg("--no-default-features"),
|
||||
execs().with_status(101).with_stderr(
|
||||
"\
|
||||
error: target `foo` requires the features: `a`
|
||||
error: target `foo` in package `foo` requires the features: `a`
|
||||
Consider enabling them by passing e.g. `--features=\"a\"`
|
||||
",
|
||||
),
|
||||
|
@ -178,7 +178,7 @@ fn build_example_default_features() {
|
|||
.arg("--no-default-features"),
|
||||
execs().with_status(101).with_stderr(
|
||||
"\
|
||||
error: target `foo` requires the features: `a`
|
||||
error: target `foo` in package `foo` requires the features: `a`
|
||||
Consider enabling them by passing e.g. `--features=\"a\"`
|
||||
",
|
||||
),
|
||||
|
@ -251,7 +251,7 @@ fn build_example_multiple_required_features() {
|
|||
p.cargo("build").arg("--example=foo_1"),
|
||||
execs().with_status(101).with_stderr(
|
||||
"\
|
||||
error: target `foo_1` requires the features: `b`, `c`
|
||||
error: target `foo_1` in package `foo` requires the features: `b`, `c`
|
||||
Consider enabling them by passing e.g. `--features=\"b c\"`
|
||||
",
|
||||
),
|
||||
|
@ -288,7 +288,7 @@ Consider enabling them by passing e.g. `--features=\"b c\"`
|
|||
.arg("--no-default-features"),
|
||||
execs().with_status(101).with_stderr(
|
||||
"\
|
||||
error: target `foo_1` requires the features: `b`, `c`
|
||||
error: target `foo_1` in package `foo` requires the features: `b`, `c`
|
||||
Consider enabling them by passing e.g. `--features=\"b c\"`
|
||||
",
|
||||
),
|
||||
|
@ -299,7 +299,7 @@ Consider enabling them by passing e.g. `--features=\"b c\"`
|
|||
.arg("--no-default-features"),
|
||||
execs().with_status(101).with_stderr(
|
||||
"\
|
||||
error: target `foo_2` requires the features: `a`
|
||||
error: target `foo_2` in package `foo` requires the features: `a`
|
||||
Consider enabling them by passing e.g. `--features=\"a\"`
|
||||
",
|
||||
),
|
||||
|
@ -368,7 +368,7 @@ fn test_default_features() {
|
|||
.arg("--no-default-features"),
|
||||
execs().with_status(101).with_stderr(
|
||||
"\
|
||||
error: target `foo` requires the features: `a`
|
||||
error: target `foo` in package `foo` requires the features: `a`
|
||||
Consider enabling them by passing e.g. `--features=\"a\"`
|
||||
",
|
||||
),
|
||||
|
@ -551,7 +551,7 @@ fn bench_default_features() {
|
|||
.arg("--no-default-features"),
|
||||
execs().with_status(101).with_stderr(
|
||||
"\
|
||||
error: target `foo` requires the features: `a`
|
||||
error: target `foo` in package `foo` requires the features: `a`
|
||||
Consider enabling them by passing e.g. `--features=\"a\"`
|
||||
",
|
||||
),
|
||||
|
@ -756,7 +756,7 @@ fn install_default_features() {
|
|||
`[..]target`
|
||||
|
||||
Caused by:
|
||||
target `foo` requires the features: `a`
|
||||
target `foo` in package `foo` requires the features: `a`
|
||||
Consider enabling them by passing e.g. `--features=\"a\"`
|
||||
"
|
||||
)),
|
||||
|
@ -781,7 +781,7 @@ Consider enabling them by passing e.g. `--features=\"a\"`
|
|||
`[..]target`
|
||||
|
||||
Caused by:
|
||||
target `foo` requires the features: `a`
|
||||
target `foo` in package `foo` requires the features: `a`
|
||||
Consider enabling them by passing e.g. `--features=\"a\"`
|
||||
"
|
||||
)),
|
||||
|
@ -1053,7 +1053,7 @@ fn dep_feature_in_cmd_line() {
|
|||
p.cargo("build").arg("--bin=foo"),
|
||||
execs().with_status(101).with_stderr(
|
||||
"\
|
||||
error: target `foo` requires the features: `bar/a`
|
||||
error: target `foo` in package `foo` requires the features: `bar/a`
|
||||
Consider enabling them by passing e.g. `--features=\"bar/a\"`
|
||||
",
|
||||
),
|
||||
|
@ -1073,7 +1073,7 @@ Consider enabling them by passing e.g. `--features=\"bar/a\"`
|
|||
p.cargo("build").arg("--example=foo"),
|
||||
execs().with_status(101).with_stderr(
|
||||
"\
|
||||
error: target `foo` requires the features: `bar/a`
|
||||
error: target `foo` in package `foo` requires the features: `bar/a`
|
||||
Consider enabling them by passing e.g. `--features=\"bar/a\"`
|
||||
",
|
||||
),
|
||||
|
@ -1272,7 +1272,7 @@ fn run_default() {
|
|||
p.cargo("run"),
|
||||
execs().with_status(101).with_stderr(
|
||||
"\
|
||||
error: target `foo` requires the features: `a`
|
||||
error: target `foo` in package `foo` requires the features: `a`
|
||||
Consider enabling them by passing e.g. `--features=\"a\"`
|
||||
",
|
||||
),
|
||||
|
|
|
@ -3533,7 +3533,9 @@ fn doctest_skip_staticlib() {
|
|||
assert_that(
|
||||
p.cargo("test --doc"),
|
||||
execs().with_status(101).with_stderr(
|
||||
"[ERROR] doc tests are not supported for crate type(s) `staticlib` in package `foo`",
|
||||
"\
|
||||
[WARNING] doc tests are not supported for crate type(s) `staticlib` in package `foo`
|
||||
[ERROR] no library targets found in package `foo`",
|
||||
),
|
||||
);
|
||||
|
||||
|
|
Loading…
Reference in a new issue