Add option to display warnings in rustdoc

This commit is contained in:
Guillaume Gomez
2017-05-01 17:47:39 +02:00
parent 06fb4d2564
commit f30ed77f0d
6 changed files with 67 additions and 10 deletions

View File

@@ -104,7 +104,8 @@ pub fn run_core(search_paths: SearchPaths,
externs: config::Externs, externs: config::Externs,
input: Input, input: Input,
triple: Option<String>, triple: Option<String>,
maybe_sysroot: Option<PathBuf>) -> (clean::Crate, RenderInfo) maybe_sysroot: Option<PathBuf>,
allow_warnings: bool) -> (clean::Crate, RenderInfo)
{ {
// Parse, resolve, and typecheck the given crate. // Parse, resolve, and typecheck the given crate.
@@ -119,7 +120,7 @@ pub fn run_core(search_paths: SearchPaths,
maybe_sysroot: maybe_sysroot, maybe_sysroot: maybe_sysroot,
search_paths: search_paths, search_paths: search_paths,
crate_types: vec![config::CrateTypeRlib], crate_types: vec![config::CrateTypeRlib],
lint_opts: vec![(warning_lint, lint::Allow)], lint_opts: if !allow_warnings { vec![(warning_lint, lint::Allow)] } else { vec![] },
lint_cap: Some(lint::Allow), lint_cap: Some(lint::Allow),
externs: externs, externs: externs,
target_triple: triple.unwrap_or(config::host_triple().to_string()), target_triple: triple.unwrap_or(config::host_triple().to_string()),

View File

@@ -172,6 +172,7 @@ pub fn opts() -> Vec<RustcOptGroup> {
or `#![doc(html_playground_url=...)]`", or `#![doc(html_playground_url=...)]`",
"URL")), "URL")),
unstable(optflag("", "enable-commonmark", "to enable commonmark doc rendering/testing")), unstable(optflag("", "enable-commonmark", "to enable commonmark doc rendering/testing")),
unstable(optflag("", "display-warnings", "to print code warnings when testing doc")),
] ]
} }
@@ -279,14 +280,16 @@ pub fn main_args(args: &[String]) -> isize {
let crate_name = matches.opt_str("crate-name"); let crate_name = matches.opt_str("crate-name");
let playground_url = matches.opt_str("playground-url"); let playground_url = matches.opt_str("playground-url");
let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from); let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from);
let display_warnings = matches.opt_present("display-warnings");
match (should_test, markdown_input) { match (should_test, markdown_input) {
(true, true) => { (true, true) => {
return markdown::test(input, cfgs, libs, externs, test_args, maybe_sysroot, render_type) return markdown::test(input, cfgs, libs, externs, test_args, maybe_sysroot, render_type,
display_warnings)
} }
(true, false) => { (true, false) => {
return test::run(input, cfgs, libs, externs, test_args, crate_name, maybe_sysroot, return test::run(input, cfgs, libs, externs, test_args, crate_name, maybe_sysroot,
render_type) render_type, display_warnings)
} }
(false, true) => return markdown::render(input, (false, true) => return markdown::render(input,
output.unwrap_or(PathBuf::from("doc")), output.unwrap_or(PathBuf::from("doc")),
@@ -388,13 +391,15 @@ where R: 'static + Send, F: 'static + Send + FnOnce(Output) -> R {
let cr = PathBuf::from(cratefile); let cr = PathBuf::from(cratefile);
info!("starting to run rustc"); info!("starting to run rustc");
let display_warnings = matches.opt_present("display-warnings");
let (tx, rx) = channel(); let (tx, rx) = channel();
rustc_driver::monitor(move || { rustc_driver::monitor(move || {
use rustc::session::config::Input; use rustc::session::config::Input;
let (mut krate, renderinfo) = let (mut krate, renderinfo) =
core::run_core(paths, cfgs, externs, Input::File(cr), triple, maybe_sysroot); core::run_core(paths, cfgs, externs, Input::File(cr), triple, maybe_sysroot,
display_warnings);
info!("finished with rustc"); info!("finished with rustc");

View File

@@ -150,7 +150,7 @@ pub fn render(input: &str, mut output: PathBuf, matches: &getopts::Matches,
/// Run any tests/code examples in the markdown file `input`. /// Run any tests/code examples in the markdown file `input`.
pub fn test(input: &str, cfgs: Vec<String>, libs: SearchPaths, externs: Externs, pub fn test(input: &str, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
mut test_args: Vec<String>, maybe_sysroot: Option<PathBuf>, mut test_args: Vec<String>, maybe_sysroot: Option<PathBuf>,
render_type: RenderType) -> isize { render_type: RenderType, display_warnings: bool) -> isize {
let input_str = match load_string(input) { let input_str = match load_string(input) {
Ok(s) => s, Ok(s) => s,
Err(LoadStringError::ReadFail) => return 1, Err(LoadStringError::ReadFail) => return 1,
@@ -166,6 +166,9 @@ pub fn test(input: &str, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
old_find_testable_code(&input_str, &mut collector, DUMMY_SP); old_find_testable_code(&input_str, &mut collector, DUMMY_SP);
find_testable_code(&input_str, &mut collector, DUMMY_SP); find_testable_code(&input_str, &mut collector, DUMMY_SP);
test_args.insert(0, "rustdoctest".to_string()); test_args.insert(0, "rustdoctest".to_string());
if display_warnings {
test_args.insert(1, "--display-stdout".to_string());
}
testing::test_main(&test_args, collector.tests); testing::test_main(&test_args, collector.tests);
0 0
} }

View File

@@ -58,7 +58,8 @@ pub fn run(input: &str,
mut test_args: Vec<String>, mut test_args: Vec<String>,
crate_name: Option<String>, crate_name: Option<String>,
maybe_sysroot: Option<PathBuf>, maybe_sysroot: Option<PathBuf>,
render_type: RenderType) render_type: RenderType,
display_warnings: bool)
-> isize { -> isize {
let input_path = PathBuf::from(input); let input_path = PathBuf::from(input);
let input = config::Input::File(input_path.clone()); let input = config::Input::File(input_path.clone());
@@ -125,6 +126,9 @@ pub fn run(input: &str,
} }
test_args.insert(0, "rustdoctest".to_string()); test_args.insert(0, "rustdoctest".to_string());
if display_warnings {
test_args.insert(1, "--display-stdout".to_string());
}
testing::test_main(&test_args, testing::test_main(&test_args,
collector.tests.into_iter().collect()); collector.tests.into_iter().collect());

View File

@@ -304,13 +304,14 @@ pub fn test_main_static(tests: &[TestDescAndFn]) {
test_main(&args, owned_tests) test_main(&args, owned_tests)
} }
#[derive(Copy, Clone)] #[derive(Copy, Clone, Debug)]
pub enum ColorConfig { pub enum ColorConfig {
AutoColor, AutoColor,
AlwaysColor, AlwaysColor,
NeverColor, NeverColor,
} }
#[derive(Debug)]
pub struct TestOpts { pub struct TestOpts {
pub list: bool, pub list: bool,
pub filter: Option<String>, pub filter: Option<String>,
@@ -324,6 +325,7 @@ pub struct TestOpts {
pub quiet: bool, pub quiet: bool,
pub test_threads: Option<usize>, pub test_threads: Option<usize>,
pub skip: Vec<String>, pub skip: Vec<String>,
pub display_stdout: bool,
} }
impl TestOpts { impl TestOpts {
@@ -342,6 +344,7 @@ impl TestOpts {
quiet: false, quiet: false,
test_threads: None, test_threads: None,
skip: vec![], skip: vec![],
display_stdout: false,
} }
} }
} }
@@ -369,7 +372,8 @@ fn optgroups() -> Vec<getopts::OptGroup> {
getopts::optopt("", "color", "Configure coloring of output: getopts::optopt("", "color", "Configure coloring of output:
auto = colorize if stdout is a tty and tests are run on serially (default); auto = colorize if stdout is a tty and tests are run on serially (default);
always = always colorize output; always = always colorize output;
never = never colorize output;", "auto|always|never")] never = never colorize output;", "auto|always|never"),
getopts::optflag("", "display-stdout", "to print stdout even if the test succeeds")]
} }
fn usage(binary: &str) { fn usage(binary: &str) {
@@ -481,6 +485,7 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
quiet: quiet, quiet: quiet,
test_threads: test_threads, test_threads: test_threads,
skip: matches.opt_strs("skip"), skip: matches.opt_strs("skip"),
display_stdout: matches.opt_present("display-stdout"),
}; };
Some(Ok(test_opts)) Some(Ok(test_opts))
@@ -521,7 +526,9 @@ struct ConsoleTestState<T> {
measured: usize, measured: usize,
metrics: MetricMap, metrics: MetricMap,
failures: Vec<(TestDesc, Vec<u8>)>, failures: Vec<(TestDesc, Vec<u8>)>,
not_failures: Vec<(TestDesc, Vec<u8>)>,
max_name_len: usize, // number of columns to fill when aligning names max_name_len: usize, // number of columns to fill when aligning names
display_stdout: bool,
} }
impl<T: Write> ConsoleTestState<T> { impl<T: Write> ConsoleTestState<T> {
@@ -547,7 +554,9 @@ impl<T: Write> ConsoleTestState<T> {
measured: 0, measured: 0,
metrics: MetricMap::new(), metrics: MetricMap::new(),
failures: Vec::new(), failures: Vec::new(),
not_failures: Vec::new(),
max_name_len: 0, max_name_len: 0,
display_stdout: opts.display_stdout,
}) })
} }
@@ -703,9 +712,38 @@ impl<T: Write> ConsoleTestState<T> {
Ok(()) Ok(())
} }
pub fn write_outputs(&mut self) -> io::Result<()> {
self.write_plain("\nsuccesses:\n")?;
let mut successes = Vec::new();
let mut stdouts = String::new();
for &(ref f, ref stdout) in &self.not_failures {
successes.push(f.name.to_string());
if !stdout.is_empty() {
stdouts.push_str(&format!("---- {} stdout ----\n\t", f.name));
let output = String::from_utf8_lossy(stdout);
stdouts.push_str(&output);
stdouts.push_str("\n");
}
}
if !stdouts.is_empty() {
self.write_plain("\n")?;
self.write_plain(&stdouts)?;
}
self.write_plain("\nsuccesses:\n")?;
successes.sort();
for name in &successes {
self.write_plain(&format!(" {}\n", name))?;
}
Ok(())
}
pub fn write_run_finish(&mut self) -> io::Result<bool> { pub fn write_run_finish(&mut self) -> io::Result<bool> {
assert!(self.passed + self.failed + self.ignored + self.measured == self.total); assert!(self.passed + self.failed + self.ignored + self.measured == self.total);
if self.display_stdout {
self.write_outputs()?;
}
let success = self.failed == 0; let success = self.failed == 0;
if !success { if !success {
self.write_failures()?; self.write_failures()?;
@@ -824,7 +862,10 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Resu
st.write_log_result(&test, &result)?; st.write_log_result(&test, &result)?;
st.write_result(&result)?; st.write_result(&result)?;
match result { match result {
TrOk => st.passed += 1, TrOk => {
st.passed += 1;
st.not_failures.push((test, stdout));
}
TrIgnored => st.ignored += 1, TrIgnored => st.ignored += 1,
TrMetrics(mm) => { TrMetrics(mm) => {
let tname = test.name; let tname = test.name;
@@ -901,6 +942,8 @@ fn should_sort_failures_before_printing_them() {
max_name_len: 10, max_name_len: 10,
metrics: MetricMap::new(), metrics: MetricMap::new(),
failures: vec![(test_b, Vec::new()), (test_a, Vec::new())], failures: vec![(test_b, Vec::new()), (test_a, Vec::new())],
display_stdout: false,
not_failures: Vec::new(),
}; };
st.write_failures().unwrap(); st.write_failures().unwrap();

View File

@@ -336,6 +336,7 @@ pub fn test_opts(config: &Config) -> test::TestOpts {
test_threads: None, test_threads: None,
skip: vec![], skip: vec![],
list: false, list: false,
display_stdout: false,
} }
} }