Как я могу использовать запятую в строковом аргументе для задачи грабли?
У меня есть следующий файл 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\
В настоящее время я использую обходное решение, предложенное в этом запросе на тягу для рейка, но есть ли способ сделать это без патча рейка?
Ответы
Ответ 1
Я не уверен, что это возможно. Рассматривая 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.
Ответ 2
Изменение грабли - довольно грязное исправление. Вместо этого используйте OptionParser
. Синтаксис следующий
$ rake mytask -- -s 'some,comma,sepparated,string'
--
необходимо пропустить метод разборки аргументов
и здесь код 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 code
end
Ответ 3
Вы пытались выйти из ,
с помощью \
?
Ответ 4
Евгений уже ответил, почему он не работает.
Но, возможно, вам может помочь следующее обходное решение:
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 (возможно, замена оболочки)
Ответ 5
Переменные задачи рейка не очень удобны вообще, вместо этого используют переменные среды:
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
Ответ 6
# rake -v 10.5
rake test_commas\['foo\,bar'\]
работает как шарм.
Ответ 7
Другим простым решением является использование другого разделителя в ваших аргументах.
Это довольно просто заменить на трубу | символ (или другой) вместо ваших аргументов, разделенных запятой. В этом случае 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]
Ответ 8
Мы можем преобразовать каждую строку в символ,
Как,
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'
Ответ 9
Для граблей версии 12.3.2,
rake test_commas["foo\,bar"]
работает хорошо