する必要がある:
これは Rakefile 内で定義されたタスクを見つけるために機能しますが、グローバル名前空間を汚染します (つまり、これを 2 回実行すると、最初のタスクで定義されたすべてのタスクが 2 番目のタスクに表示されます)。
sub_rake = Rake::DefaultLoader.new
sub_rake.load("Rakefile")
puts Rake.application.tasks
Rake では、ここで Makefile がロードされます。
そこにロードされている変数にアクセスするにはどうすればよいですか?
これは私が解析している Rakefile の例です。
load '../common.rake'
@source_dir = 'source'
desc "Run all build and deployment tasks, for continuous delivery"
task :deliver => ['git:pull', 'jekyll:build', 'rsync:push']
ここでは私が試してみてうまくいかなかったことがいくつかあります。 Rakefile で eval を使用する:
safe_object = Object.new
safe_object.instance_eval("Dir.chdir('" + f + "')\n" + File.read(folder_rakefile))
if safe_object.instance_variable_defined?("@staging_dir")
puts " Staging directory is " + f.yellow + safe_object.instance_variable_get("@staging_dir").yellow
else
puts " Staging directory is not specified".red
end
これは、Rakefile の記述部分を解析するときに失敗しました。私も次のようなことを試しました
puts Rake.instance_variables
puts Rake.class_variables
しかし、これらは私が探している @source_dir を取得できません。
rakefile_body = <<-RUBY
load '../common.rake'
@source_dir = 'some/source/dir'
desc "Run all build and deployment tasks, for continuous delivery"
task :deliver => ['git:pull', 'jekyll:build', 'rsync:push']
RUBY
def source_dir(ast)
return nil unless ast.kind_of? AST::Node
if ast.type == :ivasgn && ast.children[0] == :@source_dir
rhs = ast.children[1]
if rhs.type != :str
raise "@source_dir is not a string literal! #{rhs.inspect}"
else
return rhs.children[0]
end
end
ast.children.each do |child|
value = source_dir(child)
return value if value
end
nil
end
require 'parser/ruby22'
body = Parser::Ruby22.parse(rakefile_body)
source_dir body # => "some/source/dir"