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