Techioz Blog

コマンドライン引数を rake タスクに渡す方法

概要

複数のデータベースに値を挿入する必要がある rake タスクがあります。

コマンドラインまたは別の rake タスクからこの値を rake タスクに渡したいと考えています。

これどうやってするの?

解決策

rake で仮引数を指定するには、タスク呼び出しにシンボル引数を追加します。例えば:

require 'rake'

task :my_task, [:arg1, :arg2] do |t, args|
  puts "Args were: #{args} of class #{args.class}"
  puts "arg1 was: '#{args[:arg1]}' of class #{args[:arg1].class}"
  puts "arg2 was: '#{args[:arg2]}' of class #{args[:arg2].class}"
end

task :invoke_my_task do
  Rake.application.invoke_task("my_task[1, 2]")
end

# or if you prefer this syntax...
task :invoke_my_task_2 do
  Rake::Task[:my_task].invoke(3, 4)
end

# a task with prerequisites passes its 
# arguments to it prerequisites
task :with_prerequisite, [:arg1, :arg2] => :my_task #<- name of prerequisite task

# to specify default values, 
# we take advantage of args being a Rake::TaskArguments object
task :with_defaults, :arg1, :arg2 do |t, args|
  args.with_defaults(:arg1 => :default_1, :arg2 => :default_2)
  puts "Args with defaults were: #{args}"
end

次に、コマンドラインから次のようにします。


> rake my_task[1,false]
Args were: {:arg1=>"1", :arg2=>"false"} of class Rake::TaskArguments
arg1 was: '1' of class String
arg2 was: 'false' of class String

> rake "my_task[1, 2]"
Args were: {:arg1=>"1", :arg2=>"2"}

> rake invoke_my_task
Args were: {:arg1=>"1", :arg2=>"2"}

> rake invoke_my_task_2
Args were: {:arg1=>3, :arg2=>4}

> rake with_prerequisite[5,6]
Args were: {:arg1=>"5", :arg2=>"6"}

> rake with_defaults
Args with defaults were: {:arg1=>:default_1, :arg2=>:default_2}

> rake with_defaults['x','y']
Args with defaults were: {:arg1=>"x", :arg2=>"y"}

2 番目の例で示したように、スペースを使用する場合は、シェルがスペースで引数を分割しないように、ターゲット名を引用符で囲む必要があります。

rake.rb のコードを見ると、rake はタスク文字列を解析して前提条件の引数を抽出しないように見えるため、 task :t1 => “dep[1,2]” を実行することはできません。前提条件に異なる引数を指定する唯一の方法は、:invoke_my_task および :invoke_my_task_2 のように、依存タスク アクション内で前提条件を明示的に呼び出すことです。

一部のシェル (zsh など) では、角括弧をエスケープする必要があることに注意してください: rake my_task[‘arg1’]