Windows
golang
cli
自動生成
cobra

JavaプログラマがGo言語を触ってみた(cobraでCLIを作ってみた)

image

ども、keita69sawada です。

Go言語で「CLIを作成するときに良いパッケージないかな?」と探してみるとcobraを見つけました。

じゃ、「cobraについて調べてみるか!」と
ウニウニしたのがこの記事です。

対象読者

  • Go言語でCLIを作成する人。

前提条件

  • windows10(home)の環境
  • golangがインストール済み

※ 環境はchocolateyでのセットアップがおすすめ。こちらも参照

はじめに

cobraって何ができるの?

  1. テンプレートを自動生成ツールcobra/cobraでベースとなるソースを作成し、
  2. 用意されたパッケージを使って簡単にCLIアプリを作成することができます。
  3. また、JSON やYAML による設定ファイルを簡単に扱うためのパッケージviperとの相性も良いです。

手順

1. 環境の準備

ワークスペース(WS)を作成し、go get でパッケージを取得します。
下記をコピペ。

コマンド(コマンドプロンプトで実行)
set WS=%HOMEDRIVE%%HOMEPATH%\git\go-cobra
mkdir %WS%
cd %WS%
set GOPATH=%WS%
mkdir bin
go get -v -u github.com/spf13/cobra
go get -v -u github.com/spf13/cobra/cobra

2. 今回作成するサンプル CLIアプリ mytool とは?

mytoolのサブコマンド(hello)とパラメタ(”keita69sawada”)を渡すと、"Hello, [パラメタ] !!" を返却するCLIアプリケーションです。

mytoolのコマンドイメージ
mytool hello keita69sawada
>> Hello, keita69sawada !!

2. CLIアプリのテンプレートを作成

mytoolCLIアプリのテンプレートを作成します。
下記をコピペ。

コマンド(コマンドプロンプトで実行)
%GOPATH%/bin/cobra.exe init mytool

3. CLIアプリのサブコマンド テンプレートを作成

hello サブコマンドのテンプレートを作成します。
下記をコピペ。

コマンド(コマンドプロンプトで実行)
cd %GOPATH%/src
%GOPATH%/bin/cobra.exe add hello

4. 実行ファイル(.exe)の作成

作成されたテンプレートをコンパイルします。
下記をコピペ。

コマンド(コマンドプロンプトで実行)
go install mytool

5. mytoolCLIアプリの実行

何も修正を加えていない状態で実行してみます。

5.1 helloサブコマンドを実行

下記をコピペ。
txt:コマンド(コマンドプロンプトで実行)
%GOPATH\bin\mytool hello

helloサブコマンドが呼び出されたことがわかるメッセージが表示されました。
6. フォルダ構成にある★hello.goにこのメッセージ表示の実装があります

実行結果
%WS%\src\mytool>%GOPATH%\bin\mytool hello
hello called

5.2 mytoolにサブコマンドを指定しないで実行

下記をコピペ。
txt:コマンド(コマンドプロンプトで実行)
%GOPATH\bin\mytool

テンプレートの状態でヘルプメッセージが出力されました!!

実行結果
%WS%\src\mytool>%GOPATH%\bin\mytool
A longer description that spans multiple lines and likely contains
examples and usage of using your application. 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.

Usage:
  mytool [command]

Available Commands:
  hello       A brief description of your command
  help        Help about any command

Flags:
      --config string   config file (default is $HOME/.mytool.yaml)
  -h, --help            help for mytool
  -t, --toggle          Help message for toggle

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

6. フォルダ構成

ここまででフォルダ構成は下記のようになっているはず。
※ パッケージ類は省略してます

フォルダ構成
├─bin
│      cobra.exe
│      mytool.exe
│      
├─pkg
│              
└─src
    │          
    └─mytool
        │  LICENSE
        │  main.go
        │  
        └─cmd
                hello.go        ★サブコマンドの実装はこのファイル
                root.go

7. hello.goを修正します。

サンプル CLIアプリ mytool の仕様に合わせてhello.goを修正します。

修正前
// helloCmd represents the hello command
var helloCmd = &cobra.Command{
    Use:   "hello",
    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) {
        fmt.Println("hello called")
    },
}

修正するのは★の1行だけ。

修正後
// helloCmd represents the hello command
var helloCmd = &cobra.Command{
    Use:   "hello",
    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) {
        fmt.Printf("Hello, %s !!", args[0])    ここを修正
    },
}

ビルド&実行してみる。
下記をコピペ。

コマンド(コマンドプロンプトで実行)
go install mytool
%GOPATH\bin\mytool hello keita69sawada

できた!!

実行結果
%WS%\go-cobra>%GOPATH%\bin\mytool hello keita69sawada
Hello, keita69sawada !!

まとめ

 まだ簡単な使い方しかできていないですが、ヘルプが含まれているテンプレートがサクサク作れるところ気に入りました。

 複数人でプログラム実装する場合も、AさんはXXXサブコマンド、BさんはYYYサブコマンド、CさんはZZZサブコマンドとしても共通のベースコードがあれば俗人的な仕様にならないし安心ですね。

 JSON やYAML による設定ファイルを簡単に扱う機能を使っていないので、機会があれば遊んでみようと思います。

参考URL