YOwatari's blog

思うままに。

cobra を使って golang で cli ツールを作ってみる

この記事は、 Advent Calendar 2016 - VOYAGE GROUP techlog の17日目のエントリです。

こんにちは。 fluct でエンジニアしている @YOwatari です。

今日は、 golangcli ツールを作ってみた話です

ある日

fluct では、バッチが生成するファイルに、何かしらの時刻が 0005 のような形で含まれたりするものがあります。 そうしたファイルを扱いたい時に、現在時刻から直近のものを取得したいなどのケースがままあります。 そんな中、ある日の社内Slack にてこんなやり取りがありました。

f:id:wata88:20161218173623p:plain

ということで、 ニッチな cli ツールを作ってみるかとやってみました。

cobra

golangcli ツールを使う場合、様々な便利がパッケージがあるのでその中から選択して利用することになるかと思われます。 これまで私は https://github.com/codegangsta/cli をよく使っていましたが、今回は気持ち新しく cobra を使ってみます。

github.com

cobra コマンドを使ってコードを自動生成してくれるようで

go get -v github.com/spf13/cobra/cobra

でインストールして

cobra init github.com/YOUR ACCOUNT/REPOSITORY

すると、$GOPATH/src/github.com/YOUR ACCOUNT/REPOSITORY にテンプレートを生成してくれます。 この時、 $HOME/.cobra.yaml を用意していれば、それに基づいてライセンス表記などの項目を埋めてくれます。

さらにサブコマンド追加は

cd $GOPATH/src/github.com/YOUR ACCOUNT/REPOSITORY
cobra add sub

とすると、sub をサブコマンドとして追加してくれます

テンプレートで生成されるコードの構成は以下のようになっていて

├── LICENSE
├── cmd
│   ├── root.go
│   └── sub.go
└── main.go

sub コマンドの処理を書きたい場合は

// subCmd represents the sub command
var subCmd = &cobra.Command{
    Use:   "sub",
    Short: "A brief description of your command",
    Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:

Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
    Run: func(cmd *cobra.Command, args []string) {
        // TODO: Work your own magic here
        fmt.Println("sub called")
    },
}

の Run の関数の中身を変更すれば良さそうです。 フラグの作り方など、さらに詳しい内容は cobra の README を参照してください。

つくってみる

さて、先ほどの 1日をn分割して現在時刻より前 or 後の HHMM を取り出す clicobra で作ってみたのが以下になります。

github.com

一日を 288分割して 現在の前後を取ってみると、以下のように

$ date
Sun Dec 18 18:19:21 JST 2016

$ hhmm -d 288 show after 
1820

$ hhmm -d 288 show before
1815

ちゃんと出力してくれます。 タイムゾーンを考慮してなかったり秒数を考慮してなかったりでまだまだですが、 それっぽく動くところまでは簡単に作れました。

おわりに

cobra を使って cliツール を作ってみました。 フラグにスコープを持たせることができたり、実行前後に処理をフックできたり、と cobra 便利さを感じたので、今後 cli ツールを使う際には cobra を積極的に使ってみようかなと思います。

それでは、明日のエントリもお楽しみに。