Как я могу использовать запятую в строковом аргументе для граблей? - PullRequest
13 голосов
/ 31 августа 2011

У меня есть следующее 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\

В настоящее время я использую обходной путь, предложенный в этом запросе на получение, для рейка , но есть ли способ сделать это без внесения изменений в рейк?

Ответы [ 8 ]

8 голосов
/ 18 июля 2012

Изменение рейка довольно грязное решение. Попробуйте использовать OptionParser вместо этого. Синтаксис следующий

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

-- необходимо пропустить рейк-способ разбора аргументов

и вот код рубина:

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
6 голосов
/ 31 августа 2011

Я не уверен, что это возможно. Глядя на 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 

Похоже, что строка аргументов разделена запятыми, поэтому у вас не может быть аргумента, который содержит запятую, по крайней мере, в текущей грабли-0.9.2.

3 голосов
/ 22 июля 2015

Переменные задачи 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
3 голосов
/ 31 августа 2011

Евгений уже ответил , почему это не работает.

Но, возможно, вам поможет следующий обходной путь:

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\"]

По крайней мере под окнами "(или ') должны быть замаскированы. Если нет, они уже удаляются, пока строка не достигнет Rake :: Aplication (возможно, подстановка оболочки)

3 голосов
/ 31 августа 2011

Вы пытались сбежать от , с \?

1 голос
/ 13 июня 2017

# rake -v 10.5

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

работает как шарм.

0 голосов
/ 09 декабря 2016

Мы можем преобразовать каждую строку в символ, Как,

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'

0 голосов
/ 20 мая 2014

Другой простой обходной путь - использование другого аргумента в качестве аргумента.

Довольно просто поменять местами канал |символ (или другой) вместо аргументов, разделенных запятой.В этом случае Rake правильно анализирует ваши аргументы и позволяет вам разбить первый массив на массив.

...