LoginSignup
22
21

More than 5 years have passed since last update.

[Go言語]codegangsta/cliで、サブコマンドとして外部コマンドをとれるようにしてみた

Last updated at Posted at 2014-06-25

codegangsta/cli

コンソールアプリを作るのに便利なライブラリ。
簡単に、オプションやサブコマンドを扱える。

サブコマンドとして外部コマンドをとる

gitコマンドのようにPATHの通っているところにgit-xxxxみたいな実行可能ファイルがあると、git xxxxみたいに、あたかもgitコマンドのサブコマンドとして扱える。

codegangsta/cliを使って同じようなことをしたい。

cli.AppBeforeというフィールドがあり、サブコマンドを実行する前に実行できる関数を設定できる。
また、exec.LookPathを使えば、PATHの通った実行可能ファイルの絶対パスを探すことができる。
この2つを使って、サブコマンドが実行される前に、プログラミング引数の2番目の値を実行可能ファイルとして探し出し、Beforeでその外部コマンドを実行するような、cli.Commandを作成して、Appにサブコマンドとして登録してやればよい。

main.go
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)
}
sub.go
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.go

sub.goはサブコマンドとして呼び出すコマンドで、以下の様にビルドするとする。

% go build -o main-sub sub.go

このようにすると、以下のようにsub.goから作った実行可能ファイルを、mainのサブコマンドとして実行できる。

% ./main sub hogehoge
hogehoge
22
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
21