From e100ee96c209e88a590e4e58243f979f56bc3b88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Hern=C3=A1ndez?= Date: Mon, 31 Oct 2016 19:15:03 +0100 Subject: [PATCH 1/4] FIX: Call rustdoc test with the correct cfg flags of a package. There was a situation in which if you you had a lib that depends on a package with features, whenever you ran the tests for the package the `rustdoc test` call was failing because rustdoc was called with the root cfg flags, not the package cfg flags. This fix solves the issue by keeping track of the cfg flags per package, so the rustdoc command will be generated with the correct cfg flags. --- src/cargo/ops/cargo_rustc/compilation.rs | 6 +- src/cargo/ops/cargo_rustc/mod.rs | 23 ++++---- src/cargo/ops/cargo_test.rs | 6 +- tests/test.rs | 70 ++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 16 deletions(-) diff --git a/src/cargo/ops/cargo_rustc/compilation.rs b/src/cargo/ops/cargo_rustc/compilation.rs index 93dead30743..f15032c2336 100644 --- a/src/cargo/ops/cargo_rustc/compilation.rs +++ b/src/cargo/ops/cargo_rustc/compilation.rs @@ -43,8 +43,8 @@ pub struct Compilation<'cfg> { pub to_doc_test: Vec, - /// Features enabled during this compilation. - pub cfgs: HashSet, + /// Features per package enabled during this compilation. + pub cfgs: HashMap>, pub target: String, @@ -63,7 +63,7 @@ impl<'cfg> Compilation<'cfg> { binaries: Vec::new(), extra_env: HashMap::new(), to_doc_test: Vec::new(), - cfgs: HashSet::new(), + cfgs: HashMap::new(), config: config, target: String::new(), } diff --git a/src/cargo/ops/cargo_rustc/mod.rs b/src/cargo/ops/cargo_rustc/mod.rs index 33f86c0ef1b..26edaae9e4f 100644 --- a/src/cargo/ops/cargo_rustc/mod.rs +++ b/src/cargo/ops/cargo_rustc/mod.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::env; use std::ffi::{OsStr, OsString}; use std::fs; @@ -81,7 +81,6 @@ pub fn compile_targets<'a, 'cfg: 'a>(ws: &Workspace<'cfg>, }) }).collect::>(); - let root = try!(ws.current()); let mut cx = try!(Context::new(ws, resolve, packages, config, build_config, profiles)); @@ -142,19 +141,21 @@ pub fn compile_targets<'a, 'cfg: 'a>(ws: &Workspace<'cfg>, cx.compilation.libraries.insert(pkgid.clone(), v); } } - } - let root_pkg = root.package_id(); - if let Some(feats) = cx.resolve.features(root_pkg) { - cx.compilation.cfgs.extend(feats.iter().map(|feat| { - format!("feature=\"{}\"", feat) - })); + if let Some(feats) = cx.resolve.features(&unit.pkg.package_id()) { + for feat in feats.iter() { + cx.compilation.cfgs.entry(unit.pkg.package_id().clone()) + .or_insert(HashSet::new()) + .insert(format!("feature=\"{}\"", feat)); + } + } } for (&(ref pkg, _), output) in cx.build_state.outputs.lock().unwrap().iter() { - if pkg == root_pkg { - cx.compilation.cfgs.extend(output.cfgs.iter().cloned()); - } + cx.compilation.cfgs.entry(pkg.clone()) + .or_insert(HashSet::new()) + .extend(output.cfgs.iter().cloned()); + for dir in output.library_paths.iter() { cx.compilation.native_dirs.insert(dir.clone()); } diff --git a/src/cargo/ops/cargo_test.rs b/src/cargo/ops/cargo_test.rs index 71a22d4e461..f382a1dd128 100644 --- a/src/cargo/ops/cargo_test.rs +++ b/src/cargo/ops/cargo_test.rs @@ -145,8 +145,10 @@ fn run_doc_tests(options: &TestOptions, p.arg("--test-args").arg(&test_args.join(" ")); } - for cfg in compilation.cfgs.iter() { - p.arg("--cfg").arg(cfg); + if let Some(cfgs) = compilation.cfgs.get(&package.package_id()) { + for cfg in cfgs.iter() { + p.arg("--cfg").arg(cfg); + } } for (_, libs) in compilation.libraries.iter() { diff --git a/tests/test.rs b/tests/test.rs index 2e5d8aa57be..cefec7e24e0 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -2262,3 +2262,73 @@ fn panic_abort_multiple() { .arg("-p").arg("a"), execs().with_status(0)); } + +#[test] +fn pass_correct_cfgs_flags_to_rustdoc() { + let p = project("foo") + .file("Cargo.toml", r#" + [package] + name = "foo" + version = "0.1.0" + authors = [] + + [features] + default = ["a/default"] + nightly = ["a/nightly"] + + [dependencies.a] + path = "libs/a" + default-features = false + "#) + .file("src/lib.rs", r#" + #[cfg(test)] + mod tests { + #[test] + fn it_works() { + assert!(true); + } + } + "#) + .file("libs/a/Cargo.toml", r#" + [package] + name = "a" + version = "0.1.0" + authors = [] + + [features] + default = ["serde_codegen"] + nightly = ["serde_derive"] + + [dependencies] + serde_derive = { version = "0.8", optional = true } + + [build-dependencies] + serde_codegen = { version = "0.8", optional = true } + "#) + .file("libs/a/src/lib.rs", r#" + #[cfg(feature = "serde_derive")] + const MSG: &'static str = "This is safe"; + + #[cfg(feature = "serde_codegen")] + const MSG: &'static str = "This is risky"; + + pub fn get() -> &'static str { + MSG + } + "#); + + assert_that(p.cargo_process("test") + .arg("--package").arg("a") + .arg("--verbose"), + execs().with_status(0) + .with_stderr_contains("\ +[DOCTEST] a +[RUNNING] `rustdoc --test [..]--cfg feature=\\\"serde_codegen\\\"[..]`")); + + assert_that(p.cargo_process("test") + .arg("--verbose"), + execs().with_status(0) + .with_stderr_contains("\ +[DOCTEST] foo +[RUNNING] `rustdoc --test [..]--cfg feature=\\\"a\\\"[..]`")); +} From fd8274a42407b6f1dc41674a0a9c51c7d6f6cdfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Hern=C3=A1ndez?= Date: Mon, 31 Oct 2016 23:54:04 +0100 Subject: [PATCH 2/4] Use better iter() semantics to collect cfg flags. --- src/cargo/ops/cargo_rustc/mod.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/cargo/ops/cargo_rustc/mod.rs b/src/cargo/ops/cargo_rustc/mod.rs index 26edaae9e4f..00bcb866282 100644 --- a/src/cargo/ops/cargo_rustc/mod.rs +++ b/src/cargo/ops/cargo_rustc/mod.rs @@ -143,11 +143,9 @@ pub fn compile_targets<'a, 'cfg: 'a>(ws: &Workspace<'cfg>, } if let Some(feats) = cx.resolve.features(&unit.pkg.package_id()) { - for feat in feats.iter() { - cx.compilation.cfgs.entry(unit.pkg.package_id().clone()) - .or_insert(HashSet::new()) - .insert(format!("feature=\"{}\"", feat)); - } + cx.compilation.cfgs.entry(unit.pkg.package_id().clone()) + .or_insert(HashSet::new()) + .extend(feats.iter().map(|feat| format!("feature=\"{}\"", feat))); } } From 3f90298d238ab101e54cefbd4b77d49e17fe26f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Hern=C3=A1ndez?= Date: Tue, 1 Nov 2016 18:14:41 +0100 Subject: [PATCH 3/4] Relax conditions in rustdoc test cfg flags tests. In Windows the rustdoc test output sets more double quotes, so the test doesn't pass. We need to relax the test so it pass in *NIX and Windows environments. --- tests/test.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/test.rs b/tests/test.rs index cefec7e24e0..69f22e701a4 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -2273,11 +2273,11 @@ fn pass_correct_cfgs_flags_to_rustdoc() { authors = [] [features] - default = ["a/default"] - nightly = ["a/nightly"] + default = ["feature_a/default"] + nightly = ["feature_a/nightly"] - [dependencies.a] - path = "libs/a" + [dependencies.feature_a] + path = "libs/feature_a" default-features = false "#) .file("src/lib.rs", r#" @@ -2289,9 +2289,9 @@ fn pass_correct_cfgs_flags_to_rustdoc() { } } "#) - .file("libs/a/Cargo.toml", r#" + .file("libs/feature_a/Cargo.toml", r#" [package] - name = "a" + name = "feature_a" version = "0.1.0" authors = [] @@ -2305,7 +2305,7 @@ fn pass_correct_cfgs_flags_to_rustdoc() { [build-dependencies] serde_codegen = { version = "0.8", optional = true } "#) - .file("libs/a/src/lib.rs", r#" + .file("libs/feature_a/src/lib.rs", r#" #[cfg(feature = "serde_derive")] const MSG: &'static str = "This is safe"; @@ -2318,17 +2318,17 @@ fn pass_correct_cfgs_flags_to_rustdoc() { "#); assert_that(p.cargo_process("test") - .arg("--package").arg("a") + .arg("--package").arg("feature_a") .arg("--verbose"), execs().with_status(0) .with_stderr_contains("\ -[DOCTEST] a -[RUNNING] `rustdoc --test [..]--cfg feature=\\\"serde_codegen\\\"[..]`")); +[DOCTEST] feature_a +[RUNNING] `rustdoc --test [..]serde_codegen[..]`")); assert_that(p.cargo_process("test") .arg("--verbose"), execs().with_status(0) .with_stderr_contains("\ [DOCTEST] foo -[RUNNING] `rustdoc --test [..]--cfg feature=\\\"a\\\"[..]`")); +[RUNNING] `rustdoc --test [..]feature_a[..]`")); } From 665aa7fe7e8309712bb35b8682ccd5cdcf127234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Hern=C3=A1ndez?= Date: Tue, 1 Nov 2016 18:16:55 +0100 Subject: [PATCH 4/4] Add text language to code bloks in machine-readable-output.md Travis fails when running `make doc` because of this file. This should fix the issue. --- src/doc/machine-readable-output.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/machine-readable-output.md b/src/doc/machine-readable-output.md index e486fd6c685..7b0463a5a6e 100644 --- a/src/doc/machine-readable-output.md +++ b/src/doc/machine-readable-output.md @@ -7,7 +7,7 @@ Cargo can output information about project and build in JSON format. You can use `cargo metadata` command to get information about project structure and dependencies. The output of the command looks like this: -``` +```text { // Integer version number of the format. "version": integer, @@ -59,7 +59,7 @@ without waiting for the whole build to finish. The message format looks like this: -``` +```text { // Type of the message. "reason": "compiler-message",