Dfinity SDKのHomebrew formulae(非公式)を書いた
Dfinity SDKは標準のインストーラーが付属するが、 これをHomebrew管理したかったのでラッパーとなるようにFormulaを書いた。
尚これは非公式なものであること・あまりHomebrewのformulaeとしては お行儀良くないことは留意していただきたい。
使い方
brew tap cj-bc/dfx
brew install dfx
技術的メモ
環境変数を設定する
https://docs.brew.sh/Formula-Cookbook#using-environment-variables
ENV["DFX_INSTALL_ROOT"] = prefix
ビルド中の一時ディレクトリにファイルを保存する
https://docs.brew.sh/Formula-Cookbook#variables-for-directory-locations
#{hoge}
はRubyの記法で、文字列の中に変数を埋め込むことができる。
system "curl -fsSL https://sdk.dfinity.org/install.sh > #{buildpath}/install.sh"
system
等で実行したいプログラムの標準入出力を操作する
brewのrubydocのFormula.testの部分に書かれているのだが、どうやら open3
という
ライブラリを使えるらしい。(筆者のRuby歴はHomebrew formulaeを除けば0)
ということでその例を拝借して書き換えてみると:
require "open3"
Open3.popen3("sh", "-i install.sh") do |stdin, stdout, _, th|
# ここでIO処理をする
end
ユーザーの入力を受け付けてそれをプログラムに渡す
今回の公式のインストールスクリプトは、ライセンスへの同意をキー入力で答える必要があります。 これのためには、homebrew側で受け取ったキー入力をスクリプトに渡してあげる必要があります。
stdin
を先程の Open3.popen3
で設定した変数だとすると、以下のようにすることで
入力のバイパスが出来ました。
stdin << $stdin.gets
Rubyにおいて、 $変数名
は「グローバル変数」を指します。
なので、グローバルにhomebrewが扱っている標準入力を $stdin
として参照しています。
スレッドを待機させる必要がありそう
単純に Open3.popen3
を使った場合、その処理を行っているスレッドは別スレッドとして非同期的に処理がされるようです。
なので、このままだとそちらの処理が終わる前にプログラムが進んでしまいます。
他の言語での await
のような機能として、 <thread>.join
を使います。
Open3.popen3("sh", "-i", "#{buildpath}/install.sh") do |stdin, stdout, stderr, t|
# やりたい処理
t.join
end
とすることで、 sh -i install.sh
が終了するまで待つことができます。
文字列にある文字列が含まれるかを確認する
String#match?(/<Regex>/)
を使うことで、正規表現 <Regex>
がマッチしたなら true
, しなかったら false
を返してくれる。