docopt / docopt.go

A command-line arguments parser that will make you smile.
http://docopt.org/
MIT License
1.43k stars 108 forks source link

Bug: Help: false with `--help` does not return options when there are required arguments #49

Closed ghostsquad closed 6 years ago

ghostsquad commented 6 years ago

Description

setting help: false, and providing --help, and having a required position argument at the command line causes docopt to not return any options/args and also print usage (without options)

Repro Steps

This is taken directly from the options_shortcut_example.

package main

import (
    "fmt"
    "github.com/docopt/docopt-go"
)

func main() {
    usage := `Example of program which uses [options] shortcut in pattern.

Usage:
  options_shortcut_example [options] <port>

Options:
  -h --help                show this help message and exit
  --version                show version and exit
  -n, --number N           use N as a number
  -t, --timeout TIMEOUT    set timeout TIMEOUT seconds
  --apply                  apply changes to database
  -q                       operate in quiet mode`

    fmt.Println("*** About To Parse ****")
    arguments, _ := docopt.Parse(usage, nil, false, "1.0.0rc2", false)
    fmt.Println("*** Done Parsing ****")
    fmt.Println(arguments)
}

Expected Output

( with exit: false and help: false )

$ go run options_shortcut_example.go --help
*** About To Parse ****
*** Done Parsing ****
map[--number:<nil> --timeout:<nil> --apply:false -q:false <port>:<nil> --help:true --version:false]

From reading the docs, I expect to get options back from the parser when --help is on the commandline and help: false parse option is used. The whole idea of help: false is so I can print a custom message, or perform other work.

Actual Output

$ go run options_shortcut_example.go --help
*** About To Parse ****
Usage:
  options_shortcut_example [options] <port>
exit status 1

$ go run options_shortcut_example.go
*** About To Parse ****
Usage:
  options_shortcut_example [options] <port>
exit status 1

When exit is set to false, you can also see there are no options:

$ go run options_shortcut_example.go --help
*** About To Parse ****
Usage:
  options_shortcut_example [options] <port>
*** Done Parsing ****
map[]

This is most likely because the <port> positional argument is required, and because it wasn't provided. But that means that --help is no longer special.

Workaround

Usage:
   options_shortcut_example [-h|--help]|([options] <port>)

This seems to work, as it indicates you can either get help, or run the actual command. But this is super hacky, and defeats the elegance of this framework. It also means --help is no longer special.

ghostsquad commented 6 years ago

I forgot you can have multiple usage patterns. This is solved with

Usage:
   options_shortcut_example [options] <port>
   options_shortcut_example -h | --help