Skip to content

Commit 1b42a21

Browse files
committed
Auto merge of #6039 - ehuss:fix-all-targets, r=alexcrichton
--all-targets fixes - Fix: `cargo test --all-targets` was running lib tests three times. - `--all-targets` help strings were wrong or misleading. - Minor cleanup to add `Proposal` type to maybe make the code more readable. Closes #5178.
2 parents 8201560 + 3a1cad6 commit 1b42a21

File tree

10 files changed

+77
-51
lines changed

10 files changed

+77
-51
lines changed

src/bin/cargo/commands/bench.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub fn cli() -> App {
2626
"Benchmark all tests",
2727
"Benchmark only the specified bench target",
2828
"Benchmark all benches",
29-
"Benchmark all targets (default)",
29+
"Benchmark all targets",
3030
)
3131
.arg(opt("no-run", "Compile, but don't run benchmarks"))
3232
.arg_package_spec(
@@ -78,7 +78,6 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
7878
let ops = TestOptions {
7979
no_run: args.is_present("no-run"),
8080
no_fail_fast: args.is_present("no-fail-fast"),
81-
only_doc: false,
8281
compile_opts,
8382
};
8483

src/bin/cargo/commands/build.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub fn cli() -> App {
2222
"Build all tests",
2323
"Build only the specified bench target",
2424
"Build all benches",
25-
"Build all targets (lib and bin targets by default)",
25+
"Build all targets",
2626
)
2727
.arg_release("Build artifacts in release mode, with optimizations")
2828
.arg_features()

src/bin/cargo/commands/check.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub fn cli() -> App {
2121
"Check all tests",
2222
"Check only the specified bench target",
2323
"Check all benches",
24-
"Check all targets (lib and bin targets by default)",
24+
"Check all targets",
2525
)
2626
.arg_release("Check artifacts in release mode, with optimizations")
2727
.arg(opt("profile", "Profile to build the selected target for").value_name("PROFILE"))

src/bin/cargo/commands/fix.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub fn cli() -> App {
2121
"Fix all tests",
2222
"Fix only the specified bench target",
2323
"Fix all benches",
24-
"Fix all targets (lib and bin targets by default)",
24+
"Fix all targets (default)",
2525
)
2626
.arg_release("Fix artifacts in release mode, with optimizations")
2727
.arg(opt("profile", "Profile to build the selected target for").value_name("PROFILE"))

src/bin/cargo/commands/rustc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub fn cli() -> App {
1919
"Build all tests",
2020
"Build only the specified bench target",
2121
"Build all benches",
22-
"Build all targets (lib and bin targets by default)",
22+
"Build all targets",
2323
)
2424
.arg_release("Build artifacts in release mode, with optimizations")
2525
.arg(opt("profile", "Profile to build the selected target for").value_name("PROFILE"))

src/bin/cargo/commands/rustdoc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub fn cli() -> App {
2323
"Build all tests",
2424
"Build only the specified bench target",
2525
"Build all benches",
26-
"Build all targets (default)",
26+
"Build all targets",
2727
)
2828
.arg_release("Build artifacts in release mode, with optimizations")
2929
.arg_features()

src/bin/cargo/commands/test.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ pub fn cli() -> App {
2727
"Test all tests",
2828
"Test only the specified bench target",
2929
"Test all benches",
30-
"Test all targets (default)",
30+
"Test all targets",
3131
)
3232
.arg(opt("doc", "Test only this library's documentation"))
3333
.arg(opt("no-run", "Compile, but don't run tests"))
@@ -116,7 +116,6 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
116116
let ops = ops::TestOptions {
117117
no_run: args.is_present("no-run"),
118118
no_fail_fast: args.is_present("no-fail-fast"),
119-
only_doc: doc,
120119
compile_opts,
121120
};
122121

src/cargo/ops/cargo_compile.rs

Lines changed: 55 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,22 @@ impl CompileFilter {
444444
}
445445
}
446446

447+
/// A proposed target.
448+
///
449+
/// Proposed targets are later filtered into actual Units based on whether or
450+
/// not the target requires its features to be present.
451+
#[derive(Debug)]
452+
struct Proposal<'a> {
453+
pkg: &'a Package,
454+
target: &'a Target,
455+
/// Indicates whether or not all required features *must* be present. If
456+
/// false, and the features are not available, then it will be silently
457+
/// skipped. Generally, targets specified by name (`--bin foo`) are
458+
/// required, all others can be silently skipped if features are missing.
459+
requires_features: bool,
460+
mode: CompileMode,
461+
}
462+
447463
/// Generates all the base targets for the packages the user has requested to
448464
/// compile. Dependencies for these targets are computed later in
449465
/// `unit_dependencies`.
@@ -531,36 +547,33 @@ fn generate_targets<'a>(
531547
}
532548
};
533549

534-
// Create a list of proposed targets. The `bool` value indicates
535-
// whether or not all required features *must* be present. If false,
536-
// and the features are not available, then it will be silently
537-
// skipped. Generally, targets specified by name (`--bin foo`) are
538-
// required, all others can be silently skipped if features are
539-
// missing.
540-
let mut proposals: Vec<(&Package, &Target, bool, CompileMode)> = Vec::new();
550+
// Create a list of proposed targets.
551+
let mut proposals: Vec<Proposal> = Vec::new();
541552

542553
match *filter {
543554
CompileFilter::Default {
544555
required_features_filterable,
545556
} => {
546557
for pkg in packages {
547558
let default = filter_default_targets(pkg.targets(), build_config.mode);
548-
proposals.extend(default.into_iter().map(|target| {
549-
(
550-
*pkg,
551-
target,
552-
!required_features_filterable,
553-
build_config.mode,
554-
)
559+
proposals.extend(default.into_iter().map(|target| Proposal {
560+
pkg,
561+
target,
562+
requires_features: !required_features_filterable,
563+
mode: build_config.mode,
555564
}));
556565
if build_config.mode == CompileMode::Test {
557-
// Include doctest for lib.
558566
if let Some(t) = pkg
559567
.targets()
560568
.iter()
561569
.find(|t| t.is_lib() && t.doctested() && t.doctestable())
562570
{
563-
proposals.push((pkg, t, false, CompileMode::Doctest));
571+
proposals.push(Proposal {
572+
pkg,
573+
target: t,
574+
requires_features: false,
575+
mode: CompileMode::Doctest,
576+
});
564577
}
565578
}
566579
}
@@ -586,7 +599,12 @@ fn generate_targets<'a>(
586599
pkg.name()
587600
))?;
588601
} else {
589-
libs.push((*pkg, target, false, build_config.mode));
602+
libs.push(Proposal {
603+
pkg,
604+
target,
605+
requires_features: false,
606+
mode: build_config.mode,
607+
});
590608
}
591609
}
592610
}
@@ -600,6 +618,7 @@ fn generate_targets<'a>(
600618
}
601619
proposals.extend(libs);
602620
}
621+
603622
// If --tests was specified, add all targets that would be
604623
// generated by `cargo test`.
605624
let test_filter = match *tests {
@@ -657,8 +676,8 @@ fn generate_targets<'a>(
657676
// Only include targets that are libraries or have all required
658677
// features available.
659678
let mut features_map = HashMap::new();
660-
let mut units = Vec::new();
661-
for (pkg, target, required, mode) in proposals {
679+
let mut units = HashSet::new();
680+
for Proposal { pkg, target, requires_features, mode} in proposals {
662681
let unavailable_features = match target.required_features() {
663682
Some(rf) => {
664683
let features = features_map
@@ -670,8 +689,8 @@ fn generate_targets<'a>(
670689
};
671690
if target.is_lib() || unavailable_features.is_empty() {
672691
let unit = new_unit(pkg, target, mode);
673-
units.push(unit);
674-
} else if required {
692+
units.insert(unit);
693+
} else if requires_features {
675694
let required_features = target.required_features().unwrap();
676695
let quoted_required_features: Vec<String> = required_features
677696
.iter()
@@ -688,7 +707,7 @@ fn generate_targets<'a>(
688707
}
689708
// else, silently skip target.
690709
}
691-
Ok(units)
710+
Ok(units.into_iter().collect())
692711
}
693712

694713
fn resolve_all_features(
@@ -746,14 +765,19 @@ fn list_rule_targets<'a>(
746765
target_desc: &'static str,
747766
is_expected_kind: fn(&Target) -> bool,
748767
mode: CompileMode,
749-
) -> CargoResult<Vec<(&'a Package, &'a Target, bool, CompileMode)>> {
768+
) -> CargoResult<Vec<Proposal<'a>>> {
750769
let mut result = Vec::new();
751770
match *rule {
752771
FilterRule::All => {
753772
for pkg in packages {
754773
for target in pkg.targets() {
755774
if is_expected_kind(target) {
756-
result.push((*pkg, target, false, mode));
775+
result.push(Proposal {
776+
pkg,
777+
target,
778+
requires_features: false,
779+
mode,
780+
});
757781
}
758782
}
759783
}
@@ -780,12 +804,17 @@ fn find_named_targets<'a>(
780804
target_desc: &'static str,
781805
is_expected_kind: fn(&Target) -> bool,
782806
mode: CompileMode,
783-
) -> CargoResult<Vec<(&'a Package, &'a Target, bool, CompileMode)>> {
807+
) -> CargoResult<Vec<Proposal<'a>>> {
784808
let mut result = Vec::new();
785809
for pkg in packages {
786810
for target in pkg.targets() {
787811
if target.name() == target_name && is_expected_kind(target) {
788-
result.push((*pkg, target, true, mode));
812+
result.push(Proposal {
813+
pkg,
814+
target,
815+
requires_features: true,
816+
mode,
817+
});
789818
}
790819
}
791820
}

src/cargo/ops/cargo_test.rs

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ pub struct TestOptions<'a> {
1010
pub compile_opts: ops::CompileOptions<'a>,
1111
pub no_run: bool,
1212
pub no_fail_fast: bool,
13-
pub only_doc: bool,
1413
}
1514

1615
pub fn run_tests(
@@ -23,27 +22,13 @@ pub fn run_tests(
2322
if options.no_run {
2423
return Ok(None);
2524
}
26-
let (test, mut errors) = if options.only_doc {
27-
assert!(options.compile_opts.filter.is_specific());
28-
run_doc_tests(options, test_args, &compilation)?
29-
} else {
30-
run_unit_tests(options, test_args, &compilation)?
31-
};
25+
let (test, mut errors) = run_unit_tests(options, test_args, &compilation)?;
3226

3327
// If we have an error and want to fail fast, return
3428
if !errors.is_empty() && !options.no_fail_fast {
3529
return Ok(Some(CargoTestError::new(test, errors)));
3630
}
3731

38-
// If a specific test was requested or we're not running any tests at all,
39-
// don't run any doc tests.
40-
if options.compile_opts.filter.is_specific() {
41-
match errors.len() {
42-
0 => return Ok(None),
43-
_ => return Ok(Some(CargoTestError::new(test, errors))),
44-
}
45-
}
46-
4732
let (doctest, docerrors) = run_doc_tests(options, test_args, &compilation)?;
4833
let test = if docerrors.is_empty() { test } else { doctest };
4934
errors.extend(docerrors);

tests/testsuite/test.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3168,3 +3168,17 @@ test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
31683168
.with_stderr("[ERROR] Can't mix --doc with other target selecting options\n")
31693169
.run();
31703170
}
3171+
3172+
#[test]
3173+
fn test_all_targets_lib() {
3174+
let p = project().file("src/lib.rs", "").build();
3175+
3176+
p.cargo("test --all-targets")
3177+
.with_stderr(
3178+
"\
3179+
[COMPILING] foo [..]
3180+
[FINISHED] dev [..]
3181+
[RUNNING] [..]foo[..]
3182+
",
3183+
).run();
3184+
}

0 commit comments

Comments
 (0)