Skip to content
This repository has been archived by the owner on Jun 4, 2019. It is now read-only.

Commit

Permalink
Merge pull request #83 from unihorn/102
Browse files Browse the repository at this point in the history
bump(codegangsta/cli): bb9189510
  • Loading branch information
philips committed Jun 23, 2014
2 parents 061135b + b199e5b commit 5f51e04
Show file tree
Hide file tree
Showing 12 changed files with 772 additions and 45 deletions.
64 changes: 63 additions & 1 deletion third_party/github.com/codegangsta/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Command line apps are usually so tiny that there is absolutely no reason why you
This is where cli.go comes into play. cli.go makes command line programming fun, organized, and expressive!

## Installation
Make sure you have the a working Go environment (go 1.1 is *required*). [See the install instructions](http://golang.org/doc/install.html).
Make sure you have a working Go environment (go 1.1 is *required*). [See the install instructions](http://golang.org/doc/install.html).

To install cli.go, simply run:
```
Expand Down Expand Up @@ -187,9 +187,71 @@ app.Commands = []cli.Command{
println("completed task: ", c.Args().First())
},
},
{
Name: "template",
ShortName: "r",
Usage: "options for task templates",
Subcommands: []cli.Command{
{
Name: "add",
Usage: "add a new template",
Action: func(c *cli.Context) {
println("new task template: ", c.Args().First())
},
},
{
Name: "remove",
Usage: "remove an existing template",
Action: func(c *cli.Context) {
println("removed task template: ", c.Args().First())
},
},
},
},
}
...
```

### Bash Completion

You can enable completion commands by setting the EnableBashCompletion
flag on the App object. By default, this setting will only auto-complete to
show an app's subcommands, but you can write your own completion methods for
the App or its subcommands.
```go
...
var tasks = []string{"cook", "clean", "laundry", "eat", "sleep", "code"}
app := cli.NewApp()
app.EnableBashCompletion = true
app.Commands = []cli.Command{
{
Name: "complete",
ShortName: "c",
Usage: "complete a task on the list",
Action: func(c *cli.Context) {
println("completed task: ", c.Args().First())
},
BashComplete: func(c *cli.Context) {
// This will complete if no args are passed
if len(c.Args()) > 0 {
return
}
for _, t := range tasks {
println(t)
}
},
}
}
...
```

#### To Enable

Source the autocomplete/bash_autocomplete file in your .bashrc file while
setting the PROG variable to the name of your program:

`PROG=myprogram source /.../cli/autocomplete/bash_autocomplete`


## About
cli.go is written by none other than the [Code Gangsta](http://codegangsta.io)
111 changes: 102 additions & 9 deletions third_party/github.com/codegangsta/cli/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,17 @@ type App struct {
Commands []Command
// List of flags to parse
Flags []Flag
// Boolean to enable bash completion commands
EnableBashCompletion bool
// An action to execute when the bash-completion flag is set
BashComplete func(context *Context)
// An action to execute before any subcommands are run, but after the context is ready
// If a non-nil error is returned, no subcommands are run
Before func(context *Context) error
// The action to execute when no subcommands are specified
Action func(context *Context)
// Execute this function if the proper command cannot be found
CommandNotFound func(context *Context, command string)
// Compilation date
Compiled time.Time
// Author
Expand All @@ -46,13 +52,14 @@ func compileTime() time.Time {
// Creates a new cli Application with some reasonable defaults for Name, Usage, Version and Action.
func NewApp() *App {
return &App{
Name: os.Args[0],
Usage: "A new cli application",
Version: "0.0.0",
Action: helpCommand.Action,
Compiled: compileTime(),
Author: "Author",
Email: "unknown@email",
Name: os.Args[0],
Usage: "A new cli application",
Version: "0.0.0",
BashComplete: DefaultAppComplete,
Action: helpCommand.Action,
Compiled: compileTime(),
Author: "Author",
Email: "unknown@email",
}
}

Expand All @@ -64,8 +71,11 @@ func (a *App) Run(arguments []string) error {
}

//append version/help flags
a.appendFlag(BoolFlag{"version, v", "print the version"})
a.appendFlag(BoolFlag{"help, h", "show help"})
if a.EnableBashCompletion {
a.appendFlag(BashCompletionFlag)
}
a.appendFlag(VersionFlag)
a.appendFlag(HelpFlag)

// parse flags
set := flagSet(a.Name, a.Flags)
Expand All @@ -88,6 +98,10 @@ func (a *App) Run(arguments []string) error {
return err
}

if checkCompletions(context) {
return nil
}

if checkHelp(context) {
return nil
}
Expand Down Expand Up @@ -117,6 +131,85 @@ func (a *App) Run(arguments []string) error {
return nil
}

// Invokes the subcommand given the context, parses ctx.Args() to generate command-specific flags
func (a *App) RunAsSubcommand(ctx *Context) error {
// append help to commands
if len(a.Commands) > 0 {
if a.Command(helpCommand.Name) == nil {
a.Commands = append(a.Commands, helpCommand)
}
}

// append flags
if a.EnableBashCompletion {
a.appendFlag(BashCompletionFlag)
}
a.appendFlag(HelpFlag)

// parse flags
set := flagSet(a.Name, a.Flags)
set.SetOutput(ioutil.Discard)
err := set.Parse(ctx.Args().Tail())
nerr := normalizeFlags(a.Flags, set)
context := NewContext(a, set, set)

if nerr != nil {
fmt.Println(nerr)
if len(a.Commands) > 0 {
ShowSubcommandHelp(context)
} else {
ShowCommandHelp(ctx, context.Args().First())
}
fmt.Println("")
return nerr
}

if err != nil {
fmt.Printf("Incorrect Usage.\n\n")
ShowSubcommandHelp(context)
return err
}

if checkCompletions(context) {
return nil
}

if len(a.Commands) > 0 {
if checkSubcommandHelp(context) {
return nil
}
} else {
if checkCommandHelp(ctx, context.Args().First()) {
return nil
}
}

if a.Before != nil {
err := a.Before(context)
if err != nil {
return err
}
}

args := context.Args()
if args.Present() {
name := args.First()
c := a.Command(name)
if c != nil {
return c.Run(context)
}
}

// Run default Action
if len(a.Commands) > 0 {
a.Action(context)
} else {
a.Action(ctx)
}

return nil
}

// Returns the named command on App. Returns nil if the command does not exist
func (a *App) Command(name string) *Command {
for _, c := range a.Commands {
Expand Down
Loading

0 comments on commit 5f51e04

Please sign in to comment.