Goでコマンドラインツールを作るときの鉄板ライブラリ

最近golangでコマンドラインツールを作るのが楽しいです。コンパイルするとバイナリになってコンパイル時のオプションでいろいろなプラットフォームで使えるのがいいですよね（実際はよく使うMac用にしかコンパイルしないけど）。

今回は簡単なコマンドラインツールを作りつつ、そのときよく使うライブラリを紹介したいと思います。

例となるコマンドラインツールは次のリポジトリです。

https://github.com/nasum/culc

簡単なコマンドラインでの計算機を作っていきます。

## CLIツールのベースとなるライブラリ「cobra」

まずはこれがないとはじまらない。コマンドラインツールを作る際の定番フライブラリ「[cobra](https://github.com/spf13/cobra)」です（こっぶら〜♪

cobraは簡単にコマンドラインツールのベースを作成することができます。サブコマンドを作ることが出来たりヘルプを自動生成してくれたりとコマンドラインツールを作る際のあると便利なことは大抵そろっているように思えます。

簡単にルートコマンドのみのコマンドを作ると次のようになります。

```golang:main.go
package main

import (
	"fmt"
	"os"

	"github.com/nasum/culc/cmd"
)

func main() {
	if err := cmd.RootCmd.Execute(); err != nil {
		fmt.Fprintf(os.Stderr, "%s: %v\n", os.Args[0], err)
		os.Exit(-1)
	}
}
```

```golang:cmd/root.go
package cmd

import (
	"fmt"

	"github.com/spf13/cobra"
)

// RootCmd is root command
var RootCmd = &cobra.Command{
	Use:   "culc",
	Short: "command line calculator",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("root command")
	},
}
```

この状態でコマンドを実行する次のように出力されます。

```zsh
$ go run main.go     
root command

$ go run main.go --help
command line calculator

Usage:
  culc [flags]

Flags:
  -h, --help   help for culc
```

簡単に文字列を出力するコマンドが作成できました。ヘルプも自動生成されていることが分かります。

サブコマンドを作成してみます。足し算するサブコマンド `sum` を追加します。

```golang:cmd/sum.go
package cmd

import (
	"fmt"
	"log"
	"strconv"

	"github.com/spf13/cobra"
)

func sumCmd() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "sum",
		Short: "sum culc",
		Args:  cobra.RangeArgs(2, 2),
		RunE: func(cmd *cobra.Command, args []string) error {
			if len(args) == 0 {
				return nil
			}

			itemOne, err := strconv.Atoi(args[0])

			if err != nil {
				log.Fatal(err)
				return nil
			}

			itemTwo, err := strconv.Atoi(args[1])

			if err != nil {
				log.Fatal(err)
				return nil
			}

			fmt.Println(itemOne + itemTwo)

			return nil
		},
	}

	return cmd
}
```

作成したサブコマンドをルートコマンドで `AddCommand` で追加することでネストされたコマンドを作成することが出来ます。

```golang:root.go
func init() {
	cobra.OnInitialize()
	RootCmd.AddCommand(
		sumCmd(),
	)
}
```

実装したあとヘルプコマンドを実行すると次のように表示されることが分かります。

```zsh
$ go run main.go help
command line calculator

Usage:
  culc [flags]
  culc [command]

Available Commands:
  help        Help about any command
  sum         sum culc

Flags:
  -h, --help   help for culc

Use "culc [command] --help" for more information about a command.
```

`sum` コマンドを実行すると引数で与えた数値で足し算が行われ結果が表示されます。

```zsh
$ go run main.go sum 1 1
2
```

## コマンドラインの出力結果に色をつける「color」

出力結果にいい感じに色をつけたい。そういうときは[color](https://github.com/fatih/color)を使います。

が、今気づいたのですがこのライブラリはアーカイブ化されているようです。ブログを見ると作者が燃え尽きてしまったっぽいことがうかがえます。他のライブラリを使うことを検討してもいいかもしれませんが、とりあえずここではcolorを使いたいと思います。

計算結果を緑色にするために次のようにコードを書きます。

```golang
green := color.New(color.FgGreen).SprintFunc()
fmt.Println(green(itemOne + itemTwo))
```

これで計算結果が緑色に着色されます。

## 他にも使えそうなライブラリ

他にも設定を読み込むためのライブラリ「[viper](https://github.com/spf13/viper)」

https://github.com/spf13/viper

があったり。

まだちゃんと使えてないけどコマンドラインツール作るのに便利そうなライブラリがちらほらあります。

インタラクティブなプロンプトを作るためのライブラリ「[go-prompt](https://github.com/c-bata/go-prompt)」

https://github.com/c-bata/go-prompt

TUIのコマンドを作るための表示ライブラリ「[termbox-go](https://github.com/nsf/termbox-go)」

https://github.com/nsf/termbox-go

このあたりについては後で追記するなり新しい記事を作るなりで書いていきたいですね。

## まとめ

以上簡単ですがgolangでコマンドラインツールを作るときに使っているライブラリやこれから使いたいライブラリをまとめていきました。

後半失速してあんまりないようのない記事になってしまいましたが追記したり更新したりで対応していければと思います。

golangでコマンドラインツール作るの楽しいのでcobraやtembox-goなんかを使って楽しいコマンドを作っていきたいところです。