Как разбирать аргументы rake с помощью OptionParser

Повторяя этот ответ Я пытался использовать OptionParser для анализа rake аргументов. Я упростил пример оттуда, и мне пришлось добавить два ARGV.shift, чтобы он заработал.

require 'optparse'

namespace :user do |args|

  # Fix I hate to have here
  puts "ARGV: #{ARGV}"
  ARGV.shift
  ARGV.shift
  puts "ARGV: #{ARGV}"

  desc 'Creates user account with given credentials: rake user:create'
  # environment is required to have access to Rails models
  task :create => :environment do
    options = {}
    OptionParser.new(args) do |opts|      
      opts.banner = "Usage: rake user:create [options]"
      opts.on("-u", "--user {username}","Username") { |user| options[:user] = user }
    end.parse!

    puts "user: #{options[:user]}"

    exit 0
  end
end

Это результат:

$ rake user:create -- -u foo
ARGV: ["user:create", "--", "-u", "foo"]
ARGV: ["-u", "foo"]
user: foo

Я полагаю, ARGV.shift - это не то, что нужно делать. Хотелось бы узнать, почему без него не работает и как правильно исправить.


person pawel7318    schedule 23.01.2015    source источник
comment
есть ли способ избежать использования exit(0) и rake без выброса "Don't know how to build task 'foo'" при попытке с rake user:create -- -u foo? что, если вы не хотите, чтобы rake останавливался на достигнутом? OptionParser#parse не позволяет использовать _7 _...   -  person rellampec    schedule 18.01.2020


Ответы (4)


Вы можете использовать метод OptionParser#order!, который возвращает ARGV без неверных аргументов:

options = {}

o = OptionParser.new

o.banner = "Usage: rake user:create [options]"
o.on("-u NAME", "--user NAME") { |username|
  options[:user] = username
}
args = o.order!(ARGV) {}
o.parse!(args)
puts "user: #{options[:user]}"

Вы можете передавать такие аргументы: $ rake foo:bar -- '--user=john'

person reguilon    schedule 23.01.2015

Я знаю, что это не совсем ответ на ваш вопрос, но рассматривали ли вы возможность использования аргументов задачи?

Это избавит вас от необходимости возиться с OptionParser и ARGV:

namespace :user do |args|
  desc 'Creates user account with given credentials: rake user:create'
  task :create, [:username] => :environment do |t, args|
    # when called with rake user:create[foo],
    # args is now {username: 'foo'} and you can access it with args[:username]
  end
end

Для получения дополнительной информации см. этот ответ здесь, на SO.

person awendt    schedule 23.01.2015

Попробуй это:

require 'optparse'

namespace :programs do |args|
  desc "Download whatever"
  task :download => [:environment] do

    # USAGE: rake programs:download -- rm
    #-- Setting options $ rake programs:download -- --rm
    options = {}
    option_parser = OptionParser.new
    option_parser.banner = "Usage: rake programs:download -- rm"
    option_parser.on("-r", "--rm","Remove s3 files downloaded") do |value|
      options[:remove] = value
    end
    args = option_parser.order!(ARGV) {}
    option_parser.parse!(args)
    #-- end

    # your code here
  end
end
person Alther Alves    schedule 20.04.2016
comment
Добро пожаловать в Stack Overflow. Пожалуйста, проверьте Как ответить, чтобы узнать, как дать наилучшие ответы. Например, было бы полезно, если бы вы показали наиболее релевантный код в своем ответе и некоторый контекст для ссылок на случай, если они будут недоступны, когда будущие пользователи придут с аналогичными вопросами. - person Kateract; 20.04.2016

Вы должны поставить знак "=" между -u и foo:

$ rake user:create -- -u=foo

Вместо:

$ rake user:create -- -u foo

person reguilon    schedule 23.01.2015
comment
С ARGV.shift он работает с = или без него. К сожалению, без ARGV.shift он не работает, когда я использую = или нет. - person pawel7318; 23.01.2015
comment
Вопрос в том, как разбирать общие аргументы в Rake, а не как передавать аргументы в Rake. - person Xiao Hanyu; 20.03.2016