Railsアプリはデフォルトでbin
配下に各種のbinstubを作成する。
bin/yarn
はyarnのbinstub。
bin/yarn
がどうやってyarnを実行しているのか気になったので、bin/yarn
のコードを読んでみた。
1. 実行環境
2. bin/yarn
自分の環境では以下のbin/yarn
ファイルが作成されていた。
#!/usr/bin/env ruby APP_ROOT = File.expand_path('..', __dir__) Dir.chdir(APP_ROOT) do yarn = ENV["PATH"].split(File::PATH_SEPARATOR). select { |dir| File.expand_path(dir) != __dir__ }. product(["yarn", "yarn.cmd", "yarn.ps1"]). map { |dir, file| File.expand_path(file, dir) }. find { |file| File.executable?(file) } if yarn exec yarn, *ARGV else $stderr.puts "Yarn executable was not detected in the system." $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install" exit 1 end end
3. コードの解説
APP_ROOT = File.expand_path('..', __dir__)
APP_ROOT
にはアプリのルートディレクトリのパスが入ってる__dir__
は実行中のファイルの絶対パスを返す→Users/hoge/myapp/bin
- File.expand_pathで
__dir__
の一つ上('..'
)のパスを返す→Users/hoge/myapp
Dir.chdir(APP_ROOT) do ~ end
- Dir.chdirでブロック内の処理を
APP_ROOT
で行うようにする
ENV["PATH"].split(File::PATH_SEPARATOR)
- パスを要素に持つ配列を返す
ENV["PATH"]
でパスの文字列を返すsplit(File::PATH_SEPARATOR)
でパスの文字列を:
で分割してそれぞれのパスを要素に持つ配列を返す
select { |dir| File.expand_path(dir) != __dir__ }
- パスの配列から
__dir__
(Users/hoge/myapp/bin
)を除いた配列を返す
product(["yarn", "yarn.cmd", "yarn.ps1"])
- パスの配列とファイル名の配列(
["yarn", "yarn.cmd", "yarn.ps1"]
)の直積を返す[1,2,3].product([4,5]) # => [[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]]
map { |dir, file| File.expand_path(file, dir) }
- 各組み合わせのフルパスを作成する
["/usr/local/bin", "yarn"]
だったら、"/usr/local/bin/yarn"
にする
find { |file| File.executable?(file) }
- 最初に見つかった実行可能なyarnファイルを返す→
"/usr/local/bin/yarn"
exec yarn, *ARGV
- execでyarnコマンドを実行する
【参考】