mkgoprj : Golang CLIコマンド/ライブラリ プロジェクト生成コマンド(仕様説明)
前書き:なぜmkgoprjを開発したか
本記事は、mkgoprjコマンド(golang製)の仕様を説明する記事です。mkgoprjコマンドは、CLIコマンド/ライブラリ向けのテンプレートプロジェクト(Golang)を生成するコマンドです。
私は、2022年に入ってから小規模なGolangプロジェクトを12個作りました(2022年4月時点)。プロジェクトを作る度に「あのファイルをコピーして〜」「この文字列を置換して〜」みたいな作業をする事が、次第に苦痛になってきました。
そこで、「Javaのgradleコマンド」のようなプロジェクト生成コマンドを探しました。しかし、どれもイマイチな部分(以下の3点)があり、私の期待に応えていませんでした。
- 出力ファイルが少ない(プロジェクト作成が楽になっていない)
- 人様のリポジトリをクローンする必要がある(クローンパスを覚えてられない)
- 無駄に凝ったアーキテクチャのコード構成
仕方がないので、プロジェクト作成コマンドを自作することにしました。このような開発経緯を持つため、mkgoprjは私にピッタリのツールですが、皆さんに合うかは分かりません。
インストール方法
現在は、"go install"によるインストール方法のみ対応しています。golang用のツールなので十分だと考えていますが、要望があれば.debや.rpmに対応します。
$ go install github.com/nao1215/mkgoprj/v2@latest
なお、mkgoprjコマンドは、クロスプラットフォーム(Linux、Mac、Windows)対応です。
mkgoprjのサブコマンド一覧
mkgoprjコマンドは、Version 2.1.0時点で下表のサブコマンドを備えています。サブコマンドを指定しない場合は、ヘルプメッセージが表示されます。
サブコマンド | 機能 |
---|---|
cli | spf13/cobraを利用したCLIコマンドプロジェクトを生成 |
library | ライブラリ用プロジェクトを生成 |
cliサブコマンドの方がlibraryサブコマンドより出力するファイル数が多いため、以降の説明ではcliサブコマンドに関して説明します。
生成物の一覧
cliサブコマンドが生成するファイルは、大別すると以下の通りです。
- CLIコマンド用ソースコード
- GitHub Actions用のymlファイル(詳細は後述)
- Issueテンプレートファイル
- Makefile(詳細は後述)
- プロジェクト情報ファイル(Changelog、Code of conduct)
- go.mod, go.sum
実行例
cliサブコマンドは、import pathを引数に取ります。つまり、"$ go mod init"と同じ引数です。以下の実行例では、github.com/nao1215/sample を引数としています。-n オプションをつけた場合、プロジェクトルートディレクトリを作成せず、カレントディレクトリにファイルを生成します。
$ mkgoprj cli github.com/nao1215/sample
mkgoprj starts creating the 'sample' application project (import path='github.com/nao1215/sample')
[START] check if mkgoprj can create the project
[START] create directories
[START] create files
sample (your project root)
├─ CODE_OF_CONDUCT.md
├─ main.go
├─ Makefile
├─ Changelog.md
├─ .goreleaser.yml
├─ cmd
│ ├─ version.go
│ └─ root.go
├─ .github
│ ├─ dependabot.yml
│ ├─ ISSUE_TEMPLATE
│ │ ├─ issue.md
│ │ └─ bug_report.md
│ └─ workflows
│ ├─ reviewdog.yml
│ ├─ build.yml
│ ├─ unit_test.yml
│ ├─ release.yml
│ └─ contributors.yml
└─ internal
├─ cmdinfo
│ └─ cmdinfo.go
├─ completion
│ └─ completion.go
└─ print
└─ print.go
[START] Execute 'go mod init github.com/nao1215/sample'
[START] Execute 'go mod tidy'
BUILD SUCCESSFUL in 2485[ms]
GitHub Actions用のymlファイルファイル
mkgoprjコマンドは、プロジェクト作成時に下表のGitHub Actions用ymlファイルを生成します。一般的なOSSで用いられるGitHub Actionsには対応していると考えています(カバレッジ取得だけ意図的に含めていません)
Action name | Description |
---|---|
build | プロジェクトのビルドを行う |
unit test | ユニットテストを行う |
reviewdog | 静的解析を行う |
release | gitタグ毎にプロジェクトをリリースする |
contributors | コントリビューターリストファイルを作成する |
一般的ではないのは、contributorsだと思います。contributorsは、コードを修正した人のリスト(Contributors.md)を自動的に生成します。コード修正者の情報はGitのログから取得しており、botによる修正(貢献)を含んだ表を出力します。
出力例は、以下の通りです。
NAME | +(APPEND) | -(DELETE) | |
---|---|---|---|
Naohiro | dummy@gmail.com | 4663 | 1259 |
Yasuhiro | dummy2@gmail.com | 19 | 32 |
matsuyoshi | dummy3@gmail.com | 5 | 6 |
nao1215 | nao1215@users.noreply.github.com | 5 | 4 |
dependabot[bot] | 49699333+dependabot[bot]@users.noreply.github.com | 0 | 0 |
一般的ではありませんが、貢献した人いただいた人に敬意を払うため、Contributors.mdを出力するようにしています。
自己文書化されたMakefile
mkgoprjコマンドによって生成されるMakefileは、自己文書化されています。makeコマンドを実行した時、Makefileのターゲットリストが表示されます。ターゲット名の横には、ヘルプメッセージが表示されます。
$ make
build Build binary
clean Clean project
fmt Format go source code
test Start test
新しいターゲットを追加したい場合は、ターゲットの横に "##" から始まるコメントを書いてください。make実行時に"##"以降の文字列が抽出され、ヘルプメッセージとして利用されます。以下に例を示します。
build: ## Build binary
env GO111MODULE=on GOOS=$(GOOS) $(GO_BUILD) $(GO_LDFLAGS) -o $(APP) cmd/sample/main.go
clean: ## Clean project
-rm -rf $(APP) cover.out cover.html
シェル補完ファイルの自動生成 (bash, zsh, fish)
mkgoprjコマンドは、bash、zsh、fish向けのシェル補完ファイルを自動生成します。ユーザーがmkgoprjを実行した後、シェル補完ファイルがシステムに存在しない場合は、自動生成処理を開始します。シェル補完を有効にするには、シェル再起動が必要です。
$ mkgoprj
mkgoprj:INFO : append bash-completion file: /home/nao/.bash_completion
mkgoprj:INFO : create fish-completion file: /home/nao/.config/fish/completions/mkgoprj.fish
mkgoprj:INFO : create zsh-completion file: /home/nao/.zsh/completion/_mkgoprj
同様に、mkgoprjコマンドで生成したCLIコマンドも、シェル補完ファイルの自動生成機能が実装されています。
余談:前世はubumeという名前だった
mkgoprjコマンドは、version 1.x.x時代はubumeという名前でした。
プロジェクトを子供に見立てて「子供(出産)に関係する神様探そう!」と考え、良いのが見つからず、パッと思いついた”姑獲鳥 (ubume)”を採用しました。京極夏彦、好きなんです。しかし、意味も悪いし、何をするコマンドか分かりづらかったのでリネームしました。
リネーム後は、機能を減らしたにもかかわらず、GitHub Starが増え始めて驚いています。機能に紐付いたコマンド名は、大事なんですね。
Discussion