I've got a rake task that I am making that needs to insert a value into multiple databases.
I'd like to be able to pass this value into the rake task from the command line, or from another rake task, how can I do this?
I've got a rake task that I am making that needs to insert a value into multiple databases.
I'd like to be able to pass this value into the rake task from the command line, or from another rake task, how can I do this?
You can specify formal arguments in rake by adding symbol arguments to the task call. For example:
require 'rake'
task :my_task, :arg1, :arg2 do |t, args|
puts "Args were: #{args}"
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, :needs => :my_task
# equivalently...
task :with_prerequisite_2, [:arg1, :arg2] => :my_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
Then, from the command line:
F:\test\rake>rake my_task[1,2]
(in F:/test/rake)
Args were: {:arg1=>"1", :arg2=>"2"}
F:\test\rake>rake "my_task[1, 2]"
(in F:/test/rake)
Args were: {:arg1=>"1", :arg2=>"2"}
F:\test\rake>rake invoke_my_task
(in F:/test/rake)
Args were: {:arg1=>"1", :arg2=>"2"}
F:\test\rake>rake invoke_my_task_2
(in F:/test/rake)
Args were: {:arg1=>3, :arg2=>4}
F:\test\rake>rake with_prerequisite[5,6]
(in F:/test/rake)
Args were: {:arg1=>"5", :arg2=>"6"}
F:\test\rake>rake with_prerequisite_2[7,8]
(in F:/test/rake)
Args were: {:arg1=>"7", :arg2=>"8"}
F:\test\rake>rake with_defaults
(in F:/test/rake)
Args with defaults were: {:arg1=>:default_1, :arg2=>:default_2}
F:\test\rake>rake with_defaults['x','y']
(in F:/test/rake)
Args with defaults were: {:arg1=>"x", :arg2=>"y"}
As demonstrated in the second example, if you want to use spaces, the quotes around the target name are necessary to keep the shell from splitting up the arguments at the space.
Looking at the code in rake.rb
, it appears that rake does not parse task strings to extract arguments for prerequisites, so you can't do task :t1 => "dep[1,2]"
. The only way to specify different arguments for a prerequisite would be to invoke it explicitly within the dependent task action, as in :invoke_my_task
and :invoke_my_task_2
.
I've found the answer from these two websites: Net Maniac and Aimred.
You need to have version > 0.8 of rake to use this technique
The normal rake task description is this:
desc 'Task Description'
task :task_name => [:depends_on_taskA, :depends_on_taskB] do
#interesting things
end
To pass arguments, do three things:
To access the arguments in the script, use args.arg_name
desc 'Takes arguments task'
task :task_name, :display_value, :display_times, :needs => [:depends_on_taskA, :depends_on_taskB] do |t, args|
args.display_times.to_i.times do
puts args.display_value
end
end
To call this task from the command line, pass it the arguments in []s
rake task_name['Hello',4]
will output
Hello
Hello
Hello
Hello
and if you want to call this task from another task, and pass it arguments, use invoke
task :caller do
puts 'In Caller'
Rake::Task[:task_name].invoke('hi',2)
end
then the command
rake caller
will output
In Caller
hi
hi
I haven't found a way to pass arguments as part of a dependency, as the following code breaks:
task :caller => :task_name['hi',2]' do
puts 'In Caller'
end
Another commonly used option is to pass environment variables. In your code you read them via ENV['VAR']
, and can pass them right before the rake
command, like
$ VAR=foo rake mytask
I have a follow up question (for Nick Desjardins). I have copied your example here:
task :with_defaults, :arg1, :arg2 do |t, args|
args.with_defaults(:arg1 => :default_1, :arg2 => :default_2)
puts "Args with defaults were: #{args}"
end
and it works flawlessly but when I make the following change:
desc "Task with defaults"
task :my_task, :arg1, :arg2 do |t, args|
args.my_task(:arg1 => :default_1, :arg2 => :default_2)
puts "Args with defaults were: #{args}"
end
it falls flat on its face. Is there something I'm missing here?
Thanks in advance.