Article
cli.go — better command-line applications in Go
Go ships with
flag
standard library package, which covers a lot of what's needed to write command-line interfaces, however if you need more power and better structure for your console apps, try codegangsta's package cli.go.
Installing cli.go
You can install cli.go using go get:go get github.com/codegangsta/cli
In your code, import the package:
import "github.com/codegangsta/cli"
Writing command-line apps with cli.go
Defining commands and subcommands
Here is an example program:package main
import (
"fmt"
"os"
"github.com/codegangsta/cli"
)
func main() {
app := cli.NewApp()
app.Name = "progville"
app.Usage = "sample command-line app by Progville"
app.Author = "Carter"
app.Email = "[email protected]"
app.Commands = []cli.Command{
{
Name: "read",
ShortName: "r",
Usage: "read something",
Subcommands: []cli.Command{
{
Name: "articles",
Usage: "read articles",
Action: readArticles,
},
{
Name: "tweets",
Usage: "read Tweets",
Action: readTweets,
},
},
},
}
app.Run(os.Args)
}
func readArticles(ctx *cli.Context) {
fmt.Println("Go to https://www.progville.com to read articles!")
}
func readTweets(ctx *cli.Context) {
fmt.Println("Go to https://twitter.com/TheProgville to read our tweets!")
}
When you run it without any command-line arguments, you'll get the following help screen:
NAME:
progville - sample command-line app by Progville
USAGE:
progville [global options] command [command options] [arguments...]
VERSION:
0.0.0
AUTHOR:
Carter - <[email protected]>
COMMANDS:
read, r read something
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--help, -h show help
--version, -v print the version
We defined a read
subcommand, which itself has articles
and tweet
commands. Running:
progville read articles
will output:
Go to https://www.progville.com to read articles!
and running:
progville read tweets
will print:
Go to https://twitter.com/TheProgville to read our tweets!
Using context
Each action has a context. In the above example functionsreadArticles
and readTweets
accept a context argument. We can use it like this:
func readArticles(ctx *cli.Context) {
fmt.Printf("The first argument was: %s", ctx.Args().First())
}
Now running progville read articles please
will output:
The first argument was: please
Using flags
To demonstrate the usage of flags, let's changetweets
subcommand to this:
{
Name: "tweets",
Usage: "read Tweets",
Flags: []cli.Flag{
cli.StringFlag{
Name: "account",
Value: "TheProgville",
Usage: "name of Twitter account",
},
},
Action: readTwitter,
},
and readTweets
function to this:
func readTwitter(ctx *cli.Context) {
fmt.Printf("Go to https://twitter.com/%s to read tweets!", ctx.String("account"))
}
Now let's compile the result and run it to check the new help for tweets
subcommand:
progville read tweets --help
The output we get is:
NAME:
tweets - read Tweets
USAGE:
command tweets [command options] [arguments...]
OPTIONS:
--account 'TheProgville' name of Twitter account
Cool, now let's try it:
$ progville read tweets
Go to https://twitter.com/TheProgville to read tweets!
$ progville read tweets --account codegangsta
Go to https://twitter.com/codegangsta to read tweets!
Flags work!