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

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


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 codeend


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.


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  endenddesc '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)