How to pass command line arguments to a rake task
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} of class #{args.class}" puts "arg1 was: '#{args[:arg1]}' of class #{args[:arg1].class}" puts "arg2 was: '#{args[:arg2]}' of class #{args[:arg2].class}"endtask :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 prerequisitestask :with_prerequisite, [:arg1, :arg2] => :my_task #<- name of prerequisite task# to specify default values, # we take advantage of args being a Rake::TaskArguments objecttask :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:
> rake my_task[1,false]Args were: {:arg1=>"1", :arg2=>"false"} of class Rake::TaskArgumentsarg1 was: '1' of class Stringarg2 was: 'false' of class String> rake "my_task[1, 2]"Args were: {:arg1=>"1", :arg2=>"2"}> rake invoke_my_taskArgs were: {:arg1=>"1", :arg2=>"2"}> rake invoke_my_task_2Args were: {:arg1=>3, :arg2=>4}> rake with_prerequisite[5,6]Args were: {:arg1=>"5", :arg2=>"6"}> rake with_defaultsArgs with defaults were: {:arg1=>:default_1, :arg2=>:default_2}> rake with_defaults['x','y']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
.
Note that some shells (like zsh) require you to escape the brackets: rake my_task\['arg1'\]
Options and dependencies need to be inside arrays:
namespace :thing do desc "it does a thing" task :work, [:option, :foo, :bar] do |task, args| puts "work", args end task :another, [:option, :foo, :bar] do |task, args| puts "another #{args}" Rake::Task["thing:work"].invoke(args[:option], args[:foo], args[:bar]) # or splat the args # Rake::Task["thing:work"].invoke(*args) endend
Then
rake thing:work[1,2,3]=> work: {:option=>"1", :foo=>"2", :bar=>"3"}rake thing:another[1,2,3]=> another {:option=>"1", :foo=>"2", :bar=>"3"}=> work: {:option=>"1", :foo=>"2", :bar=>"3"}
NOTE: variable
task
is the task object, not very helpful unless you know/care about Rake internals.
RAILS NOTE:
If running the task from Rails, it's best to preload the environment by adding
=> [:environment]
which is a way to setup dependent tasks.
task :work, [:option, :foo, :bar] => [:environment] do |task, args| puts "work", args end
In addition to answer by kch (I didn't find how to leave a comment to that, sorry):
You don't have to specify variables as ENV
variables before the rake
command. You can just set them as usual command line parameters like that:
rake mytask var=foo
and access those from your rake file as ENV variables like such:
p ENV['var'] # => "foo"