From 23c973e8ceafe00d9dc202f04f3151a9672872e5 Mon Sep 17 00:00:00 2001 From: Josh Junon Date: Fri, 12 Aug 2022 02:57:28 +0200 Subject: [PATCH] Allow --document-private-items to accept =yes|no Fixes #7963. Previously, --document-private-items was only a 'truthy' flag, and was enabled in #7593 for binary targets by default. However, this prevented any means of *disabling* this functionality for binary targets, hence #7963. This change does a few things. It first adds a new argument parser type called `yesno_flag()` that is a wrapper around a few `clap::Arg` settings to use the built-in `BoolishValueParser` in a way that allows for the `--flag` to return `true`, as well as an optional `=no` or `=yes` (or `=1`, `=off`, etc.) to explicitly set it to `true` or `false`. Then, the internal field for passing the private member documentation flag to rustdoc was changed to an `Option` to treat `None` as the automatic project type detection, and a `Some` value to override the behavior outright. This change should be entirely backwards compatible. --- src/bin/cargo/commands/doc.rs | 9 ++++- src/cargo/ops/cargo_compile.rs | 12 +++--- src/cargo/ops/cargo_package.rs | 2 +- src/cargo/util/command_prelude.rs | 16 +++++++- src/doc/man/cargo-doc.md | 2 +- src/doc/man/generated_txt/cargo-doc.txt | 2 +- src/doc/src/commands/cargo-doc.md | 2 +- src/etc/_cargo | 8 +++- src/etc/man/cargo-doc.1 | 2 +- tests/testsuite/doc.rs | 52 +++++++++++++++++++++++++ 10 files changed, 92 insertions(+), 15 deletions(-) diff --git a/src/bin/cargo/commands/doc.rs b/src/bin/cargo/commands/doc.rs index 429662c5f7f..a823c32f1cc 100644 --- a/src/bin/cargo/commands/doc.rs +++ b/src/bin/cargo/commands/doc.rs @@ -21,7 +21,10 @@ pub fn cli() -> App { "no-deps", "Don't build documentation for dependencies", )) - .arg(flag("document-private-items", "Document private items")) + .arg(yesno_flag( + "document-private-items", + "Document private items (the default for binaries)", + )) .arg_jobs() .arg_targets_lib_bin_example( "Document only this package's library", @@ -50,7 +53,9 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult { }; let mut compile_opts = args.compile_options(config, mode, Some(&ws), ProfileChecking::Custom)?; - compile_opts.rustdoc_document_private_items = args.flag("document-private-items"); + + compile_opts.rustdoc_document_private_items = + args.get_one::("document-private-items").copied(); let doc_opts = DocOptions { open_result: args.flag("open"), diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index ced55770ef8..fcec0296587 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -75,9 +75,11 @@ pub struct CompileOptions { pub target_rustc_crate_types: Option>, /// Extra arguments passed to all selected targets for rustdoc. pub local_rustdoc_args: Option>, - /// Whether the `--document-private-items` flags was specified and should - /// be forwarded to `rustdoc`. - pub rustdoc_document_private_items: bool, + /// Whether either the `--document-private-items` flag was specified, and + /// if so, if that argument should be forwarded to `rustdoc`. `None` indicates + /// that the behavior should be decided based on the target type - either public-only + /// for libraries, or private items for binaries. + pub rustdoc_document_private_items: Option, /// Whether the build process should check the minimum Rust version /// defined in the cargo metadata for a crate. pub honor_rust_version: bool, @@ -98,7 +100,7 @@ impl CompileOptions { target_rustc_args: None, target_rustc_crate_types: None, local_rustdoc_args: None, - rustdoc_document_private_items: false, + rustdoc_document_private_items: None, honor_rust_version: true, }) } @@ -620,7 +622,7 @@ pub fn create_bcx<'a, 'cfg>( // Add `--document-private-items` rustdoc flag if requested or if // the target is a binary. Binary crates get their private items // documented by default. - if rustdoc_document_private_items || unit.target.is_bin() { + if rustdoc_document_private_items.unwrap_or(unit.target.is_bin()) { let mut args = extra_args.take().unwrap_or_default(); args.push("--document-private-items".into()); if unit.target.is_bin() { diff --git a/src/cargo/ops/cargo_package.rs b/src/cargo/ops/cargo_package.rs index 270e1d70d3a..804bf5249d1 100644 --- a/src/cargo/ops/cargo_package.rs +++ b/src/cargo/ops/cargo_package.rs @@ -830,7 +830,7 @@ fn run_verify( target_rustc_args: rustc_args, target_rustc_crate_types: None, local_rustdoc_args: None, - rustdoc_document_private_items: false, + rustdoc_document_private_items: None, honor_rust_version: true, }, &exec, diff --git a/src/cargo/util/command_prelude.rs b/src/cargo/util/command_prelude.rs index 5d197b9f117..25a09055280 100644 --- a/src/cargo/util/command_prelude.rs +++ b/src/cargo/util/command_prelude.rs @@ -268,6 +268,20 @@ pub fn flag(name: &'static str, help: &'static str) -> Arg<'static> { .action(ArgAction::SetTrue) } +pub fn yesno_flag(name: &'static str, help: &'static str) -> Arg<'static> { + Arg::new(name) + .long(name) + .help(help) + .value_name("yes|no") + .value_parser(clap::builder::BoolishValueParser::new()) + .hide_possible_values(true) + .min_values(0) + .takes_value(true) + .multiple_values(false) + .require_equals(true) + .default_missing_value("yes") +} + pub fn opt(name: &'static str, help: &'static str) -> Arg<'static> { Arg::new(name).long(name).help(help) } @@ -610,7 +624,7 @@ pub trait ArgMatchesExt { target_rustc_args: None, target_rustc_crate_types: None, local_rustdoc_args: None, - rustdoc_document_private_items: false, + rustdoc_document_private_items: None, honor_rust_version: !self.flag("ignore-rust-version"), }; diff --git a/src/doc/man/cargo-doc.md b/src/doc/man/cargo-doc.md index f8f517d9ae7..6f212b926e9 100644 --- a/src/doc/man/cargo-doc.md +++ b/src/doc/man/cargo-doc.md @@ -32,7 +32,7 @@ option. Do not build documentation for dependencies. {{/option}} -{{#option "`--document-private-items`" }} +{{#option "`--document-private-items`[=_yes|no_]" }} Include non-public items in the documentation. This will be enabled by default if documenting a binary target. {{/option}} diff --git a/src/doc/man/generated_txt/cargo-doc.txt b/src/doc/man/generated_txt/cargo-doc.txt index 1a9492f3c1c..b37aeb84fcb 100644 --- a/src/doc/man/generated_txt/cargo-doc.txt +++ b/src/doc/man/generated_txt/cargo-doc.txt @@ -22,7 +22,7 @@ OPTIONS --no-deps Do not build documentation for dependencies. - --document-private-items + --document-private-items[=yes|no] Include non-public items in the documentation. This will be enabled by default if documenting a binary target. diff --git a/src/doc/src/commands/cargo-doc.md b/src/doc/src/commands/cargo-doc.md index a18d873c8e1..96c98e76792 100644 --- a/src/doc/src/commands/cargo-doc.md +++ b/src/doc/src/commands/cargo-doc.md @@ -32,7 +32,7 @@ option.
Do not build documentation for dependencies.
-
--document-private-items
+
--document-private-items[=yes|no]
Include non-public items in the documentation. This will be enabled by default if documenting a binary target.
diff --git a/src/etc/_cargo b/src/etc/_cargo index 5b0f881f66b..254b9bba3a2 100644 --- a/src/etc/_cargo +++ b/src/etc/_cargo @@ -125,7 +125,7 @@ _cargo() { doc | d) _arguments -s -S $common $parallel $features $msgfmt $triple $target $manifest \ '--no-deps[do not build docs for dependencies]' \ - '--document-private-items[include non-public items in the documentation]' \ + '--document-private-items'{--document-private-items=}'[include non-public items in the documentation]:bool:_cargo_yesno' \ '--open[open docs in browser after the build]' \ '(-p --package)'{-p+,--package=}'[specify package to document]:package:_cargo_package_names' \ '--release[build artifacts in release mode, with optimizations]' \ @@ -261,7 +261,7 @@ _cargo() { rustdoc) _arguments -s -S $common $parallel $features $msgfmt $triple $target $manifest \ - '--document-private-items[include non-public items in the documentation]' \ + '--document-private-items'{--document-private-items=}'[include non-public items in the documentation]:bool:_cargo_yesno' \ '--open[open the docs in a browser after the operation]' \ '(-p --package)'{-p+,--package=}'[specify package to document]:package:_cargo_package_names' \ '--release[build artifacts in release mode, with optimizations]' \ @@ -444,4 +444,8 @@ _cargo_example_names() { fi } +_cargo_yesno() { + _values 'yes|no' yes no +} + _cargo diff --git a/src/etc/man/cargo-doc.1 b/src/etc/man/cargo-doc.1 index 1982e602ea1..382e377b85c 100644 --- a/src/etc/man/cargo-doc.1 +++ b/src/etc/man/cargo-doc.1 @@ -26,7 +26,7 @@ option. Do not build documentation for dependencies. .RE .sp -\fB\-\-document\-private\-items\fR +\fB\-\-document\-private\-items\fR[=\fIyes|no\fR] .RS 4 Include non\-public items in the documentation. This will be enabled by default if documenting a binary target. .RE diff --git a/tests/testsuite/doc.rs b/tests/testsuite/doc.rs index 09d6b2b5f73..5d186b2772e 100644 --- a/tests/testsuite/doc.rs +++ b/tests/testsuite/doc.rs @@ -1922,6 +1922,58 @@ fn bin_private_items() { assert!(p.root().join("target/doc/foo/foo_mod/index.html").is_file()); } +#[cargo_test] +fn bin_private_items_disable() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + "#, + ) + .file( + "src/main.rs", + " + pub fn foo_pub() {} + fn foo_priv() {} + struct FooStruct; + enum FooEnum {} + trait FooTrait {} + type FooType = u32; + mod foo_mod {} + + ", + ) + .build(); + + p.cargo("doc --document-private-items=no") + .with_stderr( + "\ +[DOCUMENTING] foo v0.0.1 ([CWD]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +", + ) + .run(); + + assert!(p.root().join("target/doc/foo/index.html").is_file()); + assert!(p.root().join("target/doc/foo/fn.foo_pub.html").is_file()); + assert!(!p.root().join("target/doc/foo/fn.foo_priv.html").is_file()); + assert!(!p + .root() + .join("target/doc/foo/struct.FooStruct.html") + .is_file()); + assert!(!p.root().join("target/doc/foo/enum.FooEnum.html").is_file()); + assert!(!p + .root() + .join("target/doc/foo/trait.FooTrait.html") + .is_file()); + assert!(!p.root().join("target/doc/foo/type.FooType.html").is_file()); + assert!(!p.root().join("target/doc/foo/foo_mod/index.html").is_file()); +} + #[cargo_test] fn bin_private_items_deps() { let p = project()