hdl / containers

Building and deploying container images for open source electronic design automation (EDA)
https://hdl.github.io/containers/
Apache License 2.0
106 stars 24 forks source link

Showing default values for (sub)command args/opts using ArgParse/pyAttributes #23

Closed umarcor closed 3 years ago

umarcor commented 3 years ago

Formatter class ArgumentDefaultsHelpFormatter is used (https://github.com/hdl/containers/commit/8dcf3ada2c654766ae3c460c926be61cf21af048). I'd expect it to be inherited by the help of all (sub)commands. However, default values are shown for the top level help only:

# ./pyHDLC/cli.py help 
================================================================================
                    hdl/containers (HDLC) command-line tool
================================================================================
usage: cli.py [-n] {help,build,push,pull} ...

Helper tool for building one or multiple images, for easily browsing publicly available tags, and   
for generating graphs showing the dependencies between them.

positional arguments:
  {help,build,push,pull}
                        sub-command help
    help                Display help page(s) for the given command name.
    build               Build images by name.
    push                Push images by name.
    pull                Pull images by name.

optional arguments:
  -n, --noexec          print commands but do not execute them. (default: False)

Happy hacking!
# ./pyHDLC/cli.py help build
================================================================================
                    hdl/containers (HDLC) command-line tool
================================================================================
usage: cli.py build [-h] [-c COLLECTION] [-r REGISTRY] [-f DOCKERFILE] [-t TARGET] [-a ARGIMG]      
                    [-p] [-d]
                    Image [Image ...]

positional arguments:
  Image                 image name(s), without registry prefix.

optional arguments:
  -h, --help            show this help message and exit
  -c COLLECTION, --collection COLLECTION
                        name of the collection/subset of images.
  -r REGISTRY, --registry REGISTRY
                        container image registry prefix.
  -f DOCKERFILE, --dockerfile DOCKERFILE
                        dockerfile to be built, from the collection.
  -t TARGET, --target TARGET
                        target stage in the dockerfile.
  -a ARGIMG, --argimg ARGIMG
                        base image passed as an ARG to the dockerfile.
  -p, --pkg             preprend 'pkg:' to Image and set Target to 'pkg' (if unset).
  -d, --default         set default Dockerfile, Target and ArgImg options, given the image
                        name(s).

Note that -c, -r, -p and -d do have default values.

Paebbels commented 3 years ago

Is there a solution to ArgParse for this behavior?

Maybe the formatter must be applied to the subparsers too?

umarcor commented 3 years ago

https://bugs.python.org/issue21633

You can specify the 'formatter_class' when creating each subparser:

sp1=sp.add_parser('cmd1', formatter_class = argparse.RawDescriptionHelpFormatter)

The 'add_parser' command is the one that passes a variety of **kwargs to 'ArgumentParser' (or what ever parser creator is being used for the subparsers). 'add_subparsers' is more like a 'add_argument' command, creating a '_SubParsersAction' instance.

Few, if any, attributes of the main parser are propagated to the subparsers. I'd have to study the code more closely, but I think it's just the parser class that is propagated.

Paebbels commented 3 years ago

Do you think this could fix it: https://github.com/Paebbels/pyAttributes/pull/17 ?

It can be tested with:

    @CommandAttribute("build", help="Build images by name.", formatter_class=ArgumentDefaultsHelpFormatter)
    # ...
    def HandleBuild(self, args):
        # ...

If this works, I think we can release v2.1.0 of pyAttributes.

umarcor commented 3 years ago

Paebbels/pyAttributes#17 fixed it! Thanks!

This is the output with pyAttributes v2.1.0:

# ./pyHDLC/cli.py help build
================================================================================
                    hdl/containers (HDLC) command-line tool
================================================================================
usage: cli.py build [-h] [-c COLLECTION] [-r REGISTRY] [-f DOCKERFILE] [-t TARGET] [-a ARGIMG] [-p]     
                    [-d]
                    Image [Image ...]

positional arguments:
  Image                 image name(s), without registry prefix.

optional arguments:
  -h, --help            show this help message and exit
  -c COLLECTION, --collection COLLECTION
                        name of the collection/subset of images. (default: debian-buster)
  -r REGISTRY, --registry REGISTRY
                        container image registry prefix. (default: ghcr.io/hdl)
  -f DOCKERFILE, --dockerfile DOCKERFILE
                        dockerfile to be built, from the collection. (default: None)
  -t TARGET, --target TARGET
                        target stage in the dockerfile. (default: None)
  -a ARGIMG, --argimg ARGIMG
                        base image passed as an ARG to the dockerfile. (default: None)
  -p, --pkg             preprend 'pkg:' to Image and set Target to 'pkg' (if unset). (default: False)   
  -d, --default         set default Dockerfile, Target and ArgImg options, given the image name(s).     
                        (default: False)