TeXitoi / structopt

Parse command line arguments by defining a struct.
Other
2.7k stars 148 forks source link

`flatten` causes the wrong doc-comment to be respected #333

Open epage opened 4 years ago

epage commented 4 years ago

With clap-verbosity-flag "3.0.0"

use structopt::StructOpt;
use clap_verbosity_flag::Verbosity;

#[derive(Debug, StructOpt)]
/// Foo
struct Cli {
    #[structopt(flatten)]
    verbose: Verbosity,
}

fn main() {
    Cli::from_args();
}

will cause clap-verbosity-flag's documentation to be used for the help instead of the user-specified one

❯ ./target/debug/examples/simple --help
clap-verbosity-flag 0.3.0
Easily add a `--verbose` flag to CLIs using Structopt

# Examples

```rust use structopt::StructOpt; use clap_verbosity_flag::Verbosity;

/// Le CLI #[derive(Debug, StructOpt)] struct Cli { #[structopt(flatten)] verbose: Verbosity, } # # fn main() {} ```

USAGE:
    simple [FLAGS]

FLAGS:
    -h, --help
            Prints help information

    -q, --quiet
            Pass many times for less log output

    -V, --version
            Prints version information

    -v, --verbose
            Pass many times for more log output

            By default, it'll only report errors. Passing `-v` one time also prints warnings, `-vv` enables info
            logging, `-vvv` debug, and `-vvvv` trace.

I am working around it in clap-verbosity-flag by. not providing a doc comment (https://github.com/rust-cli/clap-verbosity-flag/pull/21).

A workaround is explained in https://github.com/TeXitoi/structopt/issues/333#issuecomment-712265332

epage commented 4 years ago

Based on reports (https://github.com/rust-cli/clap-verbosity-flag/issues/20) I'm guessing https://github.com/TeXitoi/structopt/commit/e2270deae2c9b930541afecd4c28f41ddd1d669b broke this

CreepySkeleton commented 4 years ago

will cause clap-verbosity-flag's documentation to be used for the help instead of the user-specified one

But there's no user specified help here as far as I can see 😕

epage commented 4 years ago
/// Foo
struct Cli {

The user's doc-comment is being overridden by the doc-comment from the chain. Instead of "Foo", we're getting library documentation

CreepySkeleton commented 4 years ago

This is caused by #290 since doc comments on top of struct/enum are top level attributes too :(

ssokolow commented 4 years ago

I just noticed that this also causes the doc comment on my boilerplate opts (which get flattened into the main struct) to override the about attribute on the main struct.

I'm really starting to feel like I need to write a regression/integration suite on my --help output just to feel safe using --help generation.

pizzamig commented 4 years ago

This is caused by #290 since doc comments on top of struct/enum are top level attributes too :(

Is there any update or way to fix this? Currently I cannot document a struct and re-use it flattened and the workaround to move documentation to the lib doesn't work for me now, it would require quite some changes in my code.

The complexity of structopt is too high for me right now to try to find a fix.

thanks in advance

CreepySkeleton commented 4 years ago

I tried to fix it. I couldn't. I'll take another round a bit later.

vorner commented 3 years ago

Hello

I guess the „proper“ way to fix it will be hard and will take time (I'm not sure if reordering the calls inside the StructOptInternal::augment_clap to call these after descending into flattened fields instead of at the beginning would work ‒ it seems version is called at the end, so possibly the .about and similar could too?).

But if it is hard, would it make sense to add some kind of #[no_about] parameter that would skip all the auto-generated application information, like about and version? I guess most people know that a struct will be used as flattened field and could annotate them.

TeXitoi commented 3 years ago

By default, there is no about, but doc comment are about, so the workaround would be no doc comment on these structs.

vorner commented 3 years ago

I've figured that, but it is kind of bad for structs provided by libraries. I want to have doc comment to render on docs.rs, I also tend to #[warn(missing_docs)]. But then structdoc tries to interpret it and hijacks it if someone flattens the structure into their top-level Opts structure, which is bad.

But as the author of the library I know my struct should not be used directly and that it should never provide the about and --version. I want to mark it as just a source of more fields, not to do anything with the App at all.

https://docs.rs/spirit-daemonize/0.3.2/spirit_daemonize/struct.Opts.html

Maybe the right name would be #[ignore_doc_comment] or #[flattenable] or like that? Or is this orthogonal to this bug?

vorner commented 3 years ago

Just for the record, I've figured a workaround that keeps them for the docs.rs, but doesn't hijacks them for the about:

#[cfg_attr(not(doc), allow(missing_docs))]
#[cfg_attr(doc, doc = r#"
The doc comment goes here

Following the doc comment
"#)]

It simply enables the doc comment only for the documentation generation (and seems to work with doc tests too)

TeXitoi commented 3 years ago

I've put a link to your workaround in the description of the issue for ease of access.