mkideal / cli

CLI - A package for building command line app with go
MIT License
732 stars 43 forks source link

Show usage by default #18

Closed suntong closed 7 years ago

suntong commented 8 years ago

Hi,

Can you add an option to show usage help by default, when no command line options are provided please?

Many of my sub commands have complicated cli options (that's why I need cli, hehe), so I'd need to have a way to show usage help when no command line options are provided.

This is not the same as when there is some error (required argument missing) happens then show usage help, because it is all about friendliness to me. I.e., as long as friendliness is concerned, here is my view of the order going from bad to better:

  1. Complains about required argument missing
  2. Complains about required argument missing but then show usage
  3. Show usage up front, when no command line options are provided. If users have given anything else on the command line, then complains about missing arguments etc

What do you think?

mkideal commented 8 years ago

How about if I add a NumOption like NumArg?

suntong commented 8 years ago

Hmm... will it work even when all parameters should be provided as cli options? Oh, yeah, gotya, Yep, me too think it should work.

mkideal commented 8 years ago

NumOption is added.

suntong commented 8 years ago

Thanks, send you some PM, to the one you listed on github.com.

suntong commented 8 years ago

Documenting our conversation in PM, please take a look at

https://github.com/suntong/lang/blob/master/lang/Go/src/sys/CLI/027-global-redo/redoCmds.go#L119-L126

I.e.,

var publishCmd = &cli.Command{
    Name: "publish",
    Desc: "Publish the network application",
    Argv: func() interface{} { return new(publishT) },
    Fn:   publish,

    NumOption: cli.AtLeast(1),
}

The NumOption: cli.AtLeast(1) should work exactly as NumArg: cli.AtLeast(1). E.g., https://github.com/suntong/lang/blob/master/lang/Go/src/sys/CLI/027-global-redo/redoCmds.go#L98

However, their behavior are different:

$ redo install
Install the network application
...

$ redo publish 
ERR! required argument --dir missing
mkideal commented 8 years ago

Now, everything is OK, See commit 1ed3d0d

suntong commented 8 years ago

Hmm.... redo publish still complains about required argument missing, but it does show usage first now:

$ redo publish 
Publish the network application

Options:

  -h, --help
      display help information
...
  -l, --list
      list all sub commands
ERR! required argument --dir missing

Can we get rid of that complaining, :-)?

mkideal commented 8 years ago

See commit 13e2fe4.

suntong commented 8 years ago

Perfect! Thanks a lot for your hard works!

suntong commented 8 years ago

Hi 仕晋,

Found a very strange error, please take a look at https://gist.github.com/suntong/9b85f3f96f6d9333701ce4a78e3221b3#file-dump-go

This is what i got when run it:

$ go run /tmp/dump.go dump
ERR! required argument --input missing

What strange is I have my demo code working for this case -- https://gist.github.com/suntong/c387dffef76b02df85f18857cf11d66a

echo '{}' > redo.json

$ go run /tmp/027-global-redo.go install
Install the network application

Usage:
  redo install [Options] package [package...]
...

To me the two code are exactly the same:

var dumpDef = &cli.Command{
    Name: "dump",
    Desc: "*Dump as text-only file",
    Argv: func() interface{} { return new(dumpT) },
    Fn:   dumpCLI,

    NumArg:      cli.AtLeast(1),
    CanSubRoute: true,
}

func dumpCLI(ctx *cli.Context) error {
    rootArgv := ctx.RootArgv().(*rootT)
    argv := ctx.Argv().(*dumpT)
    fmt.Printf("[dump]:\n  %+v\n  %+v\n  %v\n", rootArgv, argv, ctx.Args())
    return nil
}
var installDef = &cli.Command{
    Name: "install",
    Desc: "Install the network application",
    Text: "Usage:\n  redo install [Options] package [package...]",
    Argv: func() interface{} { return new(installT) },
    Fn:   installCLI,

    NumArg:      cli.AtLeast(1),
    CanSubRoute: true,
}

func installCLI(ctx *cli.Context) error {
    rootArgv := ctx.RootArgv().(*rootT)
    argv := ctx.Argv().(*installT)
    fmt.Printf("[install]:\n  %+v\n  %+v\n  %v\n", rootArgv, argv, ctx.Args())
    return nil
}

So why the two behaves differently? Thx

mkideal commented 8 years ago
Dir    string `cli:"*d,dir" usage:"source code root dir" dft:"./"`

Note the dft tag. If dft tag is specified with a non-empty value, required argument have been present.

suntong commented 8 years ago

Oh, that's where I forgot to change -- I should have removed it as mandatory options should not have default values.

So the behavior of dump.go would be the normal usage. In this case, when none-option parameters are needed, and they are less than NumArg, let's show usage help without complaining. Make sense? thx.

mkideal commented 8 years ago

See commit 7bfc6df

suntong commented 8 years ago

Perfect! and super fast as always! :+1:

suntong commented 7 years ago

Hi 仕晋,

Found another strange error, please take a look at https://gist.github.com/suntong/fdd74049660315e54fa72ecb5fd2f04e

If I run it with go run /tmp/dump.go, the help output is OK.

However, if I change "NumArg: cli.AtLeast(1)" to "NumOption: cli.AtLeast(1)", and run it with go run /tmp/dump.go, it complains about required argument missing again:

$ go run /tmp/dump.go 
ERR! required argument --input missing

Moreover, another problem, I remember that the *clix.Reader will read from stdin if file is not specified, but mine is not:

$ go run /tmp/dump.go -i
ERR! option -i invalid: missing argument

How can I correct it? Thx.

mkideal commented 7 years ago

Eh..., I run it with NumOption: cli.AtLeast(1), but the help output is OK.

mkideal commented 7 years ago

Maybe you should update cli

suntong commented 7 years ago

Oh, my bad, my home env is not properly setup as my work env. My bad, sorry.