How can I use a comma in a string argument to a rake task?

Eugen already answered, why it doesn't work.

But perhaps the following workaround may help you:

task :test_commas, :arg1, :arg2 do |t, args|
  arg = args.to_hash.values.join(',')
  puts "Argument is #{arg.inspect}"
end

It takes two arguments, but joins them to get the 'real' one.

If you have more then one comma, you need more arguments.


I did some deeper research and found one (or two) solution. I don't think it's a perfect solution, but it seems it works.

require 'rake'
module Rake
  class Application
    #usage: 
    #   rake test_commas[1\,2\,3]
    def parse_task_string_masked_commas(string)
      if string =~ /^([^\[]+)(\[(.*)\])$/
        name = $1
        args = $3.split(/\s*(?<!\\),\s*/).map{|x|x.gsub(/\\,/,',')}
      else
        name = string
        args = []
      end 
      [name, args]
    end   

    #Usage: 
    #   rake test_commas[\"1,2\",3]
    #" and ' must be masked
    def parse_task_string_combined(string)
      if string =~ /^([^\[]+)(\[(.*)\])$/
        name = $1
        args = $3.split(/(['"].+?["'])?,(["'].+?["'])?/).map{|ts| ts.gsub(/\A["']|["']\Z/,'') }
        args.shift if args.first.empty?
      else
        name = string
        args = []
      end 
      [name, args]
    end   

    #~ alias :parse_task_string :parse_task_string_masked_commas
    alias :parse_task_string :parse_task_string_combined

  end

end
desc 'Test comma separated arguments'
task :test_commas, :arg1  do |t, args|
  puts '---'
  puts "Argument is #{args.inspect}"
end

The version parse_task_string_masked_commasallows calls with masked commas:

rake test_commas[1\,2\,3]

The version parse_task_string_combined allows:

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

At least under windows, the " (or ') must be masked. If not, they are already deleted until the string reached Rake::Aplication (probably shell substitution)


Changing rake is quite a dirty fix. Try using OptionParser instead. The syntax is following

$ rake mytask -- -s 'some,comma,sepparated,string'

the -- is necessary to skip the rake way of parsing the arguments

and here's the ruby code:

task :mytask do
  options = {}

  optparse = OptionParser.new do |opts|
    opts.on('-s', '--string ARG', 'desc of my argument') do |str|
      options[:str] = str
    end

    opts.on('-h', '--help', 'Display this screen') do     
      puts opts                                                          
      exit                                                                      
    end 
  end

  begin 
    optparse.parse!
    mandatory = [:str]
    missing = mandatory.select{ |param| options[param].nil? }
    if not missing.empty?
      puts "Missing options: #{missing.join(', ')}"
      puts optparse
      exit
    end

  rescue OptionParser::InvalidOption, OptionParser::MissingArgument
    puts $!.to_s
    puts optparse
    exit  
  end

  puts "Performing task with options: #{options.inspect}"
  # @TODO add task's code
end

I'm not sure it's possible. Looking at lib/rake/application.rb, the method for parsing the task string is:

def parse_task_string(string)
  if string =~ /^([^\[]+)(\[(.*)\])$/
    name = $1
    args = $3.split(/\s*,\s*/)
  else
    name = string
    args = []
  end 
  [name, args]
end 

It appears that the arguments string is split by commas, so you cannot have an argument that contains a comma, at least not in the current rake-0.9.2.