From 755b3fc722c36d9761bf49c246b5f7c85a62380d Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Thu, 18 Feb 2021 16:15:24 +0100 Subject: [PATCH] rustdoc: Support argument files Factors out the `rustc_driver` logic that handles argument files so that rustdoc supports them as well, e.g.: rustdoc @argfile This is needed to be able to generate docs for projects that already use argument files when compiling them, e.g. projects that pass a huge number of `--cfg` arguments. The feature was stabilized for `rustc` in #66172. Signed-off-by: Miguel Ojeda --- compiler/rustc_driver/src/args.rs | 16 +++++++++++++++- compiler/rustc_driver/src/lib.rs | 14 +++----------- src/doc/rustdoc/src/command-line-arguments.md | 7 +++++++ src/librustdoc/lib.rs | 5 ++++- .../rustdoc-ui/commandline-argfile-badutf8.args | 2 ++ .../rustdoc-ui/commandline-argfile-badutf8.rs | 12 ++++++++++++ .../commandline-argfile-badutf8.stderr | 2 ++ .../rustdoc-ui/commandline-argfile-missing.rs | 15 +++++++++++++++ .../commandline-argfile-missing.stderr | 2 ++ src/test/rustdoc-ui/commandline-argfile.args | 2 ++ src/test/rustdoc-ui/commandline-argfile.rs | 13 +++++++++++++ 11 files changed, 77 insertions(+), 13 deletions(-) create mode 100644 src/test/rustdoc-ui/commandline-argfile-badutf8.args create mode 100644 src/test/rustdoc-ui/commandline-argfile-badutf8.rs create mode 100644 src/test/rustdoc-ui/commandline-argfile-badutf8.stderr create mode 100644 src/test/rustdoc-ui/commandline-argfile-missing.rs create mode 100644 src/test/rustdoc-ui/commandline-argfile-missing.stderr create mode 100644 src/test/rustdoc-ui/commandline-argfile.args create mode 100644 src/test/rustdoc-ui/commandline-argfile.rs diff --git a/compiler/rustc_driver/src/args.rs b/compiler/rustc_driver/src/args.rs index 4f2febf04b1..01338359f1a 100644 --- a/compiler/rustc_driver/src/args.rs +++ b/compiler/rustc_driver/src/args.rs @@ -3,7 +3,7 @@ use std::fmt; use std::fs; use std::io; -pub fn arg_expand(arg: String) -> Result, Error> { +fn arg_expand(arg: String) -> Result, Error> { if let Some(path) = arg.strip_prefix('@') { let file = match fs::read_to_string(path) { Ok(file) => file, @@ -18,6 +18,20 @@ pub fn arg_expand(arg: String) -> Result, Error> { } } +pub fn arg_expand_all(at_args: &[String]) -> Vec { + let mut args = Vec::new(); + for arg in at_args { + match arg_expand(arg.clone()) { + Ok(arg) => args.extend(arg), + Err(err) => rustc_session::early_error( + rustc_session::config::ErrorOutputType::default(), + &format!("Failed to load argument file: {}", err), + ), + } + } + args +} + #[derive(Debug)] pub enum Error { Utf8Error(Option), diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 15b984acac5..2aa20dc1e64 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -55,7 +55,7 @@ use std::process::{self, Command, Stdio}; use std::str; use std::time::Instant; -mod args; +pub mod args; pub mod pretty; /// Exit status code used for successful compilation and help output. @@ -188,16 +188,8 @@ fn run_compiler( Box Box + Send>, >, ) -> interface::Result<()> { - let mut args = Vec::new(); - for arg in at_args { - match args::arg_expand(arg.clone()) { - Ok(arg) => args.extend(arg), - Err(err) => early_error( - ErrorOutputType::default(), - &format!("Failed to load argument file: {}", err), - ), - } - } + let args = args::arg_expand_all(at_args); + let diagnostic_output = emitter.map_or(DiagnosticOutput::Default, DiagnosticOutput::Raw); let matches = match handle_options(&args) { Some(matches) => matches, diff --git a/src/doc/rustdoc/src/command-line-arguments.md b/src/doc/rustdoc/src/command-line-arguments.md index 80f7851debf..0302fbecb6e 100644 --- a/src/doc/rustdoc/src/command-line-arguments.md +++ b/src/doc/rustdoc/src/command-line-arguments.md @@ -422,3 +422,10 @@ $ rustdoc src/lib.rs --crate-version 1.3.37 When `rustdoc` receives this flag, it will print an extra "Version (version)" into the sidebar of the crate root's docs. You can use this flag to differentiate between different versions of your library's documentation. + +## `@path`: load command-line flags from a path + +If you specify `@path` on the command-line, then it will open `path` and read +command line options from it. These options are one per line; a blank line indicates +an empty option. The file can use Unix or Windows style line endings, and must be +encoded as UTF-8. diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index c61cbf78f77..5394d23e1c5 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -432,13 +432,16 @@ fn usage(argv0: &str) { (option.apply)(&mut options); } println!("{}", options.usage(&format!("{} [options] ", argv0))); + println!(" @path Read newline separated options from `path`\n"); println!("More information available at https://doc.rust-lang.org/rustdoc/what-is-rustdoc.html") } /// A result type used by several functions under `main()`. type MainResult = Result<(), ErrorReported>; -fn main_args(args: &[String]) -> MainResult { +fn main_args(at_args: &[String]) -> MainResult { + let args = rustc_driver::args::arg_expand_all(at_args); + let mut options = getopts::Options::new(); for option in opts() { (option.apply)(&mut options); diff --git a/src/test/rustdoc-ui/commandline-argfile-badutf8.args b/src/test/rustdoc-ui/commandline-argfile-badutf8.args new file mode 100644 index 00000000000..c070b0c2400 --- /dev/null +++ b/src/test/rustdoc-ui/commandline-argfile-badutf8.args @@ -0,0 +1,2 @@ +--cfg +unbroken€ \ No newline at end of file diff --git a/src/test/rustdoc-ui/commandline-argfile-badutf8.rs b/src/test/rustdoc-ui/commandline-argfile-badutf8.rs new file mode 100644 index 00000000000..e2984e3ca97 --- /dev/null +++ b/src/test/rustdoc-ui/commandline-argfile-badutf8.rs @@ -0,0 +1,12 @@ +// Check to see if we can get parameters from an @argsfile file +// +// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-badutf8.args + +#[cfg(not(cmdline_set))] +compile_error!("cmdline_set not set"); + +#[cfg(not(unbroken))] +compile_error!("unbroken not set"); + +fn main() { +} diff --git a/src/test/rustdoc-ui/commandline-argfile-badutf8.stderr b/src/test/rustdoc-ui/commandline-argfile-badutf8.stderr new file mode 100644 index 00000000000..9af6fc0a518 --- /dev/null +++ b/src/test/rustdoc-ui/commandline-argfile-badutf8.stderr @@ -0,0 +1,2 @@ +error: Failed to load argument file: Utf8 error in $DIR/commandline-argfile-badutf8.args + diff --git a/src/test/rustdoc-ui/commandline-argfile-missing.rs b/src/test/rustdoc-ui/commandline-argfile-missing.rs new file mode 100644 index 00000000000..020c3ff3c7e --- /dev/null +++ b/src/test/rustdoc-ui/commandline-argfile-missing.rs @@ -0,0 +1,15 @@ +// Check to see if we can get parameters from an @argsfile file +// +// ignore-tidy-linelength +// normalize-stderr-test: "os error \d+" -> "os error $$ERR" +// normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-missing.args + +#[cfg(not(cmdline_set))] +compile_error!("cmdline_set not set"); + +#[cfg(not(unbroken))] +compile_error!("unbroken not set"); + +fn main() { +} diff --git a/src/test/rustdoc-ui/commandline-argfile-missing.stderr b/src/test/rustdoc-ui/commandline-argfile-missing.stderr new file mode 100644 index 00000000000..179ad831004 --- /dev/null +++ b/src/test/rustdoc-ui/commandline-argfile-missing.stderr @@ -0,0 +1,2 @@ +error: Failed to load argument file: IO Error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR) + diff --git a/src/test/rustdoc-ui/commandline-argfile.args b/src/test/rustdoc-ui/commandline-argfile.args new file mode 100644 index 00000000000..972938bf6c8 --- /dev/null +++ b/src/test/rustdoc-ui/commandline-argfile.args @@ -0,0 +1,2 @@ +--cfg +unbroken \ No newline at end of file diff --git a/src/test/rustdoc-ui/commandline-argfile.rs b/src/test/rustdoc-ui/commandline-argfile.rs new file mode 100644 index 00000000000..cc8c8722c1c --- /dev/null +++ b/src/test/rustdoc-ui/commandline-argfile.rs @@ -0,0 +1,13 @@ +// Check to see if we can get parameters from an @argsfile file +// +// check-pass +// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile.args + +#[cfg(not(cmdline_set))] +compile_error!("cmdline_set not set"); + +#[cfg(not(unbroken))] +compile_error!("unbroken not set"); + +fn main() { +}