[コードリーディング] Rails の Rakefile がどのように lib/tasks の rake ファイルを読み込んでいるか
概要
Railsの Rakefile がどのように lib/tasksのrakeファイルを読み込んでいるかについて
コードリーディングをしました。
コードリーディング
Rakefile
rails new で生成された Rakefile には以下の処理があります。
Rails.application.load_tasks
Rails.application.load_tasks
GitHubの rails リポジトリを検索した結果、
rails / railties / lib / rails / engine.rb
で該当の処理が見つかりました。
# Load Rake, railties tasks and invoke the registered hooks.
# Check <tt>Rails::Railtie.rake_tasks</tt> for more info.
def load_tasks(app=self)
require "rake"
run_tasks_blocks(app)
self
end
rake を require して、 run_tasks_blocks というメソッドを呼んでいるようです。
run_tasks_blocks
Rails.application.load_tasks と同一クラスの protected method として定義されています。
def run_tasks_blocks(*) #:nodoc:
super
paths["lib/tasks"].existent.sort.each { |ext| load(ext) }
end
pathsは rails / railties / lib / rails / engine / configuration.rb 内の処理で
Railsで扱う各種パスの配列を保持しています。
この配列の中に、下記が含まれています。
paths.add "lib/tasks", glob: "**/*.rake"
existent はファイルの存在チェックをして、存在するファイルのみを抽出しています。
つまり、 lib/tasks 配下の全ての rake ファイルをソートして load しているということになります。
試してみる
試しに下記の rake ファイルを作成して検証してみます。
$ cd lib/tasks
$ tree
|-- a
| `-- a.rake
|-- aaaa.rake
|-- z
| `-- z.rake
`-- zzzz.rake
各ファイルには以下のような内容が記述されています
lib/tasks/a/a.rake
puts "a/a.rake loaded"
lib/tasks/aaaa.rake
puts "aaaa.rake loaded"
lib/tasks/z/z.rake
puts "z/z.rake loaded"
lib/tasks/zzzz.rake
puts "zzzz.rake loaded"
では、 rake -T を呼び出してみます。
$ rake -T
(in /home/vagrant/work_rails/blog)
a/a.rake loaded
aaaa.rake loaded
z/z.rake loaded
zzzz.rake loaded
rake about # List versions of all Rails framew...
rake assets:clean[keep] # Remove old compiled assets
# :
# : 以下略
確かにソートされてロードされているようです。