如何在字符串参数中对rake任务使用逗号?

时间:2022-08-03 02:32:21

I have the following Rakefile:

我有以下录音:

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

And want to call it with a single string argument containing commas. Here's what I get:

要用一个包含逗号的字符串参数调用它。这就是我得到:

%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\

I'm currently using the workaround proposed in this pull request to rake, but is there a way to accomplish this without patching rake?

我目前正在使用这个拖拽请求中提出的解决方案来rake,但是是否有一种方法可以在不需要patching rake的情况下完成这个任务呢?

8 个解决方案

#1


6  

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

我不确定这是否可能。查看lib /耙/应用程序。rb,解析任务字符串的方法为:

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.

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

#2


8  

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

改变耙子是一个很棘手的问题。试着用OptionParser代替。后的语法

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

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

—是跳过解析参数的rake方法的必要条件

and here's the ruby code:

下面是ruby代码:

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

#3


3  

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:

这个版本的parse_task_string_masked_commasallow调用带有隐藏的逗号:

rake test_commas[1\,2\,3]

The version parse_task_string_combined allows:

版本parse_task_string_combined允许:

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)

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

#4


3  

Rake task variables are not very convenient generally, instead use environment variables:

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

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

Then you can invoke with

然后可以调用。

MY_ARGUMENT=foo,bar rake my_task

Or if you prefer

或者如果你喜欢

rake my_task MY_ARGUMENT=foo,bar

#5


3  

Have you tried escaping the , with a \?

你试过逃避吗?

#6


0  

Another simple workaround is to use a different delimiter in your arguments.

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

It's pretty simple to swap to a pipe | character (or another) instead of your comma separated args. Rake parses your arguments correctly in this case and allows you to split the first for an array.

切换到管道|字符(或其他字符)而不是逗号分隔的args非常简单。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

Call it with:

叫它:

rake test_pipes["foo|bar",baz]

#7


0  

We can convert each string to symbol, 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

run as,

运行,

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

耙创建'1,s' 2' ww ww' w,w'

#8


0  

# rake -v 10.5

# rake - v 10.5

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

rake test_commas \[“foo \,bar”\]

works like a charm.

就像一个魅力。

#1


6  

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

我不确定这是否可能。查看lib /耙/应用程序。rb,解析任务字符串的方法为:

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.

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

#2


8  

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

改变耙子是一个很棘手的问题。试着用OptionParser代替。后的语法

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

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

—是跳过解析参数的rake方法的必要条件

and here's the ruby code:

下面是ruby代码:

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

#3


3  

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:

这个版本的parse_task_string_masked_commasallow调用带有隐藏的逗号:

rake test_commas[1\,2\,3]

The version parse_task_string_combined allows:

版本parse_task_string_combined允许:

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)

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

#4


3  

Rake task variables are not very convenient generally, instead use environment variables:

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

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

Then you can invoke with

然后可以调用。

MY_ARGUMENT=foo,bar rake my_task

Or if you prefer

或者如果你喜欢

rake my_task MY_ARGUMENT=foo,bar

#5


3  

Have you tried escaping the , with a \?

你试过逃避吗?

#6


0  

Another simple workaround is to use a different delimiter in your arguments.

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

It's pretty simple to swap to a pipe | character (or another) instead of your comma separated args. Rake parses your arguments correctly in this case and allows you to split the first for an array.

切换到管道|字符(或其他字符)而不是逗号分隔的args非常简单。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

Call it with:

叫它:

rake test_pipes["foo|bar",baz]

#7


0  

We can convert each string to symbol, 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

run as,

运行,

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

耙创建'1,s' 2' ww ww' w,w'

#8


0  

# rake -v 10.5

# rake - v 10.5

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

rake test_commas \[“foo \,bar”\]

works like a charm.

就像一个魅力。