Ink

Contents related to tech, hobby, etc

Dfinity SDKのHomebrew formulae(非公式)を書いた

|

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 を返してくれる。