Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass command line arguments to a rake task

I have a rake task that needs to insert a value into multiple databases.

I'd like to pass this value into the rake task from the command line, or from another rake task.

How can I do this?

like image 426
Tilendor Avatar asked May 05 '09 16:05

Tilendor


People also ask

How do I run a rake task?

Go to Websites & Domains and click Ruby. After gems installation you can try to run a Rake task by clicking Run rake task. In the opened dialog, you can provide some parameters and click OK - this will be equivalent to running the rake utility with the specified parameters in the command line.

When would you use a rake task?

Rake allows you to define a list of other tasks that must run before the current task.

Where do I put rake tasks?

rake extension and are placed in Rails. root/lib/tasks . You can create these custom rake tasks with the bin/rails generate task command. If your need to interact with your application models, perform database queries and so on, your task should depend on the environment task, which will load your application code.


2 Answers

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}" 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 

Then, from the command line:

 > 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"} 

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'\]

like image 156
Nick Desjardins Avatar answered Oct 20 '22 15:10

Nick Desjardins


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)   end  end 

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 
like image 21
Blair Anderson Avatar answered Oct 20 '22 16:10

Blair Anderson