1[![Coverage](http://gocover.io/_badge/github.com/codegangsta/cli?0)](http://gocover.io/github.com/codegangsta/cli) 2[![Build Status](https://travis-ci.org/codegangsta/cli.png?branch=master)](https://travis-ci.org/codegangsta/cli) 3[![GoDoc](https://godoc.org/github.com/codegangsta/cli?status.svg)](https://godoc.org/github.com/codegangsta/cli) 4 5# cli.go 6`cli.go` is simple, fast, and fun package for building command line apps in Go. The goal is to enable developers to write fast and distributable command line applications in an expressive way. 7 8## Overview 9Command line apps are usually so tiny that there is absolutely no reason why your code should *not* be self-documenting. Things like generating help text and parsing command flags/options should not hinder productivity when writing a command line app. 10 11**This is where `cli.go` comes into play.** `cli.go` makes command line programming fun, organized, and expressive! 12 13## Installation 14Make sure you have a working Go environment (go 1.1+ is *required*). [See the install instructions](http://golang.org/doc/install.html). 15 16To install `cli.go`, simply run: 17``` 18$ go get github.com/codegangsta/cli 19``` 20 21Make sure your `PATH` includes to the `$GOPATH/bin` directory so your commands can be easily used: 22``` 23export PATH=$PATH:$GOPATH/bin 24``` 25 26## Getting Started 27One of the philosophies behind `cli.go` is that an API should be playful and full of discovery. So a `cli.go` app can be as little as one line of code in `main()`. 28 29``` go 30package main 31 32import ( 33 "os" 34 "github.com/codegangsta/cli" 35) 36 37func main() { 38 cli.NewApp().Run(os.Args) 39} 40``` 41 42This app will run and show help text, but is not very useful. Let's give an action to execute and some help documentation: 43 44``` go 45package main 46 47import ( 48 "os" 49 "github.com/codegangsta/cli" 50) 51 52func main() { 53 app := cli.NewApp() 54 app.Name = "boom" 55 app.Usage = "make an explosive entrance" 56 app.Action = func(c *cli.Context) { 57 println("boom! I say!") 58 } 59 60 app.Run(os.Args) 61} 62``` 63 64Running this already gives you a ton of functionality, plus support for things like subcommands and flags, which are covered below. 65 66## Example 67 68Being a programmer can be a lonely job. Thankfully by the power of automation that is not the case! Let's create a greeter app to fend off our demons of loneliness! 69 70Start by creating a directory named `greet`, and within it, add a file, `greet.go` with the following code in it: 71 72``` go 73package main 74 75import ( 76 "os" 77 "github.com/codegangsta/cli" 78) 79 80func main() { 81 app := cli.NewApp() 82 app.Name = "greet" 83 app.Usage = "fight the loneliness!" 84 app.Action = func(c *cli.Context) { 85 println("Hello friend!") 86 } 87 88 app.Run(os.Args) 89} 90``` 91 92Install our command to the `$GOPATH/bin` directory: 93 94``` 95$ go install 96``` 97 98Finally run our new command: 99 100``` 101$ greet 102Hello friend! 103``` 104 105`cli.go` also generates neat help text: 106 107``` 108$ greet help 109NAME: 110 greet - fight the loneliness! 111 112USAGE: 113 greet [global options] command [command options] [arguments...] 114 115VERSION: 116 0.0.0 117 118COMMANDS: 119 help, h Shows a list of commands or help for one command 120 121GLOBAL OPTIONS 122 --version Shows version information 123``` 124 125### Arguments 126You can lookup arguments by calling the `Args` function on `cli.Context`. 127 128``` go 129... 130app.Action = func(c *cli.Context) { 131 println("Hello", c.Args()[0]) 132} 133... 134``` 135 136### Flags 137Setting and querying flags is simple. 138``` go 139... 140app.Flags = []cli.Flag { 141 cli.StringFlag{ 142 Name: "lang", 143 Value: "english", 144 Usage: "language for the greeting", 145 }, 146} 147app.Action = func(c *cli.Context) { 148 name := "someone" 149 if len(c.Args()) > 0 { 150 name = c.Args()[0] 151 } 152 if c.String("lang") == "spanish" { 153 println("Hola", name) 154 } else { 155 println("Hello", name) 156 } 157} 158... 159``` 160 161You can also set a destination variable for a flag, to which the content will be scanned. 162``` go 163... 164var language string 165app.Flags = []cli.Flag { 166 cli.StringFlag{ 167 Name: "lang", 168 Value: "english", 169 Usage: "language for the greeting", 170 Destination: &language, 171 }, 172} 173app.Action = func(c *cli.Context) { 174 name := "someone" 175 if len(c.Args()) > 0 { 176 name = c.Args()[0] 177 } 178 if language == "spanish" { 179 println("Hola", name) 180 } else { 181 println("Hello", name) 182 } 183} 184... 185``` 186 187See full list of flags at http://godoc.org/github.com/codegangsta/cli 188 189#### Alternate Names 190 191You can set alternate (or short) names for flags by providing a comma-delimited list for the `Name`. e.g. 192 193``` go 194app.Flags = []cli.Flag { 195 cli.StringFlag{ 196 Name: "lang, l", 197 Value: "english", 198 Usage: "language for the greeting", 199 }, 200} 201``` 202 203That flag can then be set with `--lang spanish` or `-l spanish`. Note that giving two different forms of the same flag in the same command invocation is an error. 204 205#### Values from the Environment 206 207You can also have the default value set from the environment via `EnvVar`. e.g. 208 209``` go 210app.Flags = []cli.Flag { 211 cli.StringFlag{ 212 Name: "lang, l", 213 Value: "english", 214 Usage: "language for the greeting", 215 EnvVar: "APP_LANG", 216 }, 217} 218``` 219 220The `EnvVar` may also be given as a comma-delimited "cascade", where the first environment variable that resolves is used as the default. 221 222``` go 223app.Flags = []cli.Flag { 224 cli.StringFlag{ 225 Name: "lang, l", 226 Value: "english", 227 Usage: "language for the greeting", 228 EnvVar: "LEGACY_COMPAT_LANG,APP_LANG,LANG", 229 }, 230} 231``` 232 233### Subcommands 234 235Subcommands can be defined for a more git-like command line app. 236```go 237... 238app.Commands = []cli.Command{ 239 { 240 Name: "add", 241 Aliases: []string{"a"}, 242 Usage: "add a task to the list", 243 Action: func(c *cli.Context) { 244 println("added task: ", c.Args().First()) 245 }, 246 }, 247 { 248 Name: "complete", 249 Aliases: []string{"c"}, 250 Usage: "complete a task on the list", 251 Action: func(c *cli.Context) { 252 println("completed task: ", c.Args().First()) 253 }, 254 }, 255 { 256 Name: "template", 257 Aliases: []string{"r"}, 258 Usage: "options for task templates", 259 Subcommands: []cli.Command{ 260 { 261 Name: "add", 262 Usage: "add a new template", 263 Action: func(c *cli.Context) { 264 println("new task template: ", c.Args().First()) 265 }, 266 }, 267 { 268 Name: "remove", 269 Usage: "remove an existing template", 270 Action: func(c *cli.Context) { 271 println("removed task template: ", c.Args().First()) 272 }, 273 }, 274 }, 275 }, 276} 277... 278``` 279 280### Bash Completion 281 282You can enable completion commands by setting the `EnableBashCompletion` 283flag on the `App` object. By default, this setting will only auto-complete to 284show an app's subcommands, but you can write your own completion methods for 285the App or its subcommands. 286```go 287... 288var tasks = []string{"cook", "clean", "laundry", "eat", "sleep", "code"} 289app := cli.NewApp() 290app.EnableBashCompletion = true 291app.Commands = []cli.Command{ 292 { 293 Name: "complete", 294 Aliases: []string{"c"}, 295 Usage: "complete a task on the list", 296 Action: func(c *cli.Context) { 297 println("completed task: ", c.Args().First()) 298 }, 299 BashComplete: func(c *cli.Context) { 300 // This will complete if no args are passed 301 if len(c.Args()) > 0 { 302 return 303 } 304 for _, t := range tasks { 305 fmt.Println(t) 306 } 307 }, 308 } 309} 310... 311``` 312 313#### To Enable 314 315Source the `autocomplete/bash_autocomplete` file in your `.bashrc` file while 316setting the `PROG` variable to the name of your program: 317 318`PROG=myprogram source /.../cli/autocomplete/bash_autocomplete` 319 320#### To Distribute 321 322Copy `autocomplete/bash_autocomplete` into `/etc/bash_completion.d/` and rename 323it to the name of the program you wish to add autocomplete support for (or 324automatically install it there if you are distributing a package). Don't forget 325to source the file to make it active in the current shell. 326 327``` 328 sudo cp src/bash_autocomplete /etc/bash_completion.d/<myprogram> 329 source /etc/bash_completion.d/<myprogram> 330``` 331 332Alternatively, you can just document that users should source the generic 333`autocomplete/bash_autocomplete` in their bash configuration with `$PROG` set 334to the name of their program (as above). 335 336## Contribution Guidelines 337Feel free to put up a pull request to fix a bug or maybe add a feature. I will give it a code review and make sure that it does not break backwards compatibility. If I or any other collaborators agree that it is in line with the vision of the project, we will work with you to get the code into a mergeable state and merge it into the master branch. 338 339If you have contributed something significant to the project, I will most likely add you as a collaborator. As a collaborator you are given the ability to merge others pull requests. It is very important that new code does not break existing code, so be careful about what code you do choose to merge. If you have any questions feel free to link @codegangsta to the issue in question and we can review it together. 340 341If you feel like you have contributed to the project but have not yet been added as a collaborator, I probably forgot to add you. Hit @codegangsta up over email and we will get it figured out. 342