Go製cliといえば
GoでCLIを作ると言えばglagやcobraが有名かと思います。ですが今回はあえてGoogle製のsubcommands
でcliを作ってみます。
google/subcommands
Google謹製のライブラリということで、使ってみるしかありません。
他のcliを作るライブラリよりも極めてシンプルなのがgihubから伺えます。
今回は引数に渡されたcsvファイルの中身を標準出力として表示するといったものを作成します。(catええやん...)
インストール
go get github.com/google/subcommands
ファイル作成
$ touch main.go
$ mkdir cmd && touch cmd/open_csv.go
コマンド本体
サブコマンドの設定や、処理の本体をここに書いています。
open_csv.go
package cmd
import (
"context"
"encoding/csv"
"flag"
"fmt"
"io"
"os"
"strings"
"github.com/google/subcommands"
)
type ShowCSVContentCmd struct {
show string
}
func (*ShowCSVContentCmd) Name() string { return "show" } // サブコマンド名指定
func (*ShowCSVContentCmd) Synopsis() string { return "show args csv content to stdout." }
func (*ShowCSVContentCmd) Usage() string {
return `show [-capitalize] <some text>:
Show args csv content to stdout.
`
}
func (p *ShowCSVContentCmd) SetFlags(f *flag.FlagSet) {
}
func (p *ShowCSVContentCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
for _, arg := range f.Args() {
file, err := os.Open(arg)
if err != nil {
fmt.Printf("Failed to open file: %v\n", err)
return subcommands.ExitFailure
}
defer file.Close()
reader := csv.NewReader(file)
for {
record, err := reader.Read()
if err == io.EOF {
break
}
if err != nil {
fmt.Printf("Failed to read CSV record: %v\n", err)
return subcommands.ExitFailure
}
fmt.Println(strings.Join(record, ","))
}
}
return subcommands.ExitSuccess
}
main関数です。
main.go
package main
import (
"context"
"flag"
"os"
"github.com/google/subcommands"
"github.com/shuyaeer/golang-subcommands/cmd"
)
func main() {
subcommands.Register(subcommands.HelpCommand(), "")
subcommands.Register(subcommands.FlagsCommand(), "")
subcommands.Register(subcommands.CommandsCommand(), "")
subcommands.Register(&cmd.ShowCSVContentCmd{}, "")
flag.Parse()
ctx := context.Background()
os.Exit(int(subcommands.Execute(ctx)))
}
実行してみる
$ go build -o gocsvcat . # ビルド
$ ./gocsvcat help
Usage: gocsvcat <flags> <subcommand> <subcommand args>
Subcommands:
commands list all command names
flags describe all known top-level flags
help describe subcommands and their syntax
show show args csv content to stdout.
csvファイルを用意します。
sample.csv
Name,Age,City
Alice,25,New York
Bob,30,Los Angeles
Charlie,35,Chicago
$ ./gocsvcat show ./sample.csv
Name,Age,City
Alice,25,New York
Bob,30,Los Angeles
Charlie,35,Chicago
良さそうです。
あとは./gocsvcat
をPATHが通っている/usr/local/bin
などに配置すれば、どこからでもこのコマンドが使えるようになりますね。