pacak / bpaf

Command line parser with applicative interface
337 stars 17 forks source link

Top-level "Available options" move to the bottom of the help text when using `group_help` #354

Open abey79 opened 4 months ago

abey79 commented 4 months ago

Consider the command chaining example from the docs:

use bpaf::{construct, long, positional, short, OptionParser, Parser};

#[derive(Debug, Clone)]
pub struct Options {
    premium: bool,
    commands: Vec<Cmd>,
}

#[derive(Debug, Clone)]
// shape of the variants doesn't really matter, let's use all of them :)
enum Cmd {
    Eat(String),
    Drink { coffee: bool },
    Sleep { time: usize },
}

fn cmd() -> impl Parser<Cmd> {
    let eat = positional::<String>("FOOD")
        .to_options()
        .descr("Performs eating action")
        .command("eat")
        .adjacent()
        .map(Cmd::Eat);

    let coffee = long("coffee")
        .help("Are you going to drink coffee?")
        .switch();
    let drink = construct!(Cmd::Drink { coffee })
        .to_options()
        .descr("Performs drinking action")
        .command("drink")
        .adjacent();

    let time = long("time").argument::<usize>("HOURS");
    let sleep = construct!(Cmd::Sleep { time })
        .to_options()
        .descr("Performs taking a nap action")
        .command("sleep")
        .adjacent();

    construct!([eat, drink, sleep])
}

pub fn options() -> OptionParser<Options> {
    let premium = short('p')
        .long("premium")
        .help("Opt in for premium serivces")
        .switch();
    let commands = cmd().many();
    construct!(Options { premium, commands }).to_options()
}

fn main() {
    println!("{:?}", options().run())
}

It yields the following help string:

Usage: bug [-p] [COMMAND ...]...

Available options:
    -p, --premium  Opt in for premium serivces
    -h, --help     Prints help information

Available commands:
    eat            Performs eating action
    drink          Performs drinking action
    sleep          Performs taking a nap action

Now, add a group help to the command parser:

-    construct!([eat, drink, sleep])
+    construct!([eat, drink, sleep]).group_help("My Commands")

The help string is now changed to the following:

Usage: bug [-p] [COMMAND ...]...

My Commands
    eat            Performs eating action
    drink          Performs drinking action
    sleep          Performs taking a nap action

Available options:
    -p, --premium  Opt in for premium serivces
    -h, --help     Prints help information

In particular, notice how the "Available options" section is now at the bottom. This could be annoying if the total number of commands is large.

Reproduced with bpaf 0.9.11

pacak commented 4 months ago

This is the current behavior, I have some ideas to how to make this more flexible but nothing concrete yet.