-
Notifications
You must be signed in to change notification settings - Fork 24
subcommand parser #41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
I was just looking to suggest something like this, after using the Crystal What do you think about the ability to make Here's the example from the Crystal website: verbose = false
salute = false
welcome = false
name = "World"
parser = OptionParser.new do |parser|
parser.banner = "Usage: example [subcommand] [arguments]"
parser.on("salute", "Salute a name") do
salute = true
parser.banner = "Usage: example salute [arguments]"
parser.on("-t NAME", "--to=NAME", "Specify the name to salute") { |_name| name = _name }
end
parser.on("welcome", "Print a greeting message") do # This UX is very symmetric with the rest
welcome = true
parser.banner = "Usage: example welcome" # Re-uses original parser in scope - which might affect visitor pattern of Ruby's optparse?
end
parser.on("-v", "--verbose", "Enabled verbose output") { verbose = true }
parser.on("-h", "--help", "Show this help") do
puts parser
exit
end
end
parser.parse
if salute
STDERR.puts "Saluting #{name}" if verbose
puts "Hello #{name}"
elsif welcome
STDERR.puts "Welcoming #{name}" if verbose
puts "Welcome!"
else
puts parser
exit(1)
end |
I think that it is NOT a good idea to support subcommand functionality in OptionParser. I strongly recommend for OptionParser to focus on its role as command option parsing. |
I released cliapp gem which is a small framework for CLI application similar to Git or Docker. Example code of cliapp (filename: #!/usr/bin/env ruby
require 'cliapp'
## create an application object
app = CLIApp.new("Sample", "Sample Application", version: "1.0.0")
app.global_options({
:help => ["-h", "--help" , "print help message"],
:version => [ "--version" , "print version number"],
:list => ["-l", "--list" , "list action names"],
})
## 'hello' action
app.action("hello", "greeting message", {
:lang => ["-l", "--lang=<en|fr|it>", "language", ["en", "it", "fr"]],
}) do |name="world", lang: "en"|
case lang
when "en" ; puts "Hello, #{name}!"
when "fr" ; puts "Bonjour, #{name}!"
when "it" ; puts "Chao, #{name}!"
else raise "** internal error: lang=#{lang.inspect}"
end
end
## main
begin
app.run(*ARGV)
exit 0
rescue OptionParser::ParseError, CLIApp::ActionError => exc
$stderr.puts "[ERROR] #{exc.message}"
exit 1
end Example output: $ chmod ./sample
$ ./sample hello # subcommand example
Hello, world!
$ ./sample hello --lang=fr # subcommand option example
Bonjour, world!
$ ./sample hello Alice --lang=fr # subcommand argument example
Bonjour, Alice! Again, I strongly recommend for OptionParser to focus on its role as command option parsing. |
No description provided.