Skip to content

explicitly print help when no arguments are given #1156

@lager1

Description

@lager1

Hi,

I would like to explicitly print full help for my script if no arguments are given. The code:

@click.command()
@click.argument('input_dir', type=click.Path(exists=True))
@click.argument('output_dir', type=click.Path(exists=True))
@click.option('-fc', 'fix_coord_chars', is_flag=True, help='fix wrong characters used in coordinates definitions')
@click.option('-fl', 'fix_lon_lat', is_flag=True, help='enable swapping of lon and lat if switched. Configure list of accepted values in config.py')
@click.option('-c', 'check_lon_lat', is_flag=True, help='check that longitude and latitude are in defined ranges. Configure list of accepted values in config.py')
@click.option('-v', 'verbose', is_flag=True, help='enable verbose output')
def cli(input_dir, output_dir, fix_coord_chars, fix_lon_lat, check_lon_lat, verbose):
  """This script converts institution.xml files to json v2 format.
  It requires positional parameters input_dir and output_dir.
  input_dir specifies the input directory with institution.xml files.
  output_dir specifies the output directory for json files.
  """

  main(input_dir, output_dir, { "fix_coord_chars" : fix_coord_chars, "fix_lon_lat" : fix_lon_lat,
                                "check_lon_lat" : check_lon_lat, "verbose" : verbose })

if __name__ == "__main__":
  cli()

I'm not getting just:

$ ./converter.py 
Usage: converter.py [OPTIONS] INPUT_DIR OUTPUT_DIR

Error: Missing argument "input_dir".

This is not acceptable for me. Also anyone using the script needs to run it explicitly with --help to view full help.

There is way to explicitly call help for defined command, composed together is looks like this:

def print_help_msg(command):
  with click.Context(command) as ctx:
    click.echo(command.get_help(ctx))

  sys.exit(1)

# ==============================================================================
@click.command()
@click.argument('input_dir', type=click.Path(exists=True), default=print_help_msg(cli))
@click.argument('output_dir', type=click.Path(exists=True), default=print_help_msg(cli))
@click.option('-fc', 'fix_coord_chars', is_flag=True, help='fix wrong characters used in coordinates definitions')
@click.option('-fl', 'fix_lon_lat', is_flag=True, help='enable swapping of lon and lat if switched. Configure list of accepted values in config.py')
@click.option('-c', 'check_lon_lat', is_flag=True, help='check that longitude and latitude are in defined ranges. Configure list of accepted values in config.py')
@click.option('-v', 'verbose', is_flag=True, help='enable verbose output')
def cli(input_dir, output_dir, fix_coord_chars, fix_lon_lat, check_lon_lat, verbose):
  """This script converts institution.xml files to json v2 format.
  It requires positional parameters input_dir and output_dir.
  input_dir specifies the input directory with institution.xml files.
  output_dir specifies the output directory for json files.
  """

  main(input_dir, output_dir, { "fix_coord_chars" : fix_coord_chars, "fix_lon_lat" : fix_lon_lat,
                                "check_lon_lat" : check_lon_lat, "verbose" : verbose })

This code is unfortunately unusable because the function referenced in arguments does not exist yet.

I've managed to achieve the functionality i need, but the code is rubbish:

@click.command()
@click.argument('input_dir', type=click.Path(exists=True))
@click.argument('output_dir', type=click.Path(exists=True))
@click.option('-fc', 'fix_coord_chars', is_flag=True, help='fix wrong characters used in coordinates definitions')
@click.option('-fl', 'fix_lon_lat', is_flag=True, help='enable swapping of lon and lat if switched. Configure list of accepted values in config.py')
@click.option('-c', 'check_lon_lat', is_flag=True, help='check that longitude and latitude are in defined ranges. Configure list of accepted values in config.py')
@click.option('-v', 'verbose', is_flag=True, help='enable verbose output')
def cli(input_dir, output_dir, fix_coord_chars, fix_lon_lat, check_lon_lat, verbose):
  """This script converts institution.xml files to json v2 format.
  It requires positional parameters input_dir and output_dir.
  input_dir specifies the input directory with institution.xml files.
  output_dir specifies the output directory for json files.
  """

  main(input_dir, output_dir, { "fix_coord_chars" : fix_coord_chars, "fix_lon_lat" : fix_lon_lat,
                                "check_lon_lat" : check_lon_lat, "verbose" : verbose })

# ==============================================================================
def print_help_msg(command):
  with click.Context(command) as ctx:
    click.echo(command.get_help(ctx))

  sys.exit(1)

# ==============================================================================
# duplicated here to define default for arguments
# ==============================================================================
@click.command()
@click.argument('input_dir', type=click.Path(exists=True), default=print_help_msg(cli))
@click.argument('output_dir', type=click.Path(exists=True), default=print_help_msg(cli))
@click.option('-fc', 'fix_coord_chars', is_flag=True, help='fix wrong characters used in coordinates definitions')
@click.option('-fl', 'fix_lon_lat', is_flag=True, help='enable swapping of lon and lat if switched. Configure list of accepted values in config.py')
@click.option('-c', 'check_lon_lat', is_flag=True, help='check that longitude and latitude are in defined ranges. Configure list of accepted values in config.py')
@click.option('-v', 'verbose', is_flag=True, help='enable verbose output')
def cli(input_dir, output_dir, fix_coord_chars, fix_lon_lat, check_lon_lat, verbose):
  """This script converts institution.xml files to json v2 format.
  It requires positional parameters input_dir and output_dir.
  input_dir specifies the input directory with institution.xml files.
  output_dir specifies the output directory for json files.
  """

  main(input_dir, output_dir, { "fix_coord_chars" : fix_coord_chars, "fix_lon_lat" : fix_lon_lat,
                                "check_lon_lat" : check_lon_lat, "verbose" : verbose })


if __name__ == "__main__":
  cli()

Can you please provide a clean way to solve this?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions