golangのurfave/cliを使って、なんちゃってオプションRequiredをやってみた

  • 0
    Like
  • 0
    Comment

    自作のcliツールを作る場合、オプション(引数)を使えるよう作成したりする時があると思います。
    その場合、必須オプションを指定できると引数漏れなどが無くなり便利になったりします。
    ただ、goで簡単にオプションを作成できるパッケージ urfval/cli では、オプションの Required が指定できないようです。
    調べてみるとやっぱり必須オプションの需要があるみたいでissuesで議論はされていますね。
    色々やり方はあるかと思いますが、ここでは備忘録としてなんちゃってRequiredの実装メモを残しておきます。

    やりたかったこと

    • --option, -op を必須オプションとして指定したい
    • -- 無しのオプション、第一引数などを必須にしたい
    • もし、必須のオプションが指定されていない場合はヘルプを自動で表示させて動作を終了したい

    ハイフンを付けるオプションを必須にしてみた

    以下の場合 --example, -e が指定されていない場合はヘルプを表示して処理を終了します。
    単純にデフォルトで None を指定していて、それに変更が無い場合はexitしています。

    package main
    
    import (
        "fmt"
        "os"
    
        "github.com/urfave/cli"
    )
    
    func Action(c *cli.Context) {
        app := App()
        if c.String("example") == "None" {
            app.Run(os.Args)
            os.Exit(1)
        }
        fmt.Println(c.String("example"))
    }
    
    func App() *cli.App {
        app := cli.NewApp()
        app.Name = "example"
        app.Usage = "ハイフン引数をRequiredにする例"
        app.Version = "0.0.1"
        app.Author = "sky_jokerxx"
        app.Flags = []cli.Flag{
            cli.StringFlag{
                Name:  "example, e",
                Value: "None",
                Usage: "引数例",
            },
        }
        return app
    }
    
    func main() {
        app := App()
        app.Action = Action
        app.Run(os.Args)
    }
    

    実行してみます。

    $ go run example.go
    NAME:
       example - 引数をRequiredにする例
    
    USAGE:
       example [global options] command [command options] [arguments...]
    
    VERSION:
       0.0.1
    
    AUTHOR:
       sky_jockerxx
    
    COMMANDS:
         help, h  Shows a list of commands or help for one command
    
    GLOBAL OPTIONS:
       --example value, -e value  引数例 (default: "None")
       --help, -h                 show help
       --version, -v              print the version
    exit status 1
    

    引数を指定していないので、ヘルプが表示されました。
    試しに引数を指定してみます。

    $ go run example.go --example hoge
    hoge
    

    ハイフンが無いオプションを必須にしてみた

    以下では、ハイフン無しの引数が指定されていない場合はヘルプを表示して処理を終了します。

    package main
    
    import (
        "fmt"
        "os"
    
        "github.com/urfave/cli"
    )
    
    func Action(c *cli.Context) {
        app := App()
        if c.Args().Get(0) == "" {
            help := []string{"", "--help"}
            app.Run(help)
            os.Exit(1)
        }
        fmt.Println(c.Args().Get(0))
    }
    
    func App() *cli.App {
        app := cli.NewApp()
        app.Name = "example2"
        app.Usage = "ハイフン無し引数をRequiredにする例"
        app.Version = "0.0.1"
        app.Author = "sky_jokerxx"
        return app
    }
    
    func main() {
        app := App()
        app.Action = Action
        app.Run(os.Args)
    }
    

    実行してみます。

    $ go run example2.go
    NAME:
       example2 - ハイフン無し引数をRequiredにする例
    
    USAGE:
       example2 [global options] command [command options] [arguments...]
    
    VERSION:
       0.0.1
    
    AUTHOR:
       sky_jokerxx
    
    COMMANDS:
         help, h  Shows a list of commands or help for one command
    
    GLOBAL OPTIONS:
       --help, -h     show help
       --version, -v  print the version
    exit status 1
    

    引数を指定していないので、ヘルプが表示されました。
    試しに引数を指定してみます。

    $ go run example2.go hoge
    hoge
    

    一応、やりたい動作にはなりました :-)
    ただ、必須分だけ処理を書いていく必要がありますね :-(