pawel7318 pawel7318 - 7 months ago 12
Ruby Question

How to parse rake arguments with OptionParser

Reffering that answer I was trying to use

OptionParser
to parse
rake
arguments. I simplified example from there and I had to add two
ARGV.shift
to make it work.

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


This is the output:

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


I assume
ARGV.shift
is not the way it should be done. I would like to know why it doesn't work without it and how to fix it in a proper way.

Answer

You can use the method OptionParser#order! which returns ARGV without the wrong arguments:

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

You can pass args like that: $ rake foo:bar -- '--user=john'

Comments