Easier way to define option and command groups
Opened this issue · 0 comments
dwreeves commented
Overview
I think the option and command group API is a little clunky and could be easier to use.
The API was designed with the global config in mind. Since version 1.7, however, the global config is no longer the only way to define config; the API has moved closer to the definition of commands.
Brain Dump
I don't know the best way to proceed here, but here's one idea:
import rich_click as click
@click.group
@click.option("--option1", option_group_name="foo")
@click.option("--option2", option_group_name="foo")
@click.option("--option3")
@click.rich_config(help_config=click.RichHelpConfiguration(
option_groups=[
{
"name": "foo",
"table_styles": {
"show_lines": False
}
},
{
"name": "bar",
"options": ["--option3"]
"table_styles": {
"border_style": "red"
}
}
]
))
def cli(option1, option2):
pass
@cli.command
@click.option("--option1", option_group_name="foo")
@click.option("--option2")
@click.option("--option3")
def subcommand(option1, option2, option3):
pass
cli()
In the above example, a few things are happening of note:
option_groups
is not aDict[str, List[OptionGroupDict]]
, it is aList[OptionGroupDict]
.- The option group assignment is defined in the options, not in the
OptionGroupDict
. However thetable_Styles
are still applied. - I think the
OptionGroupDict
should be entirely optional; if left undefined, the grouping should still occur. - The subcommand presents an interesting case when passing context. Here are the most intuitive behaviors to me:
option1
should be assigned tofoo
and should retain the table styles, since the table styles were defined in the parent context.option2
should be ungrouped.option3
in the subcommand should still be grouped withbar
and should retain the table styles, since it was listed in"options": ["--option3"]
.
- What about if you define a
Dict[str, List[OptionGroupDict]]
instead of aList
? Should there still be a way to pass config to subcommands? Perhaps a wildcard such as*
should be allowed that will apply to all subcommands.- And hey, should defining
option_groups
as a list be disallowed entirely, or should that be supported? We can do anif isinstance(option_groups, list): option_groups = {"*": option_groups}
to transform it into a dict with all the behaviors we expect based on the above proposals. But perhaps the user should do that themselves.
- And hey, should defining
- Is
option_group_name=...
too verbose? Should it just beoption_group=...
?- I'm worried about naming for
command_group
s, since a "Group" is already a concept in Click. I don't know that there will be an easy way to avoid some mild confusion in this context.
- I'm worried about naming for
Like I said, I'm not sure what should happen here. Open to ideas!
Lastly, all of this behavior can get quite complex and would benefit a ton from being properly documented, so I wonder if documentation should be considered a hard prerequisite for this feature. 😅