20

我有以下Rakefile

task :test_commas, :arg1 do |t, args|
  puts args[:arg1]
end

并希望使用包含逗号的单个字符串参数来调用它。这是我得到的:

%rake 'test_commas[foo, bar]'
foo

%rake 'test_commas["foo, bar"]'
"foo

%rake "test_commas['foo, bar']"
'foo

%rake "test_commas['foo,bar']"
'foo

%rake "test_commas[foo\,bar]"
foo\

我目前正在使用此拉取请求中提出的解决方法来 rake,但是有没有办法在不修补 rake 的情况下完成此操作?

4

9 回答 9

10

改变 rake 是一个相当肮脏的修复。尝试OptionParser改用。语法如下

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

--必要跳过解析参数的 rake 方式

这是红宝石代码:

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
于 2012-07-18T12:04:18.873 回答
8

我不确定这是否可能。看了一下lib/rake/application.rb,解析任务字符串的方法是:

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

看来参数字符串是用逗号分隔的,所以你不能有一个包含逗号的参数,至少在当前的 rake-0.9.2 中没有。

于 2011-08-31T15:29:26.770 回答
4

Eugen 已经回答了,为什么它不起作用。

但也许以下解决方法可以帮助您:

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

它需要两个参数,但加入它们以获得“真正的”一个。

如果您有多个逗号,则需要更多参数。


我做了一些更深入的研究并找到了一个(或两个)解决方案。我不认为这是一个完美的解决方案,但它似乎有效。

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

该版本parse_task_string_masked_commas允许使用带掩码的逗号进行调用:

rake test_commas[1\,2\,3]

该版本parse_task_string_combined允许:

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

至少在windows下,必须屏蔽"(或')。如果没有,它们已经被删除,直到字符串到达​​Rake::Aplication(可能是shell替换)

于 2011-08-31T19:10:54.397 回答
3

您是否尝试过,使用 a转义\

于 2011-08-31T14:12:54.133 回答
3

rake任务变量一般不是很方便,而是使用环境变量:

task :my_task do
  ENV["MY_ARGUMENT"].split(",").each_with_index do |arg, i|
    puts "Argument #{i}: #{arg}"
  end
end

然后你可以调用

MY_ARGUMENT=foo,bar rake my_task

或者,如果您愿意

rake my_task MY_ARGUMENT=foo,bar
于 2015-07-22T16:57:45.587 回答
2

# rake -v 10.5

rake test_commas\['foo\,bar'\]

奇迹般有效。

于 2017-06-13T14:49:40.073 回答
2

对于 rake 版本 12.3.2,

耙 test_commas["foo\,bar"]

效果很好

于 2019-09-18T17:49:29.830 回答
1

另一个简单的解决方法是在参数中使用不同的分隔符。

换成管道很简单 | 字符(或另一个)而不是逗号分隔的参数。在这种情况下,Rake 会正确解析您的参数,并允许您将第一个参数拆分为数组。

desc 'Test pipe separated arguments'
task :test_pipes, :arg1, :arg2  do |t, args|
  puts ":arg1 is: #{ args[:arg1] }"
  puts ":arg2 still works: #{ args[:arg2] }"
  puts "Split :arg1 is: #{ args[:arg1].split('|') }"
end

调用它:

rake test_pipes["foo|bar",baz]
于 2014-05-20T16:49:52.243 回答
0

我们可以将每个字符串转换为符号 As,

task :create do   
ARGV.each { |a| task a.to_sym do ; end }
 puts ARGV[1]
 puts ARGV[2]
 puts ARGV[3]
 puts ARGV[4]     
end
end

运行为,

rake create '1,s' '2' 'ww ww' 'w,w'

于 2016-12-09T07:13:38.353 回答