Nathan Long
Nathan Long

Reputation: 125912

How can I pass an array as an argument to a Rake task?

I'm writing a Rake task and I want to pass an array as one of the arguments. Here's how I currently have it.

task :change_statuses, :ids, :current_status, :new_status do |task, args|
  puts "args were #{args.inspect}"
end

I've tried running the task these ways:

# First argument as array
rake "change_statuses[[1,2,3], active, inactive]"

# First argument as string
rake "utility:change_account_statuses['1,2,3', foo, bar]"

My expected output would be:

args were {:ids=> [1,2,3], :current_status=> 2 , :new_status=> 3}

However, my actual output in each case is:

args were {:ids=>"[1", :current_status=>"2", :new_status=>"3]"}

How can I pass an array to a Rake task?

Upvotes: 43

Views: 25977

Answers (5)

LongBearded
LongBearded

Reputation: 71

You can also try to change the approach a little, and try to fetch ids with the arg.extras method.

$ rake change_statuses[foo, bar, 1, 2, 3]
task :change_statuses, [:foo, :bar] do |_task, args|
  puts args[:foo]     # => foo
  puts args[:bar]     # => bar
  puts args.extras    # => ["1","2","3"]
end

You can find more information in this article -> https://blog.stevenocchipinti.com/2013/10/18/rake-task-with-an-arbitrary-number-of-arguments/

Upvotes: 7

MatayoshiMariano
MatayoshiMariano

Reputation: 2096

Another way to achieve this and also win the ability to pass a hash

namespace :stackoverflow do
  desc 'How to pass an array and also a hash at the same time 8-D'
  task :awesome_task, [:attributes] do |_task, args|
    options = Rack::Utils.parse_nested_query(args[:attributes])
    puts options
  end
end

And just call the rake task like this:

bundle exec rake "stackoverflow:awesome_task[what_a_great_key[]=I know&what_a_great_key[]=Me too\!&i_am_a_hash[and_i_am_your_key]=what_an_idiot]"

And that will print

{"what_a_great_key"=>["I know", "Me too!"], "i_am_a_hash"=>{"and_i_am_your_key"=>"what_an_idiot"}}

Upvotes: 3

Spyros
Spyros

Reputation: 247

You can do this as an alternative:

 task :my_task, [:values] do |_task, args|
   values = args.values.split(',')
   puts values
 end

and run the task using

rake my_task"[1\,2\,3]"

Upvotes: 1

William Herry
William Herry

Reputation: 1450

rake "change_statuses[1 2 3, foo, bar]"

this works for me, you should not quota 1 2 3 with '

task :import_course, [:cids, :title] => :environment do |t, args|
  puts args[:cids]
end

if you quota 1 2 3 as the correct answer, args[:cids] will be "'1 2 3'", which ' char included, you have to trim ' char, but if you use my answer, args[:cids] will be "1 2 3", which is more easy to use, you just need args[:cids].split(" ") to get [1, 2, 3]

Upvotes: 2

lks128
lks128

Reputation: 986

One of the soulutions is to avoid , symbol in the string, so your command line would look like:

$ rake change_statuses['1 2 3', foo, bar]

Then you can simply split the IDs:

# Rakefile

task :change_statuses, :ids, :current_status, :new_status do |task, args|
  ids = args[:ids].split ' '

  puts "args were #{args.inspect}"
  puts "ids were #{ids.inspect}"
end

Or you can parse the ids value to get your expected output:

args[:ids] = args[:ids].split(' ').map{ |s| s.to_i }

I'm using rake 0.8.7

Upvotes: 58

Related Questions