0

Given the dummy rake task below

require "optparse" namespace :a do namespace :b do task c: :environment do options = {} OptionParser.new do |parser| parser.banner = "" parser.on("-v", "--verbose", "Run verbosely") do |v| options[:verbose] = v end end.parse! puts "options: #{options}" end end end 

How should I call it?

From my understanding, the way should be bin/rails a:b:c -v 3 or bin/rails a:b:c -- -v 3

But both ways generate:

Unrecognized command "3" (Rails::Command::UnrecognizedCommandError)

What am I missing here?

I'm running the task on a Mac.

UPDATE 1

a@mac appa % bundle exec rake a:b:c -- -v 3 options: {} rake aborted! Don't know how to build task '3' (See the list of available tasks with `rake --tasks`) /Users/sa/.rbenv/versions/3.3.7/bin/bundle:25:in `load' /Users/sa/.rbenv/versions/3.3.7/bin/bundle:25:in `<main>' (See full trace by running task with --trace) 
2
  • Never used OptionParser in Rake tasks within Rails, maybe bin/rails is already interpreting the options? It might be easier to create a Thor task though which provides these kind of option passing out of the box. Commented Apr 24 at 10:49
  • This blog post is from 2023 but still seems pretty useful: Tips for writing Rails tasks with Thor instead of Rake Commented Apr 24 at 10:52

2 Answers 2

1

You can capture the arguments sent to a Rake task as a block variable.

It is unclear what you intended the 3 to do but it appears that the following works fine:

require "optparse" namespace :a do namespace :b do task c: :environment do |_,args| #_ is the task name options = {} OptionParser.new do |parser| parser.banner = "" parser.on("-v", "--verbose", "Run verbosely") do |v| options[:verbose] = v end parser.on("-n", "--number [NUM]",Integer, "Some Number") do |n| options[:number] = n end end.parse!(args.to_a) #pass the collected arguments to OptionParser#parse! puts "options: #{options}" end end end 

Called as

bundle exec rake a:b:c[--verbose,-n3] #=> options: {:verbose=>true, :number=>3} bin/rails a:b:c[-v,--number,7] #=> options: {:verbose=>true, :number=>7} bin/rails a:b:c[-v,3] #=> options: {:verbose=>true} 

As an aside if every option just needs to be converted into a Hash you can use:

require "optparse" namespace :a do namespace :b do task c: :environment do |_,args| #_ is the task name options = {} OptionParser.new do |parser| parser.banner = "" parser.on("-v", "--verbose", "Run verbosely") parser.on("-n", "--number [NUM]",Integer, "Some Number") end.parse!(args.to_a, into: options) puts "options: #{options}" end end end 
Sign up to request clarification or add additional context in comments.

Comments

-1

How to call a Rake task with OptionParser

# lib/tasks/test_optparse.rake require "optparse" namespace :a do namespace :b do task c: :environment do options = {} OptionParser.new do |parser| parser.banner = "Usage: rake a:b:c [options]" parser.on("-v", "--verbose", "Run verbosely") do |v| options[:verbose] = v end end.parse! puts "options: #{options.inspect}" end end end 

🧪 How to call it correctly

Use the rake command (not rails) and add -- before the options:

bundle exec rake a:b:c -- -v //OR rake a:b:c -- -v 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.