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

AppSettings::DeriveDisplayOrder doesn't propagate to sub commands correctly #706

Closed
Nemo157 opened this issue Oct 25, 2016 · 8 comments
Closed
Labels
A-help Area: documentation, including docs.rs, readme, examples, etc... C-bug Category: Updating dependencies
Milestone

Comments

@Nemo157
Copy link
Contributor

Nemo157 commented Oct 25, 2016

Adding AppSettings::DeriveDisplayOrder to the global settings of an App doesn't propagate down to the apps sub commands.

The following example defines a subcommand with two args in reverse alphabetical order, running --help on the subcommand prints the arguments in alphabetical order with the --help and --version arguments also interspersed.

Moving the .global_setting(AppSettings::DeriveDisplayOrder) line down to the subcommand itself results in the correct ordering of the two arguments, so the setting itself is working but for some reason not propagating down correctly.


Example code

extern crate clap;

use clap::{App, Arg, SubCommand, AppSettings};

fn main() {
    App::new("MyApp")
        .global_setting(AppSettings::DeriveDisplayOrder)
        .subcommands(vec![
            SubCommand::with_name("test")
                .args(&[
                    Arg::with_name("second")
                        .long("second")
                        .help("second should come first"),
                    Arg::with_name("first")
                        .long("first")
                        .help("first should come second"),
                ])
        ])
        .get_matches();
}

Output (saved the above example into examples/derive-display-order-bug.rs and run via cargo run --example derive-display-order-bug -- test --help)

derive-display-order-bug-test

USAGE:
    derive-display-order-bug test [FLAGS]

FLAGS:
        --first      first should come second
    -h, --help       Prints help information
        --second     second should come first
    -V, --version    Prints version information
@Nemo157
Copy link
Contributor Author

Nemo157 commented Oct 25, 2016

I had a quick look through the source. Seems DeriveDisplayOrder is applied while adding the Arg to the Parser for the SubCommand, which happens before even adding the sub command to the top level app and well before the global settings are propagated down just before actually parsing the incoming arguments. It appears UnifiedHelpMessage would likely exhibit the same issue.

@Nemo157
Copy link
Contributor Author

Nemo157 commented Oct 25, 2016

Quick WIP commit of a working solution (at least for this example): https://github.com/Nemo157/clap-rs/tree/derive_order_at_print_time_2

Not sure if this will handle the interaction with UnifiedHelpMessage or not, I think it's pretty close to a workable solution though.

EDIT: Just realised this will break explicitly using the display_order method on args :(

@kbknapp
Copy link
Member

kbknapp commented Oct 26, 2016

Thanks for such a detailed write up!

I see a possibly simple way to go about fixing this. Since you've already taken the time to check through the code and get a potential fix if you'd like, I'll give my suggestion and answer any questions you've got but let you take the crack at it?

Add an Arg.user_disp_ord (default of 999) (and to subsequent *Builder structs) which gets set if the user passes in a custom display order. And then otherwise always set the disp_ord number as if DeriveDisplayOrder was set.

Then upon propagating the global settings, if DeriveDisplayOrder was set, do nothing unless user_disp_ord was anything other than 999 in which case set disp_ord to user_disp_ord. If it wasn't set, set disp_ord to the user_disp_ord no matter what.

This is just off the top of my head though 😜

Also, it sounds like I need to add a test to guard against this issue in the future!

@kbknapp kbknapp added C-bug Category: Updating dependencies P2: need to have A-help Area: documentation, including docs.rs, readme, examples, etc... labels Oct 26, 2016
@kbknapp kbknapp added this to the 2.16.3 milestone Oct 26, 2016
@kbknapp
Copy link
Member

kbknapp commented Oct 26, 2016

That solution would also allow the help generation code to remain unchanged.

I'm also open to other solutions, which I forgot to mention.

@Nemo157
Copy link
Contributor Author

Nemo157 commented Oct 26, 2016

I can see how something like that could work, I should be able to throw something together within the next day.

@Nemo157
Copy link
Contributor Author

Nemo157 commented Oct 26, 2016

New WIP commit: Nemo157@2b78c98

Based on your suggestion but slightly different to also handle propagating UnifiedHelpMessage correctly. Keeps disp_ord on the Arg purely for the users setting and copies it directly to the other option/flag builders. Adds a new unified_ord value to the option/flag builders to keep track of the overall order between the two lists in-case it's needed. After propagation checks whether the display order needs to be derived then uses either the unified_ord or just the index in the list to update the disp_ord if the user hasn't customised it.

@Nemo157
Copy link
Contributor Author

Nemo157 commented Oct 26, 2016

I'll write a couple of quick tests then make a PR for this.

Nemo157 added a commit to Nemo157/clap-rs that referenced this issue Oct 26, 2016
Try and stress the combinations of DeriveDisplayOrder and UnifiedHelpMessage
along with propagating them to subcommands and explicitly setting a display
order.

The new tests

  derive_order_subcommand_propagate
  unified_help_and_derive_order_subcommand_propagate
  unified_help_and_derive_order_subcommand_propagate_with_explicit_display_order

are currently failing because of bug clap-rs#706.
Nemo157 added a commit to Nemo157/clap-rs that referenced this issue Oct 26, 2016
Don't attempt to change the display order of flags/options until any app
settings have been propagated down from a parent App in case DeriveDisplayOrder
and/or UnifiedHelpMessage are propagated.

Fixes clap-rs#706
Nemo157 added a commit to Nemo157/clap-rs that referenced this issue Oct 26, 2016
Don't attempt to change the display order of flags/options until any app
settings have been propagated down from a parent App in case DeriveDisplayOrder
and/or UnifiedHelpMessage are propagated.

Fixes clap-rs#706
Nemo157 added a commit to Nemo157/clap-rs that referenced this issue Oct 26, 2016
Try and stress the combinations of DeriveDisplayOrder and UnifiedHelpMessage
along with propagating them to subcommands and explicitly setting a display
order.

The new tests

  derive_order_subcommand_propagate
  unified_help_and_derive_order_subcommand_propagate
  unified_help_and_derive_order_subcommand_propagate_with_explicit_display_order

are currently failing because of bug clap-rs#706.
@kbknapp
Copy link
Member

kbknapp commented Oct 27, 2016

Excellent! If it passes the prior the tests and some new one(s) for this case I'm good with it! 👍

@homu homu closed this as completed in 9cb6fac Oct 27, 2016
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
Projects
None yet
Development

No branches or pull requests

2 participants