Golang バージョン 1.16 以上をを想定しています
環境の構築方法については次の記事を参照してください:
Docker とVisual Studio Code を使った Go (Golang) 開発環境構築 - Qiita
基本
まずは Golang プロジェクトを初期化します
プロジェクト用フォルダーを作成し、そのフォルダーの直下で次のコマンドを実行します:
go mod init <リポジトリーのパス>
例:
go mod init github.com/yukihiko-shinoda/go-commandline-tool
※ リポジトリーのパスは後から変えることもできます
すると、ファイル: go.mod
が作成されます
project/
+---go.mod
次に .go
ファイルを作成します
例:
project/
+---commandline_tool.go
+---go.mod
package main
func main() {
println("Hello world!")
}
このとき、次のことに気をつけます:
-
package
はmain
とします - コマンドラインツールを実行したときの処理を
main()
に定義します
このコードをコマンドラインツールとしてインストールします
インストールには 2 通りの方法があります
go install
go install
とだけ実行すると、
最初に実行した go mod init <リポジトリーのパス>
のリポジトリー名の部分が
コマンド名になります:
$ go install
$ go-commandline-tool
Hello world!
go install <.go ファイル名>
go install
に続けて .go
ファイル名を入力すると、
.go
ファイル名の拡張子を除いた部分の文字列がコマンド名になります:
$ go install commandline_tool.go
$ commandline_tool
Hello world!
複数のコマンドラインツールを作成する場合
1 つのパッケージ内に main()
を複数定義することはできないので、
リポジトリーを分けるか、サブフォルダーを作成します
サブフォルダーを作成する場合は、cmd
フォルダーを作成し、
さらにコマンドごとにサブフォルダーを作成するのが一般的であるようです:
project/
+----cmd/
+----command1/
| +----command1.go
+----command2/
+----command2.go
ちなみに、Golang 公式のフォルダー構成の推奨は特になく、
cmd
フォルダーについても公式の言及はありませんが、
多くの Golang プロジェクトが
次の非公式ベストプラクティスに倣って cmd
フォルダーを作成しているようです:
参考: golang-standards/project-layout: Standard Go Project Layout
各 .go
ファイルの package は main
にし、
それぞれにコマンド実行時の処理を main()
として定義します
次のコマンドで go ファイル名のコマンドが実行できるようになります:
$ go install cmd/command1/command1.go
$ go install cmd/command2/command2.go
$ command1
Hello world 1!
$ command2
Hello world 2!
リポジトリーからコマンドラインツールをインストール
以下の説明は Git などバージョン管理システムの知識を前提としています
バージョン管理システムの基礎については次の記事を参照してください:
Linux 知識の要らない Git 講座 目次 | ultra code
作成したコマンドラインツールを Git などのリポジトリーに push して、
バージョンを示すタグを付けておくことで、
Golang のインストールされている環境にいつでもコマンドラインツールをインストールできます:
go install <リポジトリーの main パッケージのフォルダーまでのパス>@<バージョンを示すタグ>
例 1:
ルートパッケージがコマンドラインツールの、タグ: v1.0.0
が示すバージョンをインストールする場合:
go install github.com/yukihiko-shinoda/go-commandline-tool@v1.0.0
例 2:
cmd/command1/command1.go
にコマンドラインツールを実装しており、
タグ: v1.0.0
が示すバージョンをインストールする場合:
go install github.com/yukihiko-shinoda/go-commandline-tool/cmd/command1@v1.0.0
この場合、コマンド名は main()
が定義されている .go
ファイル名……ではなく、
その .go
ファイルの親フォルダー名になります
インストール方法ごとのコマンド名まとめ
今まで見てきたように、インストール方法によってコマンド名が変わってしまいます
まとめると、次のようになります:
インストール方法 | コマンド名 |
---|---|
ローカルの go.mod を含むフォルダーで go install
|
最初に実行した go mod init <リポジトリーのパス> のリポジトリー名の部分 |
go install <.go ファイル名> |
.go ファイル名の拡張子を除いた部分の文字列 |
リポジトリーからコマンドラインツールをインストール | リポジトリーの main パッケージのフォルダー名 |
開発時とリリース時でコマンド名が変わらないようにする方法
次のようにすると、開発時とリリース時でコマンド名が変わらないようにできます
プロジェクト直下にコマンドラインツールを作成するとき
開発時にテストのためコマンドラインツールをインストールするときは、
ファイル名を指定せずに go install
するようにします
サブフォルダーを用意してコマンドラインツールを作成するとき
フォルダー名と main()
を定義する .go
ファイル名を同じ名前で作成するようにします
例:
project/
+----cmd/
+----command1/
| +----command1.go
+----command2/
+----command2.go