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