How to pass command line arguments to a rake task How to pass command line arguments to a rake task ruby ruby

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"