README.md
1[![Build Status](https://travis-ci.org/codegangsta/cli.png?branch=master)](https://travis-ci.org/codegangsta/cli)
2
3# cli.go
4cli.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.
5
6You can view the API docs here:
7http://godoc.org/github.com/codegangsta/cli
8
9## Overview
10Command 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.
11
12**This is where cli.go comes into play.** cli.go makes command line programming fun, organized, and expressive!
13
14## Installation
15Make sure you have a working Go environment (go 1.1 is *required*). [See the install instructions](http://golang.org/doc/install.html).
16
17To install `cli.go`, simply run:
18```
19$ go get github.com/codegangsta/cli
20```
21
22Make sure your `PATH` includes to the `$GOPATH/bin` directory so your commands can be easily used:
23```
24export PATH=$PATH:$GOPATH/bin
25```
26
27## Getting Started
28One 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()`.
29
30``` go
31package main
32
33import (
34 "os"
35 "github.com/codegangsta/cli"
36)
37
38func main() {
39 cli.NewApp().Run(os.Args)
40}
41```
42
43This app will run and show help text, but is not very useful. Let's give an action to execute and some help documentation:
44
45``` go
46package main
47
48import (
49 "os"
50 "github.com/codegangsta/cli"
51)
52
53func main() {
54 app := cli.NewApp()
55 app.Name = "boom"
56 app.Usage = "make an explosive entrance"
57 app.Action = func(c *cli.Context) {
58 println("boom! I say!")
59 }
60
61 app.Run(os.Args)
62}
63```
64
65Running this already gives you a ton of functionality, plus support for things like subcommands and flags, which are covered below.
66
67## Example
68
69Being 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!
70
71Start by creating a directory named `greet`, and within it, add a file, `greet.go` with the following code in it:
72
73``` go
74package main
75
76import (
77 "os"
78 "github.com/codegangsta/cli"
79)
80
81func main() {
82 app := cli.NewApp()
83 app.Name = "greet"
84 app.Usage = "fight the loneliness!"
85 app.Action = func(c *cli.Context) {
86 println("Hello friend!")
87 }
88
89 app.Run(os.Args)
90}
91```
92
93Install our command to the `$GOPATH/bin` directory:
94
95```
96$ go install
97```
98
99Finally run our new command:
100
101```
102$ greet
103Hello friend!
104```
105
106cli.go also generates some bitchass help text:
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
161#### Alternate Names
162
163You can set alternate (or short) names for flags by providing a comma-delimited list for the `Name`. e.g.
164
165``` go
166app.Flags = []cli.Flag {
167 cli.StringFlag{
168 Name: "lang, l",
169 Value: "english",
170 Usage: "language for the greeting",
171 },
172}
173```
174
175That 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.
176
177#### Values from the Environment
178
179You can also have the default value set from the environment via `EnvVar`. e.g.
180
181``` go
182app.Flags = []cli.Flag {
183 cli.StringFlag{
184 Name: "lang, l",
185 Value: "english",
186 Usage: "language for the greeting",
187 EnvVar: "APP_LANG",
188 },
189}
190```
191
192The `EnvVar` may also be given as a comma-delimited "cascade", where the first environment variable that resolves is used as the default.
193
194``` go
195app.Flags = []cli.Flag {
196 cli.StringFlag{
197 Name: "lang, l",
198 Value: "english",
199 Usage: "language for the greeting",
200 EnvVar: "LEGACY_COMPAT_LANG,APP_LANG,LANG",
201 },
202}
203```
204
205### Subcommands
206
207Subcommands can be defined for a more git-like command line app.
208```go
209...
210app.Commands = []cli.Command{
211 {
212 Name: "add",
213 Aliases: []string{"a"},
214 Usage: "add a task to the list",
215 Action: func(c *cli.Context) {
216 println("added task: ", c.Args().First())
217 },
218 },
219 {
220 Name: "complete",
221 Aliases: []string{"c"},
222 Usage: "complete a task on the list",
223 Action: func(c *cli.Context) {
224 println("completed task: ", c.Args().First())
225 },
226 },
227 {
228 Name: "template",
229 Aliases: []string{"r"},
230 Usage: "options for task templates",
231 Subcommands: []cli.Command{
232 {
233 Name: "add",
234 Usage: "add a new template",
235 Action: func(c *cli.Context) {
236 println("new task template: ", c.Args().First())
237 },
238 },
239 {
240 Name: "remove",
241 Usage: "remove an existing template",
242 Action: func(c *cli.Context) {
243 println("removed task template: ", c.Args().First())
244 },
245 },
246 },
247 },
248}
249...
250```
251
252### Bash Completion
253
254You can enable completion commands by setting the `EnableBashCompletion`
255flag on the `App` object. By default, this setting will only auto-complete to
256show an app's subcommands, but you can write your own completion methods for
257the App or its subcommands.
258```go
259...
260var tasks = []string{"cook", "clean", "laundry", "eat", "sleep", "code"}
261app := cli.NewApp()
262app.EnableBashCompletion = true
263app.Commands = []cli.Command{
264 {
265 Name: "complete",
266 Aliases: []string{"c"},
267 Usage: "complete a task on the list",
268 Action: func(c *cli.Context) {
269 println("completed task: ", c.Args().First())
270 },
271 BashComplete: func(c *cli.Context) {
272 // This will complete if no args are passed
273 if len(c.Args()) > 0 {
274 return
275 }
276 for _, t := range tasks {
277 fmt.Println(t)
278 }
279 },
280 }
281}
282...
283```
284
285#### To Enable
286
287Source the `autocomplete/bash_autocomplete` file in your `.bashrc` file while
288setting the `PROG` variable to the name of your program:
289
290`PROG=myprogram source /.../cli/autocomplete/bash_autocomplete`
291
292
293## Contribution Guidelines
294Feel 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.
295
296If 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.
297
298If 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.
299