Giter Site home page Giter Site logo

urfave / cli Goto Github PK

View Code? Open in Web Editor NEW
21.6K 21.6K 1.7K 10.71 MB

A simple, fast, and fun package for building command line apps in Go

Home Page: https://cli.urfave.org

License: MIT License

Go 99.46% Makefile 0.20% Shell 0.24% PowerShell 0.10%
cli command-line go golang-library json toml yaml

cli's Introduction

Welcome to urfave/cli

Run Tests Go Reference Go Report Card codecov

urfave/cli is a declarative, simple, fast, and fun package for building command line tools in Go featuring:

  • commands and subcommands with alias and prefix match support
  • flexible and permissive help system
  • dynamic shell completion for bash, zsh, fish, and powershell
  • man and markdown format documentation generation
  • input flags for simple types, slices of simple types, time, duration, and others
  • compound short flag support (-a -b -c ➡️ -abc)
  • input lookup from:

Documentation

More documentation is available in ./docs or the hosted documentation site published from the latest release at https://cli.urfave.org.

Q&A

Please check the Q&A discussions or ask a new question.

License

See LICENSE

cli's People

Contributors

abitrolly avatar anberns avatar asahasrabuddhe avatar audriusbutkevicius avatar blaubaer avatar codegangsta avatar coilysiren avatar dearchap avatar drov0 avatar fernandezvara avatar grubernaut avatar hay-kot avatar hirose31 avatar james-prysm avatar joshfrench avatar jszwedko avatar marwan-at-work avatar mattfarina avatar meatballhat avatar mostynb avatar phinnaeus avatar rliebz avatar russoj88 avatar saschagrunert avatar skelouse avatar tarampampam avatar toaster avatar tomontime avatar vkd avatar xwjdsh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cli's Issues

Print in colors using the AppHelpTemplate

I want to print some parts (like usage examples) of the AppHelpTemplate in color (using ANSI escape codes).

I tried wrapping the text in escape codes, but couldn't get it to work. Rather than escaping, the text is printed on the terminal as is along with the codes.

I did something like:

var AppHelpTemplate = `\x1b[33;1m{{.Name}} - {{.Usage}}\x1b[0m`

Flags in commands

app.Commands = []cli.Command{
  {
    Name: "command",
    Action: func(c *cli.Context) {
      println("command")
    },
  },
}

I expected appending --help with only show usage but:

$ ./app command --help
Usage of command:
command

Terser help templates

The help template prints titles like OPTIONS or DESCRIPTION even when there is no content for them. Maybe a few {{if}}’s in there to reduce the verbosity when there is nothing to say?

(Happy to implement if we agree this is desirable.)

using StringSlice results in formatting error in help

Sample code:

app := cli.NewApp()
app.Name = "test"
app.Usage = "hello"
command := cli.Command{
    Name:  "cmd",
    Usage: "does stuff",
    Flags: []cli.Flag{
        cli.IntSliceFlag{Name: "p", Value: &cli.IntSlice{}, Usage: "set one or more ip addr"},
        cli.StringSliceFlag{Name: "ip", Value: &cli.StringSlice{}, Usage: "set one or more ports to open"},
    },
    Action: func(c *cli.Context) {

    },
}
app.Commands = []cli.Command{command}
//app.Run([]string{"", "cmd", "my-arg", "-p", "22", "-p", "80", "-ip", "8.8.8.8", "-ip", "8.8.4.4"})
app.Run([]string{"", "help", "cmd"})

results in:

NAME:
   cmd - does stuff

USAGE:
   command cmd [command options] [arguments...]

DESCRIPTION:


OPTIONS:
   -p '-p option -p option'     set one or more ip addr
   -- 'ip'                      -ip option -ip option%!(EXTRA string=set one or more ports to open)

app.Run() should return an error. os.Exit(1) should be avoided

@kytrinyx @msgehard This may affect you guys so I would like to know what you think about this.

I got bit recently by this, basically when an error occurs, like incorrect usage in a FlagSet or failing to find a help topic we call an os.Exit(1). This is convenient for the most part also terminates the app when you may not desire it.

The proposal is to basically replace the os.Exit(1) with a error return on app.Run(). That way these errors can be handled any way the developer wants to. This also feels a lot more idiomatic in terms of Go.

Let me know what you think. I would really love to get this to 1.0 So the api can get locked in.

Slice Flags help output is unexpected/confusing

Using a flag such as

cli.StringSliceFlag{"lang", &cli.StringSlice{"english", "spanish"}, "language for the greeting"},

results in help output like this:

OPTIONS:
   --lang [english spanish] `-lang option -lang option` language for the greeting

What exactly is the intended meaning of "-lang option -lang option"? Am I just uninformed or is this a WIP? I'd be happy to work on it if I know what it's supposed to do! :)

Interactive option

I'd really to be able to create interactive flags: when it's used, it will read it's value from standard input.

example:

$ mycmdlineapp --ask-password
password: *******

It's golang usage could like:

cli.InteractiveFlag{"ask-password, a, password", "default-password", "Asks for password"}

What do you think?

mandatory argument

how can I make a mandatory argument?

also I want to use the first parameter without the flag, but include it in the help also. whats the best way?

eg
Usage: myapp myargument

Was "eb027661af08a193a5f8a33528a44a80e9dc58ae" removed from master's history?

We noticed this in our CI:

cd /mnt/jenkins/jobs/tabasco-runtime-cf-deploy/workspace/gospace/src/github.com/codegangsta/cli; git pull --ff-only
fatal: Not possible to fast-forward, aborting.
package github.com/cloudfoundry-incubator/spiff
    imports github.com/cloudfoundry-incubator/spiff/compare
    imports github.com/cloudfoundry-incubator/spiff/yaml
    imports launchpad.net/goyaml
    imports github.com/cloudfoundry-incubator/spiff/dynaml
    imports github.com/cloudfoundry-incubator/spiff/flow
    imports github.com/codegangsta/cli: exit status 128
error: Command failed: "go get -u -v github.com/cloudfoundry-incubator/spiff" (options: {})    # 2014-01-06 23:37:14 +0000

The commit was:

commit eb027661af08a193a5f8a33528a44a80e9dc58ae
Merge: 1cb2291 69b5310
Author: Jeremy Saenz <[email protected]>
Date:   Thu Jan 2 08:36:08 2014 -0800

    Merge pull request #58 from tjarratt/master

    Allow flags to omit their default value in String()

Add support for argument definition

The help template contains just [arguments...], but it would be very useful if it was possible to define those arguments (optional arguments including) and see them in help, i.e. to se ARG1 ARG2 [ARG2] in the usage if ARG2 is optional instead of just [arguments...].

Telnet interface

I'd love to be able to use cli.go to create a telnet interface for applications that would allow me to inspect and manipulate the program's running state. I haven't looked into how easy or difficult this would be, but consider it a wishlist item if you get the time for it :-)

Help flag is not making the app exit when used with a subcommand

Hi,

I was just wondering if it is desired to run <prog> <subcmd> -h and still have the action assigned to that subcommand executed. That is what is happening now for me - the action is triggered even though -h is present.

I think that this would lead to having all the subcommand actions starting with like if -h is present then exit(1).

Cheers

Double dash for keyword flags vs single dash for character flags

I noticed that in some applications, character flags are grouped by a single hyphen, while keyword flags must be prepended with a double-hyphen.

For example:
myapp -asdf

Would be the equivalent to:
myapp -a -s -d -f

However,
myapp --asdf

Refers to the keyword flag 'asdf'

Is this something that may be considered for a later version?

Support for default command when using subcommands

This may already be doable..

In my own Python lib called Skal (which does the same thing as this one) inserting the default command in the args before using the library works but is a ugly work around. I tried this in Go also, and it works! But it is still a little unclean:

func main() {
    fmt.Println(os.Args)
    // Make sure to only add "test" if no other subcommand is set..
    os.Args = append(os.Args, "test")
    fmt.Println(os.Args)
}

Would it be possible to set which subcommand (or another command) that will be called when no subcommand is specified?

Allow applications to further customize app help

I'm writing a CLI app and we've customized the help output for the application by creating a help command that you can invoke with my-tool help. We can't just override the template because we also want to change the order of some commands and group them. Today we noticed that if you just provide the -h or --help flag then the app help is printed from codegangsta/cli, and not our custom help command.

It's great that you can customize the application help template by overriding the cli.AppHelpTemplate string, but it seems like a more useful thing would be to allow applications to set a function that prints out the app help.

eg:

cli/help.go

// Prints help for the App
var HelpPrinter = printHelp

func ShowAppHelp(c *Context) {
        HelpPrinter(AppHelpTemplate, c.App)
}

Thoughts? I'd be more than willing to write a PR for this behavior if this seems reasonable.

Required Flags

It would be really nice to have required flags and required arguments. I'm mostly putting this here as a place holder to discuss although I would be willing to put some work in on this if we can talk about how we would like to implement it.

I was thinking the easiest would just add a new field to the struct called "Required". Internally we could have some checking and fail if the required flag is not set.

type Flag interface {
    fmt.Stringer
    Required bool
    // Apply Flag settings to the given flag set
    Apply(*flag.FlagSet)
    getName() string
}

func (f *Flag) IsRequired() bool {
  return f.Required
}

Ability to parse array types

It would to be nice to parse arrays for string and int types

example:
./app create -dns 8.8.8.8 -dns 8.8.4.4 server.domain.tld

something like :
cli.ArrayStringFlag{"dns", "8.8.8.8", "set one or more dns Servers"}

Thanks in advance for this awesome app

Subcommand help

I maybe missing this, and I have looked through most of the other issues both open and closed, but I cant find anything related to this issue/feature.

If I have a sub command of a command cli command sub-command, is there a help section for the sub-command.

When I run cli help, I get the global help template with commands and global flags, and when running cli help command I again get the help template with description and command specific flag options, but I can't seem to find anyway on getting help with sub-commands of a command.

IE
If I had a cli that had a command called server, and sub-commands to server called start, stop, etc... Is there a way to get a list of those sub-commands via help?

`go vet` errors

Basically,

$ go vet ./...
app_test.go:46: cli.StringFlag composite literal uses unkeyed fields
cli_test.go:50: cli.StringFlag composite literal uses unkeyed fields
cli_test.go:60: cli.StringFlag composite literal uses unkeyed fields
cli_test.go:70: cli.StringFlag composite literal uses unkeyed fields
exit status 1

Separate Template for "Incorrect Usage"

Currently, when a user passes an unidentified argument, like app --badargument, the ShowAppHelp function is called, which uses the AppHelpTemplate.

This behavior is fine, but, I think showing the entire help might not always be nice idea. Like git only shows the common usage when a bad argument is passed.

So, it'll be better if there were a separate IncorrectUsageTemplate which will offer greater flexibility.

Different Args in "Action" and "Before" functions

I recently came across a problem when accessing Args from Context. I expected to get the same args in "Action" and "Before" functions, but "Action" has it's name at index 0 and arguments start from index 1, in "Before" arguments start from index 0.

An example to demonstrate: http://play.golang.org/p/CIrOdw3noq

Also looking at the examples https://github.com/codegangsta/cli#subcommands
I'd expect c.Args().First() to contain the first argument, not the command name itself. Is this desired behaviour, please?

Help Flags

Hi, is it a conscious design decision not to have help flags? I just wonder because this seems nasty but I don't know how else to do it.

rnd.Action = func(context *cli.Context) {

    // halp hax
    for _, comm := range rnd.Commands {
        if comm.HasName("help") {
            comm.Action(context)
            os.Exit(0)
        }
    }

    // do some stuff in the default (empty) context
    fmt.Printf("Debug: %v\n", context.Bool("debug"))
    fmt.Printf("Port: %d\n", context.Int("port"))
}

Or maybe I'm just missing something fundamental =]

-v/--version would be better as a subcommand

In my opinion it would make more sense to have -v/--version as a subcommand than a global option. It seems like the general theme is that subcommands make the app do something, whereas global options modify the behavior of whatever subcommand is selected. In this vein I think it would also make sense to remove -h/--help and solely use the h/help subcommands.

Let me know what you think. Obviously this breaks the API slightly, so maybe it would have to wait a version? If this seems like a good idea I'd be happy to submit a pull request implementing it.

PS: Thanks for how awesome and easy to use cli is. ❤️

Reordering of args to Command if BoolFlag is after args

if a Command is invoked as cli cmd arg1 -f arg2 where -f is a BoolFlag the result of ctx.Args() in the command function will be [arg2 arg1].

This appears to be related to #36

I have made the test case below (which currrently fails), but I am not really able to find a decent fix.

func TestApp_CommandWithBoolFlagAfterArgs(t *testing.T) {

    var args []string

    app := cli.NewApp()
    command := cli.Command{
        Name: "cmd",
        Flags: []cli.Flag{
            cli.BoolFlag{
                Name:  "f",
                Usage: "foo",
            },
        },
        Action: func(c *cli.Context) {
            args = c.Args()
        },
    }
    app.Commands = []cli.Command{command}
    app.Run([]string{"", "cmd", "1", "2", "-f", "3"})

    expect := []string{"1", "2", "3"}
    if !reflect.DeepEqual(args, expect) {
        t.Errorf("Got %v (type %T) - expected %v (type %T)", args, args, expect, expect)
    }
}

Fails with

    app_test.go:216: Got [3 1 2] (type []string) - expected [1 2 3] (type []string)

Hope you can come up with something good.

flag parsing terminator is broken

I want to be able to use the classic -- command parsing terminator in an app using the cli package. However, something strange happens:

./example  --lang english echo  foobar  python myscript.py
foobar [python myscript.py]
./example  --lang english echo  foobar -- python myscript.py -d
python [myscript.py -d foobar]

foobar is jumping from the 0th arg to the 2nd arg if the -- terminator is given! I haven't started digging into the code but this is rather suprising.

package main

import (
    "fmt"
    "os"

    "github.com/codegangsta/cli"
)

func main() {
    app := cli.NewApp()
    app.Flags = []cli.Flag {
        cli.StringFlag{"lang, l", "english", "language for the greeting"},
    }
    app.Commands = []cli.Command{
        {
            Name: "echo",
            Flags: []cli.Flag{
                cli.StringFlag{"newline, n", "yes", "print newline"},
            },

            Action: func(c *cli.Context) {
                args := c.Args()
                println(args[0], fmt.Sprintf("%v", args[1:]))
            },
        },
    }

    app.Run(os.Args)
}

allow actions to return its execution status.

Hi,

Like what is already possible for 'Before' actions, i found useful and somewhat logical to have 'Actions' return something on exit, so that app.Run() gets to catch all errors, if any, underneath it. Please look at 52496bf in case you care.

All the best

Let commands access top-level flags?

I'm not sure if I'm doing something wrong or if cli doesn't support this. I have an app with lots of subcommands, and I'd like to have some global flags that apply for every command (e.g. specifying the location of a config file). (Right now the commands don't have any command-specific flags, but potentially I could want both global flags and command specific flags).

If I specify the flags in the top level app.Flags, I can't seem to extract their value from the context in the action -- I always get empty strings back. Instead, I have to repeat the flags in each command definition for it to work. Is this the intended behaviour (top-level flags don't do anything for commands)?

[Q] Exiting on help message.

I apologize if this is obvious and I'm just missing it, but I'm trying to figure out how to os.Exit(0) when help is called via help, h, --help and -h. All print the help message, but none exit by default and I can't seem to find a simple way to for the exit. I attempted adding checking to my app.Action declaration, but that seems to be executed only if help isn't specified. This seems like something most applications would want to do by default.

Here's a simplified example -- http://play.golang.org/p/PEdNXSMvJ8.

Cheers and thanks in advance,
J

Possible to have flags in a subcommand?

Is there any way to do that?

I did give it a shot, but got this error:

./main.go:244: cannot use []cli.Flag literal (type []cli.Flag) as type []cli.Command in field value

Make the context argument optional

One of the ideas behind cli.go is progressive enhancement. A app developer should just be able to get running with cli.go in 2 lines:

cli.Action = func(){ println("Hello world") }
cli.Run(os.Args)

App (or Context?) should carry Stdin/out or io.Writer

If Actions wish to write out to console while remaining stateless, they should have access to means for doing so on the Context. Calling fmt.Print or os.Stdout from within the Action func feels stateful, and it is.

Seems more desirable that Actions might write to Context.Stdout or to Context.Writer or similar. Then the entire context really is within Context.

(Heck, os.Stdout is an os.File, that opens up a nice set of functionality.)

Allow App.Run to run more than once

right now appending default flags assumes that the app will only be run once. This is fine in most circumstances but got bit by it in a new command line app I am working on

Help Sub-Command Options

List sub-command options on:
$ cli help

and

$ cli sub-command help

Now it only lists global options

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.