Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
72
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

Golangでcliツール作るならこれで!

この記事はITC Advent Calendar(1) 24日目の記事です

その一
https://adventar.org/calendars/2563

その二
https://adventar.org/calendars/2640

初めまして、がっちゃんです
本年度のITC( https://itc.moe )の部長やってます

今回は思いつきで始めたGolang で CLI ツールを作る。

で使った、 urfave/cli というパッケージについてちょこっと解説記事を書くことにしました。

なぜ使おうと思ったか

Golang初心者だったので、検索して一発目に出てきたパッケージを使うことにした

どんなパッケージ?

概要

簡単にcliツールを作ることができる、cliのフレームワークと言ってもいいほど高機能なパッケージ

いいところ

一言で言うと、cliツールに必要な要件がめっちゃ整理されてて使いやすい

  • helpは自動で生成される&必要なところだけ構造体に代入するだけでよしなに成形して表示してくれる
  • コマンド(git commitcommit部分など)、サブコマンド(git stash poppop部分など)を簡単に構造体で定義でき、名前と関数を登録するだけでできる
  • オプションはFlagとして定義でき、エイリアス(--version-vでいけるようにするやつ)もまとめて定義できる
    • FlagStringFlagBoolFlagを利用することができ、初期値の設定ができたり簡単にデータ取得ができたりする。
  • コードが読みやすい(当社比)

使い方の解説

インストール

$ go get github.com/urfave/cli

でパッケージをインストールしておく

基準となるポイントを作る

main.go
package main

import (
    "os"
    "github.com/urfave/cli"
)

func main() {
  app := cli.NewApp()
  app.Run(os.Args)
}

appの中に基本的な情報が入っており、これを編集・実行する形となる

名前と使い方とバージョンを登録して、実行してみる

入力された引数の文字列を表示するサンプルアプリをつくる

main.go
package main

import (
    "os"
    "github.com/urfave/cli"
)

func main() {
  app := cli.NewApp()

  app.Name = "sampleApp"
  app.Usage = "This app echo input arguments"
  app.Version = "0.0.1"

  app.Run(os.Args) // 忘れない!(よくやらかす)
}

保存して実行!

$ go run main.go
NAME:
   sampleApp - This app echo input arguments

USAGE:
   main [global options] command [command options] [arguments...]

VERSION:
   0.0.1

COMMANDS:
     help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --help, -h     show help
   --version, -v  print the version

Actionと呼ばれる処理を登録してない場合、自動で作成されたコマンドのヘルプが表示される。

処理を登録する

Goの関数を登録することで処理を追加することができる

main.go
package main

import (
    "os"
    "fmt"
    "github.com/urfave/cli"
)

func main() {
  app := cli.NewApp()

  app.Name = "sampleApp"
  app.Usage = "This app echo input arguments"
  app.Version = "0.0.1"

  app.Action = func (context *cli.Context) error {
    fmt.Println(context.Args().Get(0))
    return nil
  }

  app.Run(os.Args)
}

コマンドの引数を受け取って、fmt#Printlnで表示するだけの処理を追加。

Actionの引数

func (context *cli.Context) error {}

としているが、contextが何者なのかを軽く説明

contextの中にはアプリについての情報やコマンド引数の値などが格納されている構造体である。

中でもContext#Args()Context#String(), Context#Bool()はよく使う。

Context#Args()

コマンド引数のリストを取得するメソッド。

返り値はArgsで、実態はstringのSliceである。

ここからデータを取得するときは、Args#Get()を利用する。

Context#String(), Context#Bool()

コマンドに指定したオプションの値を取得するメソッド。

返り値はそれぞれ、 stringboolの値が返る

上記のコードではオプションを付けていなかったので、オプションの作り方を以下で紹介しておく

main.go
package main

import (
    "os"
    "fmt"
    "github.com/urfave/cli"
)

func main() {
  app := cli.NewApp()

  app.Name = "sampleApp"
  app.Usage = "This app echo input arguments"
  app.Version = "0.0.1"

  app.Action = func (context *cli.Context) error {
    if context.Bool("cat") {
        fmt.Println(context.Args().Get(0) + "だにゃん♡")  
    } else {
        fmt.Println(context.Args().Get(0))
    }
    return nil
  }

  app.Flags = []cli.Flag{
    cli.BoolFlag {
      Name: "cat, c",
      Usage: "Echo with cat",
    },
  }

  app.Run(os.Args)
}

オプションの定義は app#Flags[]cli.Flagを登録することで定義でき、
呼び出す際はcontext#{String|Bool}にオプションの名前を指定することで値を取得できる。

定義時のcli.BoolFlag, StringFlagの構造体にはデフォルトの値の指定やヘルプに表示するか否かが指定できたりして、かなり柔軟に指定できる印象。

保存して実行!

$ go run main.go "Hello world"
Hello world
$ go run main.go -c "Hello world"
Hello worldだにゃん♡

無事に引数の文字列をechoできるcliアプリができている。

あとはbuild、installすればどこでも使える自分用cliツールの完成!👍

ビルド

$ go build
# => main.go(mainパッケージ)があるディレクトリの名前のバイナリファイルが用意される。

インストール

$GOPATHを通しておけば、go installコマンドで$GOPATH/binディレクトリ下にバイナリファイルがインストールされて通常のコマンドのように叩くことができるようになる!

まとめ

以上、Golangで簡単にcliツールを作ることができるパッケージについての紹介でした。

Golang使いやすいし、なにかコマンドラインツール作って見るときはGolang + urfave/cli で作ってみることをおすすめします!

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
72
Help us understand the problem. What are the problem?