Go
golang

cliパッケージでサブコマンドを作る

More than 1 year has passed since last update.

cliパッケージ について

A Go library for implementing command-line interfaces.
https://github.com/mitchellh/cli

github.com/mitchellh/cliは、PackerやSerfやConsulで使用されている。
コマンドラインインターフェイスを実装するためのライブラリ。

サブコマンドを作る際に、以下のような面倒を見てくれる。

  • サブコマンドのヘルプリストを自動生成
  • ヘルプフラグである-h--help引数を自動実装
  • バージョンフラグである-v--version引数を自動実装

使い方

インストール。

shell
go get github.com/mitchellh/cli

実装の流れとしては、

  1. Commandインタフェースの実装する(Help()Run()Synopsis()を実装する)
  2. サブコマンドに使う文字列と1.で実装したものを対応付けさせる

と言った感じ。

以下の例では、app fooapp barというサブコマンドを実装している。

cli.go
package main

import (
        "github.com/mitchellh/cli"
        "log"
        "os"
)

/** foo サブコマンド用の実装 **/
type Foo struct{}

func (f *Foo) Help() string {
        return "app foo"
}

func (f *Foo) Run(args []string) int {
        log.Println("Foo!")
        return 0
}

func (f *Foo) Synopsis() string {
        return "Print \"Foo!\""
}


/** bar サブコマンド用の実装 **/
type Bar struct{}

func (b *Bar) Help() string {
        return "app bar"
}

func (b *Bar) Run(args []string) int {
        log.Println("Bar!")
        return 0
}

func (b *Bar) Synopsis() string {
        return "Print \"Bar!\""
}

func main() {
        // コマンドの名前とバージョンを指定
        c := cli.NewCLI("app", "1.0.0")

        // サブコマンドの引数を指定
        c.Args = os.Args[1:]

        // サブコマンド文字列 と コマンド実装の対応付け
        c.Commands = map[string]cli.CommandFactory{
                "foo": func() (cli.Command, error) {
                        return &Foo{}, nil
                },
                "bar": func() (cli.Command, error) {
                        return &Bar{}, nil
                },
        }

        // コマンド実行
        exitStatus, err := c.Run()
        if err != nil {
                log.Println(err)
        }

        os.Exit(exitStatus)
}

コンパイル。

shell
go build -o app cli.go

サブコマンドの実行。

shell
$ ./app foo
2014/11/11 21:45:10 Foo!
$ ./app bar
2014/11/11 21:46:27 Bar!

バージョンの表示。

shell
$ ./app --version
1.0.0

ヘルプの表示。

shell
./app --help
usage: app [--version] [--help] <command> [<args>]

Available commands are:
    bar    Print "Bar!"
    foo    Print "Foo!"

サブコマンドのヘルプの表示。

shell
$ ./app --help foo
app foo
$ ./app --help bar
app bar

と言った感じで、インタフェースで定められているメソッドを実装すれば、
サブコマンドが良い感じに実装される。

サブコマンドの引数などを実装したい場合は、
flagパッケージも併用すれば良さそう。

参考

https://github.com/mitchellh/cli/blob/master/command.go