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 functions readArticles
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 change tweets
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!
Summary
Cli.go is wonderful! There are many more customizations you can do (you can even change help templates, which use the standard template package), check out documentation.
Source code and license
GitHub: https://github.com/codegangsta/cli
Documentation: https://godoc.org/github.com/codegangsta/cli
Author: Jeremy Saenz (@codegangsta)
License: MIT