読者です 読者をやめる 読者になる 読者になる

scramble cadenza

技術ネタのガラクタ置き場

初めての人がなんとなく Go で CLI を作ってみた時のまとめ

Golang cli 小ネタ

イントロ

ちょっと昔に 「みんなのGo言語」が良かったので、自分のためだけのCLIツールを作ってみた - えいのうにっき を読んで、なんとなく何か作りたい気分になっていた。

Go 言語の知識が皆無の状態から 自作 CLI 作ったので、その時のメモをまとめてみました。
効率が良いとは思いませんが、こういう学習パスを通ればものは作れるぞ、という一例として参考になれば。

まず最初に読む

Go 言語で CLI 作るときの知見

「Go」 で「CLI」というと、過去に良い記事があったような記憶があったので、
探し出して、読み直してみた。

どちらもすごい良い記事で、更に気分が高まる。

package を探す

Go で CLI 支援パッケージ絶対あるやろ、と思ったらやっぱりあった。
めんどくさがりな自分でもできそうな気がしてきて、更に気分が高まる。

開発環境

作業ディレクトリ(Workspace って言うらしい)

Goコードの書き方 - The Go Programming Language GO:Workspace と GOPATH - Web系開発メモ

多くの Go言語プログラマは、1つの GOPATH(1つの Workspace)で、複数(or 全て)の ソース・パッケージ・リポジトリ・依存性を管理しているようです。

好きなディレクトリで作業できないのはちょっと意外。
回避方法はあると思うが、深くは追わず Go ってそういうものなんだ、で一旦飲み込んだ。 経験者の意見を伺いたいところ。

GitHub で公開することを想定すると、$GOPATH/src/github.com/{repo} みたいなところで作業をすることになる。

Emacs

go-mode + go-autocomplete を導入。
先人の知恵は素晴らしい。

学習

A Tour of Go

一通り流した。なんとなくイメージが見えてきた。

A Tour of Go

CLI 支援パッケージまわり

早速調べてあったパッケージを使い始める。
私が触ったのは以下の 2 つ。

  • spf13/cobra
  • urfave/cli

spf13/cobra

spf13/cobra: A Commander for modern Go CLI interactions

有名コマンドも採用実績があり、サブコマンドを作りやすいのが嬉しいところ。 gif 見ればなんとなく使い方がわかる、というところも良いと思った。

が、作っていくうちに「今回のやりたい内容を考えると、サブコマンド要らないのでは」と思い直し、方向転換した。 残念ながら軽く触る程度で終わってしまったが、次のチャンスがあればまた触ってみたい。

urfave/cli

urfave/cli: A simple, fast, and fun package for building command line apps in Go

cobra を止めた後に選んだのはこちら。 star 数と README のわかりやすさが決め手。

他のパッケージも眺めてみたが、大体これと似ていたので、どれでもいいなら star 数で選ぶというミーハーっぷりを発揮。

依存関係の解決

自分の GOPATH には既に別のパッケージが散乱していて、汚れまくっていたので、rubybundler 的なやつが欲しかった。

そこで Big Sky :: golang オフィシャル謹製のパッケージ依存解決ツール「dep」 を発見。

なんとなくの気分で使ってみるが、まだ使いこなせていない。 まだ Go 言語に慣れてなくて、dep の全体を把握するのが難しいのもある。

それと、この時に Go の依存関係解決についてよく理解していないことに気づき、以下の資料を見て学んだ。

Goと依存パッケージ管理

それ以外の学習

後は思いついた疑問を赴くままにググりまった。効率が悪いがしょうがない。
以下はまだ読んでないけど、時間がある時にまとめて読みたい。

感想

  • 恥ずかしながら型言語を触って何かを作ったのは初めての経験。
    • 戻り値の型がわかるとコードが読みやすい。
    • 書き方がオブジェクト指向っぽくはならず、右往左往している。
  • すぐ panic になってしまう Go は、ちょっとかわいい。
  • 配列やマップの扱いが難しかった。もっとこう… 何かあるだろ、と思う場面が多い。
    • 慣れてないだけかも。
    • こういう時、型が無い方がいいなーと思う。
  • わかっていないことは非常に多い
    • 依存関係の解決
      • dep で解決できるのは、開発環境で使用するパッケージの指定。
      • リリースして go get すると失敗する可能性は残されている。
    • reflect パッケージ周り
      • まだ腹落ちしてなくて、もうちょっと慣れが必要
    • 作業ディレクト
      • 今は $GOPATH/src/github.com/{repo} で開発してる
    • ソースコードのファイル分割と import まわり
  • 結局は A Tour of Go を一通りやって、後は勢いで押し切っただけ
    • そういう意味では「何でもいいから作りたいものがあるかどうか」が一番大事で、難しいのだよなーと思った
    • 日頃の仕事を不便だと感じる気付きが重要となる

できあがったもの

完全に自分用ですが、terminal からコードレビューを依頼する CLI を作った。

仕事環境が変わり、レビュアーが曜日ごとに変わるようになってしまったので、レビュアーを自動特定できるようにした。
「今日は誰にレビュー依頼するのだっけ」「その管理シートどこにあるのだっけ」みたいなことをコードレビューのたびにやっていて、スーパー非効率だったのを改善できて良かった。
(レビュー体制をなんとかしたほうがよいのでは、という論点はあるのだが…)

mgi166/review-request: Request code review in terminal.

とはいえ、毎回固定のメッセージで依頼を投げてしまって bot っぽい。
バレないようにするためにも、ランダムでメッセージを変えるとか、人間っぽさを出していきたい。