[Go言語]codegangsta/cliで、サブコマンドとして外部コマンドをとれるようにしてみた
June 25, 2014
この記事はQiitaの記事をエクスポートしたものです。内容が古くなっている可能性があります。
codegangsta/cli
コンソールアプリを作るのに便利なライブラリ。 簡単に、オプションやサブコマンドを扱える。
サブコマンドとして外部コマンドをとる
gitコマンドのようにPATHの通っているところにgit-xxxxみたいな実行可能ファイルがあると、git xxxxみたいに、あたかもgitコマンドのサブコマンドとして扱える。
codegangsta/cliを使って同じようなことをしたい。
cli.AppにBeforeというフィールドがあり、サブコマンドを実行する前に実行できる関数を設定できる。
また、exec.LookPathを使えば、PATHの通った実行可能ファイルの絶対パスを探すことができる。
この2つを使って、サブコマンドが実行される前に、プログラミング引数の2番目の値を実行可能ファイルとして探し出し、Beforeでその外部コマンドを実行するような、cli.Commandを作成して、Appにサブコマンドとして登録してやればよい。
http://golang.org/pkg/os/exec/#LookPath
package main import ( "github.com/codegangsta/cli" "os" "os/exec" "strings" ) func main() { app := cli.NewApp() app.Before = func(c *cli.Context) error { args := c.Args() if len(args) <= 0 { return nil } subcommand := args.First() for _, c := range app.Commands { if c.HasName(subcommand) { return nil } } path, err := exec.LookPath(app.Name + "-" + subcommand) if err != nil { return err } app.Commands = append(app.Commands, cli.Command{ Name: subcommand, Action: func(c *cli.Context) { cmd := exec.Command(path, strings.Join(os.Args[2:], " ")) cmd.Stdout = os.Stdout cmd.Stdin = os.Stdin cmd.Stderr = os.Stderr cmd.Run() }, }) return nil } app.Run(os.Args) }package main import ( "fmt" "github.com/codegangsta/cli" "os" ) func main() { app := cli.NewApp() app.Action = func(c *cli.Context) { args := c.Args() if len(args) <= 0 { fmt.Println("no params") return } fmt.Println(args.First()) } app.Run(os.Args) }
main.goはメインとなるプログラムで以下の様にビルドするとする。
% go build -o main main.gosub.goはサブコマンドとして呼び出すコマンドで、以下の様にビルドするとする。
% go build -o main-sub sub.goこのようにすると、以下のようにsub.goから作った実行可能ファイルを、mainのサブコマンドとして実行できる。
% ./main sub hogehoge
hogehoge