Skip to content

Commit 5eb9072

Browse files
committed
Auto merge of #3490 - alexcrichton:dev-dep-doc-test, r=brson
Fix cargo test --doc with dev-deps Previously Cargo accidentally didn't pull in dev-dependencies due to the way `cargo test --doc` was interpreted in terms of top-level targets. This PR special cases this situation by ensuring that the doctest intention makes its way all to the backend and the dependencies can be correctly calculated. Closes #3422
2 parents 4b351ea + fb1736e commit 5eb9072

File tree

10 files changed

+69
-7
lines changed

10 files changed

+69
-7
lines changed

src/bin/test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
105105
let empty = Vec::new();
106106
let (mode, filter);
107107
if options.flag_doc {
108-
mode = ops::CompileMode::Build;
108+
mode = ops::CompileMode::Doctest;
109109
filter = ops::CompileFilter::new(true, &empty, &empty, &empty, &empty);
110110
} else {
111111
mode = ops::CompileMode::Test;

src/cargo/core/manifest.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ pub struct Profiles {
170170
pub doc: Profile,
171171
pub custom_build: Profile,
172172
pub check: Profile,
173+
pub doctest: Profile,
173174
}
174175

175176
/// Information about a binary, a library, an example, etc. that is part of the
@@ -535,6 +536,14 @@ impl Profile {
535536
..Profile::default_dev()
536537
}
537538
}
539+
540+
pub fn default_doctest() -> Profile {
541+
Profile {
542+
doc: true,
543+
test: true,
544+
..Profile::default_dev()
545+
}
546+
}
538547
}
539548

540549
impl Default for Profile {

src/cargo/core/workspace.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,7 @@ impl<'cfg> Workspace<'cfg> {
462462
doc: Profile::default_doc(),
463463
custom_build: Profile::default_custom_build(),
464464
check: Profile::default_check(),
465+
doctest: Profile::default_doctest(),
465466
};
466467

467468
for pkg in self.members().filter(|p| p.manifest_path() != root_manifest) {

src/cargo/ops/cargo_clean.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,11 @@ pub fn clean(ws: &Workspace, opts: &CleanOptions) -> CargoResult<()> {
5151
for kind in [Kind::Host, Kind::Target].iter() {
5252
let Profiles {
5353
ref release, ref dev, ref test, ref bench, ref doc,
54-
ref custom_build, ref test_deps, ref bench_deps, ref check
54+
ref custom_build, ref test_deps, ref bench_deps, ref check,
55+
ref doctest,
5556
} = *profiles;
5657
let profiles = [release, dev, test, bench, doc, custom_build,
57-
test_deps, bench_deps, check];
58+
test_deps, bench_deps, check, doctest];
5859
for profile in profiles.iter() {
5960
units.push(Unit {
6061
pkg: &pkg,

src/cargo/ops/cargo_compile.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ pub enum CompileMode {
9191
Check,
9292
Bench,
9393
Doc { deps: bool },
94+
Doctest,
9495
}
9596

9697
#[derive(Clone, Copy, PartialEq, Eq, RustcDecodable)]
@@ -321,6 +322,7 @@ fn generate_targets<'a>(pkg: &'a Package,
321322
CompileMode::Build => build,
322323
CompileMode::Check => &profiles.check,
323324
CompileMode::Doc { .. } => &profiles.doc,
325+
CompileMode::Doctest => &profiles.doctest,
324326
};
325327
match *filter {
326328
CompileFilter::Everything => {
@@ -360,6 +362,15 @@ fn generate_targets<'a>(pkg: &'a Package,
360362
Ok(pkg.targets().iter().filter(|t| t.documented())
361363
.map(|t| (t, profile)).collect())
362364
}
365+
CompileMode::Doctest => {
366+
if let Some(t) = pkg.targets().iter().find(|t| t.is_lib()) {
367+
if t.doctested() {
368+
return Ok(vec![(t, profile)])
369+
}
370+
}
371+
372+
Ok(Vec::new())
373+
}
363374
}
364375
}
365376
CompileFilter::Only { lib, bins, examples, tests, benches } => {

src/cargo/ops/cargo_rustc/context.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
562562
pub fn dep_targets(&self, unit: &Unit<'a>) -> CargoResult<Vec<Unit<'a>>> {
563563
if unit.profile.run_custom_build {
564564
return self.dep_run_custom_build(unit)
565-
} else if unit.profile.doc {
565+
} else if unit.profile.doc && !unit.profile.test {
566566
return self.doc_deps(unit);
567567
}
568568

@@ -634,7 +634,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
634634
// the library of the same package. The call to `resolve.deps` above
635635
// didn't include `pkg` in the return values, so we need to special case
636636
// it here and see if we need to push `(pkg, pkg_lib_target)`.
637-
if unit.target.is_lib() {
637+
if unit.target.is_lib() && !unit.profile.doc {
638638
return Ok(ret)
639639
}
640640
ret.extend(self.maybe_lib(unit));

src/cargo/ops/cargo_rustc/job_queue.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,8 +292,10 @@ impl<'a> JobQueue<'a> {
292292
// being a compiled package
293293
Dirty => {
294294
if key.profile.doc {
295-
self.documented.insert(key.pkg);
296-
config.shell().status("Documenting", key.pkg)?;
295+
if !key.profile.test {
296+
self.documented.insert(key.pkg);
297+
config.shell().status("Documenting", key.pkg)?;
298+
}
297299
} else {
298300
self.compiled.insert(key.pkg);
299301
config.shell().status("Compiling", key.pkg)?;

src/cargo/ops/cargo_rustc/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use core::{Profile, Profiles, Workspace};
1313
use core::shell::ColorConfig;
1414
use util::{self, CargoResult, ProcessBuilder, ProcessError, human, machine_message};
1515
use util::{Config, internal, ChainError, profile, join_paths, short_hash};
16+
use util::Freshness;
1617

1718
use self::job::{Job, Work};
1819
use self::job_queue::JobQueue;
@@ -215,6 +216,9 @@ fn compile<'a, 'cfg: 'a>(cx: &mut Context<'a, 'cfg>,
215216

216217
let (dirty, fresh, freshness) = if unit.profile.run_custom_build {
217218
custom_build::prepare(cx, unit)?
219+
} else if unit.profile.doc && unit.profile.test {
220+
// we run these targets later, so this is just a noop for now
221+
(Work::new(|_| Ok(())), Work::new(|_| Ok(())), Freshness::Fresh)
218222
} else {
219223
let (freshness, dirty, fresh) = fingerprint::prepare_target(cx, unit)?;
220224
let work = if unit.profile.doc {

src/cargo/util/toml.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1253,6 +1253,7 @@ fn build_profiles(profiles: &Option<TomlProfiles>) -> Profiles {
12531253
custom_build: Profile::default_custom_build(),
12541254
check: merge(Profile::default_check(),
12551255
profiles.and_then(|p| p.dev.as_ref())),
1256+
doctest: Profile::default_doctest(),
12561257
};
12571258
// The test/bench targets cannot have panic=abort because they'll all get
12581259
// compiled with --test which requires the unwind runtime currently

tests/test.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2143,6 +2143,7 @@ fn only_test_docs() {
21432143
}
21442144

21452145
/// ```
2146+
/// foo::bar();
21462147
/// println!("ok");
21472148
/// ```
21482149
pub fn bar() {
@@ -2524,3 +2525,35 @@ test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
25242525

25252526
"));
25262527
}
2528+
2529+
#[test]
2530+
fn doctest_only_with_dev_dep() {
2531+
let p = project("workspace")
2532+
.file("Cargo.toml", r#"
2533+
[project]
2534+
name = "a"
2535+
version = "0.1.0"
2536+
2537+
[dev-dependencies]
2538+
b = { path = "b" }
2539+
"#)
2540+
.file("src/lib.rs", r#"
2541+
/// ```
2542+
/// extern crate b;
2543+
///
2544+
/// b::b();
2545+
/// ```
2546+
pub fn a() {}
2547+
"#)
2548+
.file("b/Cargo.toml", r#"
2549+
[project]
2550+
name = "b"
2551+
version = "0.1.0"
2552+
"#)
2553+
.file("b/src/lib.rs", r#"
2554+
pub fn b() {}
2555+
"#);
2556+
2557+
assert_that(p.cargo_process("test").arg("--doc").arg("-v"),
2558+
execs().with_status(0));
2559+
}

0 commit comments

Comments
 (0)