Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not obvious how to provide multiple usage statements with App::override_usage() #3413

Open
2 tasks done
jpgrayson opened this issue Feb 7, 2022 · 4 comments
Open
2 tasks done
Labels
A-help Area: documentation, including docs.rs, readme, examples, etc... C-bug Category: Updating dependencies M-breaking-change Meta: Implementing or merging this will introduce a breaking change. S-waiting-on-design Status: Waiting on user-facing design to be resolved before implementing
Milestone

Comments

@jpgrayson
Copy link
Contributor

Please complete the following tasks

Rust Version

rustc 1.58.1 (db9d1b20b 2022-01-20)

Clap Version

3.0.14

Minimal reproducible code

fn main() {
    clap::App::new("myapp")
        .override_usage(
            "myapp -X [-a] [-b] <file>\n\
             myapp -Y [-c] <file1> <file2>\n\
             myapp -Z [-d|-e]"
        )
        .get_matches_from(["myapp", "-h"]);
}

Steps to reproduce the bug with the above code

Paste as examples/min-usage.rs.
cargo run --example=min-usage

Actual Behaviour

myapp 

USAGE:
    myapp -X [-a] [-b] <file>
myapp -Y [-c] <file1> <file2>
myapp -Z [-d|-e]

OPTIONS:
    -h, --help    Print help information

Expected Behaviour

myapp 

USAGE:
    myapp -X [-a] [-b] <file>
    myapp -Y [-c] <file1> <file2>
    myapp -Z [-d|-e]

OPTIONS:
    -h, --help    Print help information

Additional Context

This relates to issue #1068.

When providing multiple usage statements on multiple lines, the help output is mis-indented.

The canonical workaround is for the user to indent the lines within their usage string according to the following rules:

  • Do not indent the first usage line.
  • Indent all subsequent usage lines with four spaces.
  • The last line must not end with a newline.

The workaround versions of the reproducing example above:

fn main() {
    clap::App::new("myapp")
        .override_usage(
            "myapp -X [-a] [-b] <file>\n    \
             myapp -Y [-c] <file1> <file2>\n    \
             myapp -Z [-d|-e]"
        )
        .get_matches_from(["myapp", "-h"]);
}

or

fn main() {
    clap::App::new("myapp")
        .override_usage("\
    myapp -X [-a] [-b] <file>
    myapp -Y [-c] <file1> <file2>
    myapp -Z [-d|-e]"
        )
        .get_matches_from(["myapp", "-h"]);
}

The above workaround works with the current DEFAULT_TEMPLATE and DEFAULT_NO_ARGS_TEMPLATE, but is sensitive to indentation changes in those default templates. Note that in the discussion for #2002, there is a stated goal to avoid making the details of the default templates an API contract. Requiring user-indented usage strings jeopardizes the flexibility to change the default templates to some degree.

N.B. the workaround for this issue changed when PR #2067 was merged. Prior to that, usage strings were tab-indented. #1068 illustrates the old-style workaround. It's perhaps worth noting that users upgrading from clap 2 --> 3 may bump into this issue if they have legacy multi-line usage strings with tab indentation.

Possible Solutions

Document/standardize the workaround

The least intrusive way to make multiple usage statements more obvious to users would be to document the required multi-line format (i.e. the above workaround) for custom usage strings. A couple additions to App::override_usage()'s docstring would be sufficient for this option.

Handle/comprehend non-indented multi-line usage strings

This approach was implemented in PR #3404. The idea was to accept user-provided usage strings where lines may or may not be indented by the user, and then use a new template tag ({usage-indented}) to normalize the user-provided usage lines to fit into clap's default help templates.

The benefits of this approach are that multi-line usage strings will Just Work(tm) both for simple newline separated usage statements as well as usage strings containing either the modern or legacy (see #1068) workarounds.

The key downside of this approach is the API change of adding the {usage-indented} template tag.

Debug Output

No response

@jpgrayson jpgrayson added the C-bug Category: Updating dependencies label Feb 7, 2022
@epage
Copy link
Member

epage commented Feb 16, 2022

This sounds contradictory to the purported change that closed #1068. I marked #1068 as closed based on a comment in the CHANGELOG

App::override_usage no longer implies a leading \t, allowing multi lined usages

This was copied over from before the changelog rewrite and was introduced in commit 8bd1f1a. This was released in v3.0.0-beta.1 on 2020-05-03. Looking back in the history, starting around that time, I am not finding any change to the usage code that sounds like this.

Looking back through src/output/help.rss history, for the entire time we used a template for default help (a87320a), we seem to always have the fixed number of leading spaces. We seem to have been inserting spaces between the header and the usage statement for quite a while.

Going to do some more digging into this.

@jpgrayson
Copy link
Contributor Author

FWIW, I also had a hard time reconciling the CHANGELOG message that prompted #1068 to be closed with any specific commit(s) that addressed #1068. AFAICT, the only difference between clap 2 and clap 3 for this issue is whether tab or space is used to indent the usage. It has always been one or the other hardwired indentation in either the procedural or templated help generation; and that change from tab to space indentation came with the template feature in a87320a (PR #2067).

@epage epage added this to the 4.0 milestone Jun 8, 2022
@epage epage modified the milestones: 4.0, 5.0 Aug 23, 2022
@epage
Copy link
Member

epage commented Aug 23, 2022

I feel like we are hitting a cap in the number of subtle breaking changes for 4.0 and feel this should be pushed back to 5.0.

jpgrayson added a commit to jpgrayson/clap that referenced this issue Aug 23, 2022
Extend Command::override_usage() doc string to describe how to format
multiple usage lines to be compatible with clap's default help formatter.

Relates-to: clap-rs#3413
@jpgrayson
Copy link
Contributor Author

PR #4106 adds documentation for how to add multiple override usage lines. Regardless of whether we may want to do something more substantial with usage overrides in clap 5, this documentation will be helpful for anyone that wants multiple usage lines in clap 3 or 4.

jpgrayson added a commit to jpgrayson/clap that referenced this issue Aug 23, 2022
Extend Command::override_usage() doc string to describe how to format
multiple usage lines to be compatible with clap's default help formatter.

Relates-to: clap-rs#3413
@epage epage added M-breaking-change Meta: Implementing or merging this will introduce a breaking change. A-help Area: documentation, including docs.rs, readme, examples, etc... labels Sep 28, 2022
@epage epage added the S-waiting-on-design Status: Waiting on user-facing design to be resolved before implementing label Nov 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-help Area: documentation, including docs.rs, readme, examples, etc... C-bug Category: Updating dependencies M-breaking-change Meta: Implementing or merging this will introduce a breaking change. S-waiting-on-design Status: Waiting on user-facing design to be resolved before implementing
Projects
None yet
Development

No branches or pull requests

2 participants