最近作ったコマンドラインツールの話
どうもnasaです! (良いタイトルが思いつきませんでした。アイディア募集中! @nasa_desuコチラまで!)
最近寒いです。誰かボクの心と体を温めて下さい。カレー風呂に入りたい。
この記事は Treasure Advent Calendar 2019 の記念すべき1日目の記事です!
某YAGE GROUPにちなんだ内容にしたかったのですが、思いつきませんでした。
今回は、11月に作ったコマンドラインツールの紹介とHomebrewに公開するまでの話を書こうと思います。
特に難しいことはやっていないので技術的な話はありません。 読んで得るものもないかもしれません。スミマセン。
目次
- 目次
- Homebrewに公開する
- Formulaファイル
- いざインストール!!
- homebrewだけでいいのか?
- バージョンアップのたびにバイナリアップロードするのか?
- そもそもFormulaを弄りたくない(今後の展望)
- 宣伝。作ったもの紹介
- 最後に
Homebrewに公開する
注: 今回一貫して、「Homebrewに公開する」と言いますが、これはHomebrew本家にPRを送って登録するのではなく、brew tap
を使うことを想定しています。
brew tap
はサードパーティー製のツールなどを公式ツールと同様にbrew [install, update, trace]
などのコマンドで扱えるように登録するためのコマンドです。
例えばボクは11月初旬にgoku
というツールを作りましたがこれは
brew tap k-nasa/tap brew install goku
もしくは
brew install k-nasa/tap/goku
でインストールすることができます。上のコマンドでは明示的にk-nasa/tap
をtap
コマンドで登録していることが分かりますね。
ちょっと余談
うろ覚えで、下調べも何もしていないので余談とします。
tap
なんか使わずにbrew install hoge
で直接インストールできるツールはどうしてるの?と疑問に思った人もいると思います。
macユーザーの方は以下のコマンドを実行してみて下さい。
brew tap | grep core
homebrew/core
というのが見つかりましたか? brew tap
で追加した覚えはありますか?
このhomebrew/core
というのはデフォルトであります
coreに追加するためにはhomebrew-coreリポジトリにPRを投げて、自分のツールを登録する必要があります。
逆に言えばPRを投げることで誰でも登録できるということでもありますね。
しかし、PRを出せば何でも追加できるわけではありません。半年前に調べたことなどでうろ覚えなのですが、例えば、登録したいツールのソースコードがGitHubにあったとすると、starを50集めないと、登録できない。などの決まり事が多数あった気がします。
Formulaファイル
本題に戻りましょうか。(本題ってなんでしたっけ? 忘れましたが、、、)
brew tap
で自分のツールを登録するためには、まずhomebrew-<ツール名>
というリポジトリを作り、Formulaファイルと呼ばれるファイルを追加しなければなりません。多分GitHubで無くてもいいとは思いますが、未確認です。
ちなみに、リポジトリ名はhomebre-<ツール名>
が主流のようですが、ボクはhomebrew-tap
として、すべてのツールのFormulaファイルをこのリポジトリに置くようにしています。
好みだとは思いますが、1つのリポジトリで管理しておいたほうが何かと便利だと思うので、homebrew-tap
を作ることをオススメします。
homebrew-tap
で無ければいけないのか?と思われそうな言い方をしてしまいましたがhomebrew-
で始まっていればリポジトリ名は何でも大丈夫です。
homebrew-hoge
だった場合brew tap リポジトリowner/hoge
コマンドを叩いて登録します。 (ボクの場合brew tap k-asa/hoge
)
Formulaファイルの詳細な書き方は説明しません、ググって下さい(というか説明できるほど知らない)
例としてはこんな感じです。
class Rgh < Formula # ツールの説明 desc "Creates GitHub release and upload asset files" # ホームページのurl homepage "https://github.com/k-nasa/rgh" # バイナリファイルのダウンロード先 url "https://github.com/k-nasa/rgh/releases/download/0.2.0/rgh_x86_64-apple-darwin.tar.gz" version "0.2.0" # バイナリファイルのハッシュ値 sha256 "8ecc01c8be96c67c6091e9a5df2f442d01dedeb056c1e7a27f93a6b3288cfcc7" def install # こうしておけばダウンロードしたファイルを解凍していい感じに実行パスに置いてくれる bin.install "rgh" end test do system "#{bin}/rgh --version" end end
今回作ったツールはGitHub releaseに実行バイナリがあるので、ダウンロードして、解凍して、パスを通す。ということをすればインストール終わりなので、Formulaファイルもシンプルです。 ツールによってはソースコードからビルドして、ビルドのために〇〇が必要なので依存関係を解決して〜と色々とやっている事もあります。
ハッシュ値は以下のようなコマンドで求めることができます。また、間違った値にしていても、brew install
をしたときに、「なんかハッシュ値違うんだけど?こっちじゃない?」と教えてくれるので、間違っても問題ないです。
shasum -a 256 dist/prf_x86_64-apple-darwin.tar.gz
いざインストール!!
あとはbrew install
するだけ!
brew tap <あなたのGitHub id>/<ツール名> brew install <ツール名>
homebrewだけでいいのか?
macユーザーの人〜?
はーい。
じゃあそれ以外の人〜?
(しーん、、、)
となるような世の中であればhomebrewで公開するだけで良いとは思いますが、現実はそうではありません。Windowsの人,linuxの人などもいるでしょう。
しかし、それぞれのOSにhomebrew的な存在があるとは限りませんし、何より、個人でツールを作っているようなら、それぞれに公開するという手間は相当なもののはずです。
なので、GitHub releaseを活用して、windows, linux, mac用のバイナリをアップロードするようにしています。
こうしておくことで、curlで落として解凍してpathを通すだけで使うことができます。
curl -L -o goku.tar.gz https://github.com/k-nasa/goku/releases/download/0.1.1/goku_x86_64-apple-darwin.tar.gz tar -zxvf goku.tar.gz # Move binary file to the path
brewに比べれば面倒くささは有るのですが、開発者の手間と使用者の手間を考えれば悪くないトレードオフだと思います。
バージョンアップのたびにバイナリアップロードするのか?
バージョンアップのたびにtarで固めて(固めなくてもいいけど)GitHub releaseにアップロードするのって面倒くさい!
しかも、複数OSに向けた実行ファイルがあるので、それが増えれば増えるほど手間になる。。。。ひーん。
複数OSに向けた実行バイナリ作成(クロスコンパイル)は一度調べれば次から手間ではないんですが、手動で毎回アップロードするのは非常に面倒くさいです。
なので、アップロードのためのツールを作りました。
コチラのツールのパクリです。
普段CLIツールはRustで書いているのですがCIでGitHub releaseまでやろうと考えると、アップロードツールもRustにしてたほうが良いかなーと思い、作りました。
rgh <タグ名> <ディレクトリ>
とすることで、ディレクトリ配下のファイルをすべてアップロードできます。
rust製のツールはこんな感じのMakefileを書いてクロスコンパイルしてアップロードするようにしています。
# x86_64-unknown-linux-gnu # x86_64-apple-darwin # x86_64-pc-windows-gnu BIN_NAME:=prf.exe CRATE_NAME:=prf MISC:= README.md LICENSE DIRNAME:=${CRATE_NAME}_${TARGET} .PHONY: release_all release_all: rm -rf dist/ make release TARGET=x86_64-pc-windows-gnu BIN_NAME=${BIN_NAME} make release TARGET=x86_64-apple-darwin BIN_NAME=${CRATE_NAME} make release TARGET=x86_64-unknown-linux-gnu BIN_NAME=${CRATE_NAME} .PHONY: release release: cross build --target ${TARGET} --release # rustのクロスコンパイル mkdir -p ${DIRNAME} \ cp ./target/${TARGET}/release/${BIN_NAME} ${DIRNAME} cp ${MISC} ${DIRNAME} \ mkdir -p dist tar czf dist/${DIRNAME}.tar.gz ${DIRNAME} rm -rf ${DIRNAME}
そもそもFormulaを弄りたくない(今後の展望)
今後の展望ですが、ボクはいまバージョンアップのたびにFormulaファイルのダウンロードリンクとハッシュ値を手動で変更しています。
しかし、クソほど面倒くさい作業です。
なので、ココも自動化したいお気持ちです。来月中にそこら編もいい感じに出来るGitHub actionでも作りたい。
宣伝。作ったもの紹介
最後に、せっかくなので、今月に作ったツールの紹介をさせて下さい。
rghはもう紹介しましたが。
goku
vegetaというベンチマーカーが有るらしく、それならgokuもあっていいだろと思い作りました。
かめはめ波コマンドを打つことでサーバーにリクエストを投げることができます。
goku kamehameha -c 10 -n 10000 'http://127.0.0.1:8080' # or goku attack -c 10 -n 10000 'http://127.0.0.1:8080'
完全にギャグツールです。がちょこちょこ便利にしていく予定です!
応援、Contributeお待ちしております!
rgh
先程も紹介したやつですね。
これはgokuをGitHub releaseにアップロードするためだけに作りました。
完全にgokuのおまけですが、star数はこっちのほうが高いという。謎。
prf
これは昨日作りました。
試したいPRブランチがあったときに
git fetch upstream pull/503/head:random_merge
このようなコマンドを打って、ローカルリポジトリにfetchしていたんですが、PR番号とブランチ名の2つの情報が必要になります。
これは地味に面倒です。 しかもブランチ名は <forkしたユーザーID>:<ブランチ名>
となっているため、コピーボタンを押しても必要な箇所だけが、クリップボードにコピーされるわけではありません。
なので、PR番号とremoteの向き先を指定するとPRブランチをローカルにfetchするツールを作りました。
prf 55 upstream
こんな感じに
最後に
最後まで読んでくれて(最後を覗き見してくれて?)ありがとうございました。
なんかテーマのブレブレで「お前、結局何が伝えたいねん!」となる文章でしたが、許して下さい。
現在nasaはGitHubのスターを集めることに固執しており、star欠乏症になっています。
今回紹介したツールのリンクを張っておくのでスターボタンをポチッと押して、やる気エナジーを下さい!(もちろん、「いいね!」と思ったらですよ)