0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

railsのrake taskを深ぼる

0
Posted at

version

gem 'rails', '~> 6.0.0.rc1'

rails6のrc1です注意。

rakeとは

taskをrubyのdslで定義できるもの

Rakefileにタスク定義を書く

task :hoge do
  puts :hello
end

railsにおけるraketask

rails-sample-6/ [master]% bundle exec rake -T
rake about                              # List versions of all Rails frameworks and the environment
rake app:template                       # Applies the template supplied by LOCATION=(/path/to/template) or URL
rake app:update                         # Update configs and some other initially generated files (or use just update:configs or update:bin)
rake cache_digests:dependencies      
......
...

いっぱい出てくる
だけど、Rakefileを見てみると

# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.

require_relative 'config/application'

Rails.application.load_tasks

こんなけ

require_relative 'config/application'

は 'config/application' を読み込む
これはactivemodelとかGemとかを読み込むファイル。

Rails.application.load_tasks
を掘っていく

[2] pry(main)> $ Rails.application.load_tasks

def load_tasks(app = self)
  require "rake"
  run_tasks_blocks(app)
  self
end

[3] pry(main)> $ Rails.application.run_tasks_blocks

def run_tasks_blocks(app) #:nodoc:
  railties.each { |r| r.run_tasks_blocks(app) }
  super
  require "rails/tasks"
  task :environment do
    ActiveSupport.on_load(:before_initialize) { config.eager_load = false }

    require_environment!
  end
end

# super読んでるので親をみる

[4] pry(main)> Rails.application.class.ancestors
=> [RailsSample6::Application,
 Rails::Application,
 Rails::Engine,
 Rails::Railtie,
 Rails::Initializable,
 ActiveSupport::ToJsonWithActiveSupportEncoder,
 Object,
 PP::ObjectMixin,
 JSON::Ext::Generator::GeneratorMethods::Object,
 ActiveSupport::Tryable,
 ActiveSupport::Dependencies::Loadable,
 Kernel,
 BasicObject]

# 関係ありそうなのはRails::Engine, Rails::Railtie

[6] pry(main)> $ Rails::Engine#run_tasks_blocks

def run_tasks_blocks(*) #:nodoc:
  super
  paths["lib/tasks"].existent.sort.each { |ext| load(ext) }
end


# lib/tasksにあるfileをloadしている。
# 自分で定義したものがここで読まれていた。


[7] pry(main)> $ Rails::Railtie#run_tasks_blocks

def run_tasks_blocks(app) #:nodoc:
  extend Rake::DSL
  each_registered_block(:rake_tasks) { |block| instance_exec(app, &block) }
end

[15] pry(main)> $ Rails::Railtie#each_registered_block

def each_registered_block(type, &block)
  klass = self.class
  while klass.respond_to?(type)
    klass.public_send(type).each(&block)
    klass = klass.superclass
  end
end

# public_send :rake_tasks
# を親クラスに向かってしていく.

[16] pry(main)> $ Rails::Application.rake_tasks

def rake_tasks(&blk)
  register_block_for(:rake_tasks, &blk)
end

[17] pry(main)> $ Rails::Application.register_block_for

def register_block_for(type, &blk)
  var_name = "@#{type}"
  blocks = instance_variable_defined?(var_name) ? instance_variable_get(var_name) : instance_variable_set(var_name, [])
  blocks << blk if blk
  blocks
end

# ここまで見て
# Rails::Railtie#each_registered_block
# が、
# Rails::Application, Rails::Engine, Rails::Railtie
# が:rake_tasks用に保持してるProcをexecしていくのがわかった。
# それがなんなのかの深追いはやめて本筋に戻る。

[3] pry(main)> $ Rails.application.run_tasks_blocks

def run_tasks_blocks(app) #:nodoc:
  railties.each { |r| r.run_tasks_blocks(app) }
  super
  require "rails/tasks"
  task :environment do
    ActiveSupport.on_load(:before_initialize) { config.eager_load = false }

    require_environment!
  end
end

# `require 'rails/tasks'` は rails routesなどのコマンドを読み込むもの

[38] pry(main)> $ Rails.application.require_environment!

def require_environment! #:nodoc:
  environment = paths["config/environment"].existent.first
  require environment if environment
end

# これはconfig/environment.rbを読み込むもの
config/environment.rb
# Load the Rails application.
require_relative 'application'

# Initialize the Rails application.
Rails.application.initialize!

config/applicationはrakefileで読み込んでいるので
Rails.application.initialize!
を呼ぶ

[2] pry(main)> $ Rails.application.initialize!

def initialize!(group = :default) #:nodoc:
  raise "Application has been already initialized." if @initialized
  run_initializers(group, self)
  @initialized = true
  self
end

[3] pry(main)> $ Rails.application.run_initializers

def run_initializers(group = :default, *args)
  return if instance_variable_defined?(:@ran)
  initializers.tsort_each do |initializer|
    initializer.run(*args) if initializer.belongs_to?(group)
  end
  @ran = true
end

諸々のinitializersが実行される。
多分config/initializers/*
もこれで実行される。

もう疲れたから今日は終わり。

memo

desc 'hoge'
しないと rake -Tで出てこない

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?