Go
golang

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

More than 3 years have 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