commander-rb / commander Goto Github PK
View Code? Open in Web Editor NEWThe complete solution for Ruby command-line executables
License: MIT License
The complete solution for Ruby command-line executables
License: MIT License
From the README, it seems all command is predefined by command method, but I want to create a command dynamic.
Hi,
Is it possible to use this library with a custom Array instead of ARGV? I couldn't find any example of it and I can't figure out the code :/
Would it be possible to have --help show inline, like with many other CLI-tools, instead of it opening a man page?
From @pruan-rht on February 16, 2015 18:0
Sometime, it's useful to be able to access options that at set in the global_option() be accessible outside of the command block so that I can do initialization of codes that are global to all sub commands. For example
global_option('-p', '--plan_id PLAN_ID_OR_NAME', 'specify the plan name or plan id')
command :rename do |c|
...
c.action do |arg, options|
...
I want to check the option plan_id outside of the c.action block for the various commands that this global_option applies to
Copied from original issue: tj/commander#94
Maybe that's a dumb question, but firs of all take a look at this minimal working example:
#!/usr/bin/env ruby
module Minimal
require 'rubygems'
require 'commander/import'
class CLI
include Commander::Methods
def self.parse(args)
program :name, 'MWE'
program :version, '0.0.1'
program :description, 'Minimal Working Example'
command :hello do |c|
c.syntax = 'mwe hello'
c.description = 'Say hello to everyone'
c.option '--spanish', 'Say Hello in Spanish'
c.option '--french', 'Say Hello in French'
c.action do |args, options|
say options.default
options.default
end
end
end
end
end
module Minimal
class Working
def self.example(args)
option = CLI.parse args
if option.name = 'hello'
#=> How can I check if spanish of french option is true?
end
end
end
end
Minimal::Working.example ARGV
Well actually I'm trying to acces to options.default value outside the Commander space object, but I failed. What am I missing?
Thanks in advance
Commander gem shows DEPRECATION WARNING: MissingSourceFile is deprecated! Use LoadError instead.
warning when we use commander v4.4.0 with ActiveSupport v5+.
warning is thrown from /lib/commander/user_interaction.rb
while executing
module AskForClass
# All special cases in HighLine::Question#convert, except those that implement #parse
(
[Float, Integer, String, Symbol, Regexp, Array, File, Pathname] +
# All Classes that respond to #parse
Object.constants.map do |const|
# Ignore constants that trigger deprecation warnings
Object.const_get(const) unless [:Config, :TimeoutError].include?(const)
end.select do |const|
const.class == Class && const.respond_to?(:parse)
end
).each do |klass|
define_method "ask_for_#{klass.to_s.downcase}" do |prompt|
$terminal.ask(prompt, klass)
end
end
end
which defines the deprecation_message method for the ActiveSupport::Deprecation::Reporting module lib/active_support/deprecation/reporting.rb
while executing
def deprecation_message(callstack, message = nil)
message ||= "You are using deprecated behavior which will be removed from the next major or minor release."
"DEPRECATION WARNING: #{message} #{deprecation_caller_message(callstack)}"
end
could you please fix this issue.
Thanks for the great job.
I'm wondering if with this tool is possible to define two levels of commands. For example:
git remote add
git remote rm
Where git
is the name of the script, remote
is the 1st level of command and add
| rm
are the actual commands.
Thanks.
Hello!
Is there any solution to use command sequences in a short way? For example:
my_gem_based_on_commander cmd1 [some_args] && cmd2 [some_other_args]
instead of
my_gem_based_on_commander cmd1 [some_args] && my_gem_based_on_commander cmd2 [some_other_args]
Also is there any way to support command pipeline (passing results from one command to another like in macos's bash) ? For example:
my_gem_based_on_commander cmd1 [some_args] | cmd2 [some_other_args]
I'm using Commander 4.4.7. I am noticing that if I have an option that takes an argument, and the argument starts with a global option, the argument is parsed as a global option.
require 'commander/import'
program :name, 'Name'
program :version, '0.1'
program :description, 'Issue with argument parsing.'
default_command :mount
command :mount do |c|
c.option('--options=STRING', String) do |opts|
puts "Parsed mount options: #{opts}"
end
c.action do
puts 'Success'
end
end
When I run the program, it interprets -vers=3.0
as the global option -v
:
$ ruby test.rb --options "-vers=3.0"
Name 0.1
If I use =
to separate --options
from its argument, it works as expected:
$ ruby test.rb --options="-vers=3.0"
Parsed mount options: -vers=3.0
Success
So, we have a workaround, but I still argue that it's a bug. First, it's very common to omit the =
.
Second, it works in either case using optparse
directly. Here is an example:
require 'optparse'
OptionParser.new do |opts|
opts.banner = "Usage: example.rb [options]"
opts.on("-v", "--version", "Show version") do |v|
puts "-v received"
end
opts.on("-o OPTIONS", "--options OPTIONS", "Provide mount options") do |opts|
puts "-o received with #{opts}"
end
end.parse!
Observe that it works as expected in either case:
$ ruby test2.rb --options "-vers=3.0"
-o received with -vers=3.0
$ ruby test2.rb --options="-vers=3.0"
-o received with -vers=3.0
Options with arguments may not be properly removed before executing command.
Test program:
require 'commander/import'
program :name, 'Name'
program :version, '0.1'
program :description, 'Issue with Global Option parsing.'
default_command :cmd
global_option('--target=STRING', String, 'Specify a target.') do |s|
puts "Parsed Global Option: #{s}"
end
command :cmd do |c|
c.action do
puts 'Success'
end
end
Example:
$ ruby test.rb --target 1
Parsed Global Option: 1
Success
$ ruby test.rb --target=1
Parsed Global Option: 1
invalid option: --target=1
Here it is clear that the Global Option handler for --target
ran and received the expected argument 1
. However this global option was not consumed before invoking the sub-command, and produced invalid option. Doing the same thing without an =
sign works for both global option parsing and is removed before the sub-command.
Relevant code to look at is remove_global_option which I don't think correctly handles arguments that contains an =
. In this case arg
is --target=1
and the code tries to remove switches named --target
with direct comparisons, which of course fails.
Specifically this part looks fishy:
args.delete_if do |arg|
if switches.any? { |s| s[0, arg.length] == arg }
...
end
end
Or other global long option names.
runner.rb:340
is the culprit as it essentially does a starts_with
comparison.
As a test case, create an option named versionCode
, which when specified on the command line, gets deleted after remove_global_options
.
# to show failures to the user, use `exit` or `abort`
c.action do |args, options|
if args.size == 1
puts "noooo"
exit 1
end
abort "this is bad" if args.size == 2
end
From @suan on March 1, 2012 17:30
This just struck me as something very useful and practical to include as a feature. I'm only very vaguely familiar on how bash tab completion works, so I have no idea of the work it would involve. If its a significant effort though I might be willing to help - its something that I've always wanted in my scripts!
Copied from original issue: tj/commander#41
Imagine the following case:
I'm using aruba in my cucumber BDD tests, which by default is executing the commands in a child process.
That is slow and doesn't allow me to stub/mock components. So the alternative which they provide is called in_process
, which is not spawning a new process, it uses the current one .
With this approach you have to trigger your application, since my application is CLI app.
So in my case I have the following:
runner.rb
module Cli
module App
class Runner
def initialize(argv, stdin, stdout, stderr, kernel)
@argv = argv
@stdin = stdin
@stdout = stdout
@stderr = stderr
@kernel = kernel
end
def execute!
MyApp::Command.new.run
end
end
end
end
And my command.rb looks lik:
require 'commander'
module MyApp
class Command
include Commander::Methods
def run
program :name, 'myapp'
program :version, MyApp::VERSION
program :description, 'This tool handles the syncing from Bitbucket / GIT to your clearcase view.'
default_command :sync
global_option('-u', '--url STRING', 'Specifies the link to the third party site')
command :sync do |cmd|
cmd.syntax = 'sync [options]'
cmd.description = 'sync to third party'
cmd.action do |_args, options|
if !options.abort
fail 'The URL, the branch and the stream is mandatory' unless options.stream && options.url && options.branch
else
fail 'The stream is mandatory for an abort' unless options.stream
end
# Some code executed by my application
end
end
run!
end
end
end
And my cucumber step is:
I run myapp sync -u http://example.com
With that my sync command is called, but the options are missing, probably I have to inject them somehow
For example thor gem allows me to do something like that: MyCli::App.start(@argv)
in the runner and everything works
So my concern is: how can I inject the options with in my runner ?
There seems to be a problem when using '--[no-]blah' style flags as part of a global_option
. Specifically, the flag appears to not be accounted for during bookkeeping in remove_global_options
.
The following test program exhibits the problem:
#!/usr/bin/env ruby
require 'rubygems'
require 'commander'
class MyApplication
include Commander::Methods
def run
runner = Commander::Runner.instance
program :name, 'Foo Bar'
program :version, '1.0.0'
program :description, 'Stupid command that prints foo or bar.'
command :foo do |c|
c.syntax = 'foobar foo'
c.description = 'Displays foo'
c.when_called do |args, options|
puts 'Command goes foo'
puts 'Wow!' if $exclaim
end
end
global_option('-e', '--[no-]exclaim', 'Whether not to exclaim') do |val|
$exclaim = val
puts "$exclaim is: #{$exclaim}"
end
runner.parse_global_options
puts "ARGV before global options removed: #{ARGV}"
runner.remove_global_options(runner.options, ARGV)
puts "ARGV after global options removed: #{ARGV}"
run!
end
end
MyApplication.new.run if $0 == __FILE__
When run with ./commander_example.rb foo --exclaim
, the result is:
$exclaim is: true
ARGV before global options removed: ["foo", "--exclaim"]
ARGV after global options removed: ["foo", "--exclaim"]
$exclaim is: true
invalid option: --exclaim
When run with ./commander_example.rb foo --no-exclaim
the result is:
$exclaim is: false
ARGV before global options removed: ["foo", "--no-exclaim"]
ARGV after global options removed: ["foo", "--no-exclaim"]
$exclaim is: false
invalid option: --no-exclaim
When run with ./commander_example.rb foo -e
the result is:
$exclaim is: true
ARGV before global options removed: ["foo", "-e"]
ARGV after global options removed: ["foo"]
Command goes foo
Wow!
edit: Corrected the bug description, my test program, produced output, and provided one more example
magic
-s silent
-t trace
$ magic -st
Double dash as described in tj/commander#34, seems to be broken after 4.4.0, specifically after 420ffa9.
The mentioned example yields -x
as an option rather than argument, when used in conjunction with double dash.
Additionally, it fails to parse EG. ruby test.rb foo -- --foo
.
It would be great if commander would provide a helper to unintend a String created with a heredoc. Some seem to solve this "elegantly" via a core_ext to String:
class String
def unindent
gsub(/^#{scan(/^\s*/).min_by{|l|l.length}}/, "")
end
end
command :test do
message = <<-EOM.unindent
This is a test message! The left indent
gets stripped automatically!
EOM
end
From @smackesey on October 16, 2014 15:43
Is there any way to do some processing (add to options object, set instance variables and so on) after all options have been parsed but before any command has been run? If not, this would be a useful feature (I'd be willing to implement it in a PR)-- if it exists, then I think it should be mentioned in the README.
Copied from original issue: tj/commander#81
When using both, your gem and the pg gem (for PostgreSQL) in a project, I get a deprecation warning from pg as they have deprecated some of their constants. To get the deprecation warning when using the old constants, pg moved them in a special file (
https://bitbucket.org/ged/ruby-pg/src/master/lib/pg/deprecated_constants.rb) that is not needed normaly. But as you are walking through all constants (https://github.com/commander-rb/commander/blob/master/lib/commander/user_interaction.rb#L334), also the deprecated constants are accessed.
Maybe you could add them to your deprecation list.
When trying to add a "debug" alias to a previously defined command, I can't pass the --trace
flag to it, even though I could manually append --trace
when running the command from CLI manually.
e.g.:
command :run do |c|
c.syntax = "foobar run"
c.example 'foobar run --thing path/to/thing --other-thing 12345'
c.option '--thing STRING', String
c.option '--other-thing STRING', String
c.action do |_args, options|
# do stuff here
end
end
alias_command :debug, :run, '--thing', 'foo', '--other-thing', '67890', '--trace'
when running debug
:
$ foobar debug
invalid option: --trace
amusingly, if I apply --trace to debug
:
$ foobar debug
Traceback (most recent call last):
5: from /Users/me/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/commander-4.4.4/lib/commander/import.rb:5:in `block in <top (required)>'
4: from /Users/me/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/commander-4.4.4/lib/commander/delegates.rb:15:in `run!'
3: from /Users/me/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/commander-4.4.4/lib/commander/runner.rb:68:in `run!'
2: from /Users/me/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/commander-4.4.4/lib/commander/runner.rb:444:in `run_active_command'
1: from /Users/me/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/commander-4.4.4/lib/commander/command.rb:153:in `run'
/Users/me/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/commander-4.4.4/lib/commander/command.rb:164:in `parse_options_and_call_procs': invalid option: --trace (OptionParser::InvalidOption)
It'd be great if I could hardcode always providing traceback for a specific alias, but not show the traceback by default. Is there an easy way to do this that I'm missing?
Hi, sometimes it's preferable to disable -h
option and have only --help
. This for example when hostname is to be specified. Please make -h
option configurable. --help
is fine, there can be no confusion.
I have been using bundler, rake, and geminabox to build and distribute my gems locally. When I build a classic-style app via the above everything works as expected. Not so with the modular-style. Using 'bundle exec' works. Using 'rake install' does not. My app basically never runs. I traced using this snippet at the end of my app:
puts "Running #{$PROGRAM_NAME}"
puts "#{__FILE__}"
puts $PROGRAM_NAME == __FILE__
MyApplication.new.run #if $PROGRAM_NAME == __FILE__
Running 'bundle exec exe/modapp':
Running exe/modapp
exe/modapp
true
Running 'modapp [option]' after 'rake install' or 'gem install':
Running /home/lewisb/.rvm/gems/ruby-2.2.4/bin/modapp
/home/lewisb/Projects/commander_projects/modapp/exe/modapp
false
Is this expected behavior or am I missing something incredibly basic? I have been using mixins to organize my apps.
Thanks for any insights.
From @deric on October 21, 2013 13:44
Is it possible to specify an option which will be required in order to run command?
Copied from original issue: tj/commander#62
Ruby 2.2.3 does not give this error so my guess is that 2.3.0 isn't supported yet. Is this something that can be resolved as an issue?
.rvm/gems/ruby-2.3.0/gems/commander-4.3.5/lib/commander/user_interaction.rb:334: warning: constant ::TimeoutError is deprecated
Thanks for your help.
Lewis
Seeing the following:
/usr/local/lib/ruby/gems/2.5.0/gems/commander-4.4.3/lib/commander/user_interaction.rb:334: warning: constant ::Data is deprecated
When running with ruby 2.5.0 on Mac OS High Sierra. Let me know if any other info is necessary and I'll provide it.
From @d-ash on February 14, 2015 8:40
Passing only a beginning of a name triggers the option to be set.
For example, if --vagrant option is declared, passing --v or --va... to the script, works as if the full name has been passed.
However, global options work correctly (--v is not equivalent to --vagrant)
Copied from original issue: tj/commander#93
I have a command with a required option. How can I display the help page to the user if this option is not set?:
command :test do |c|
c.syntax = 'Test command'
c.description = 'Test command'
c.option '--prefix STRING', String, 'Adds a prefix to test'
c.action do |args, options|
raise ArgumentError.new("Prefix is required!") unless options.prefix
testMeth
end
end
Is it possible to heve 'commander init' generate a modular-style stub? If not now, may I submit this as a new feature request?
Thank you for the great dsl.
Lewis
From @kodybrown on March 11, 2014 17:0
The following statement fails; user_interaction.rb line #240:
find {|name| system("hash #{name.split.first} 2>&-") }
I changed it to this, which now works:
find {|name| system("hash #{name.split.first} 2>&1") }
But, now I don't know where to find hash
.. Is this a bash util or built-in lib somewhere? I tried gem install hash
but it does not seem to be what it is looking for..
I'm running bro (on Windows) which uses commander..
Copied from original issue: tj/commander#69
From @GabeMc on October 22, 2010 18:2
You hard code the text strings for the default global options. It is often necessary to manually reset those, to support things like internationalization.
Copied from original issue: tj/commander#23
From @jszwedko on March 2, 2015 19:26
It would be nice if this was instead based on the length of the longest command or was configurable.
https://github.com/tj/commander/blob/master/lib/commander/help_formatters/terminal/help.erb#L12
Copied from original issue: tj/commander#98
I have specified small switches, so they would show in help and so I have "power" over them. But when I try to use myscript run -t alfa
, the type doesnt set. It works for -i
and -m
just fine. But with type I need to write --type
#!/usr/bin/env ruby
require 'rubygems'
require 'commander/import'
program :name, 'MyScript'
program :version, '0.1.0'
program :description, "Script execution"
command :run do |c|
c.syntax = 'test_runner run [options]'
c.description = 'Run test script or a set of test scripts'
c.option('-t STRING', '--type STRING', String, 'Type')
c.option('-i STRING', '--input STRING', String, 'Path')
c.option('-m STRING', '--max_depth STRING', String, 'Maximal depth')
c.action do |args, options|
options.default max_depth: '0'
say "Params are: #{options.type}, #{options.input}, #{options.max_depth}"
end
end
c.option('-t', '--type STRING', String
Does not work either.
The change from ffc4e0d included in 4.3.6 triggers a warning on Ruby 2.1.5p273 (Debian Jessie). Reversing the change, fixes the warning:
/var/lib/gems/2.1.0/gems/commander-4.3.7/lib/commander/user_interaction.rb:333:in
const_get': Use RbConfig instead of obsolete and deprecated Config.`
Greets,
I may be completely abusing this library but I figured out I could reuse the command parsing functionality in a shell loop. Only one problem: when Commander::Command#call
is called, it empties the array where the code is kept. The net effect is that you can only #run
it once.
I don't know enough about this package to know if it would mess anything else up to make these objects effectively immutable, but even something like this:
def call(args = [])
object, meth = @when_called[0,2]
meth ||= :call
options = proxy_option_struct
case object
when Proc then object.call(args, options)
when Class then meth != :call ? object.new.send(meth, args, options) : object.new(args, options)
else object.send(meth, args, options) if object
end
end
…would be non-destructive. Then there is the matter of @proxy_options
being continually appended to via #option_proc
, so it would have to be emptied after each #run
, perhaps like this:
def proxy_option_struct!
out = proxy_option_struct
@proxy_options = []
out
end
…and then just change that one line in #call
. This is me just eyeballing it, so I have no idea if any of this would work/not break anything elsewhere. I can fork and PR this if there are no surprises.
Thanks,
If I use default_command
, any time someone runs an unknown command, Commander executes the default command. Is there any way to make Commander operate similar to bundler, and have it throw an error in this situation? I only want it run the default command when no sub command is specified.
$ bundle unknown_command
Could not find command "unknown_command".
$ bundle
Fetching gem metadata from https://rubygems.org/........
With the most recent version, the help formatter is broken, resulting the following stack trace:
./bin/fastlane --help
(erb):2:in `get_binding': undefined method `size' for nil:NilClass (NoMethodError)
from /Users/felixkrause/.rvm/rubies/ruby-2.0.0-p481/lib/ruby/2.0.0/erb.rb:849:in `eval'
from /Users/felixkrause/.rvm/rubies/ruby-2.0.0-p481/lib/ruby/2.0.0/erb.rb:849:in `result'
from /Users/felixkrause/.rvm/gems/ruby-2.0.0-p481@global/gems/commander-4.3.3/lib/commander/help_formatters/terminal.rb:7:in `render'
from /Users/felixkrause/.rvm/gems/ruby-2.0.0-p481@global/gems/commander-4.3.3/lib/commander/runner.rb:302:in `block (2 levels) in create_default_commands'
from /Users/felixkrause/.rvm/gems/ruby-2.0.0-p481@global/gems/commander-4.3.3/lib/commander/command.rb:178:in `call'
from /Users/felixkrause/.rvm/gems/ruby-2.0.0-p481@global/gems/commander-4.3.3/lib/commander/command.rb:178:in `call'
from /Users/felixkrause/.rvm/gems/ruby-2.0.0-p481@global/gems/commander-4.3.3/lib/commander/command.rb:153:in `run'
from /Users/felixkrause/.rvm/gems/ruby-2.0.0-p481@global/gems/commander-4.3.3/lib/commander/runner.rb:57:in `block in run!'
from /Users/felixkrause/.rvm/gems/ruby-2.0.0-p481@global/gems/commander-4.3.3/lib/commander/runner.rb:382:in `block in global_option_proc'
from /Users/felixkrause/.rvm/rubies/ruby-2.0.0-p481/lib/ruby/2.0.0/optparse.rb:1364:in `call'
from /Users/felixkrause/.rvm/rubies/ruby-2.0.0-p481/lib/ruby/2.0.0/optparse.rb:1364:in `block in parse_in_order'
from /Users/felixkrause/.rvm/rubies/ruby-2.0.0-p481/lib/ruby/2.0.0/optparse.rb:1351:in `catch'
from /Users/felixkrause/.rvm/rubies/ruby-2.0.0-p481/lib/ruby/2.0.0/optparse.rb:1351:in `parse_in_order'
from /Users/felixkrause/.rvm/rubies/ruby-2.0.0-p481/lib/ruby/2.0.0/optparse.rb:1345:in `order!'
from /Users/felixkrause/.rvm/rubies/ruby-2.0.0-p481/lib/ruby/2.0.0/optparse.rb:1437:in `permute!'
from /Users/felixkrause/.rvm/rubies/ruby-2.0.0-p481/lib/ruby/2.0.0/optparse.rb:1459:in `parse!'
from /Users/felixkrause/.rvm/gems/ruby-2.0.0-p481@global/gems/commander-4.3.3/lib/commander/runner.rb:363:in `parse_global_options'
from /Users/felixkrause/.rvm/gems/ruby-2.0.0-p481@global/gems/commander-4.3.3/lib/commander/runner.rb:65:in `run!'
from /Users/felixkrause/.rvm/gems/ruby-2.0.0-p481@global/gems/commander-4.3.3/lib/commander/delegates.rb:15:in `run!'
from ./bin/fastlane:118:in `run'
from ./bin/fastlane:124:in `<main>'
This can be reproduced using the fastlane gem. When I remove the help formatter specification it's working just fine.
I have been playing around with the command aliasing feature and would like to take a crack at adding to the documentation. From what I can see this isn't a true sub-command structure but the potential for organizing commands with it is awesome.
This is what a sample help screen looks like:
bundle exec projman help
...
Commands:
help ...
Aliases:
project list project list
project new project new
project show project show
task add task add
task delete task delete
task update task update
I appreciate any advice you have on this matter.
Thank you.
I'm building an application that will ultimately call another script. I would like to have a way to delineate between the commands proper args and options versus whats after the --
doh command --option --name bob -- --pass
How can I get everything after the --
using commander, or do I need to inspect the $*
on my own.
I often find mysql wanting to put --help
on the end of a command to see the help text for that command. With commander, if I do that though, I first have to remove any --option options passed or I get 'command not found'
Example:
#!/usr/bin/env ruby
require 'rubygems'
require 'commander'
class MyApplication
include Commander::Methods
# include whatever modules you need
def run
program :name, 'test'
program :version, '0.0.1'
program :description, 'test'
command :bob do |c|
c.syntax = 'test bob [options]'
c.summary = ''
c.description = ''
c.example 'description', 'command example'
c.option '--some-switch', 'Some switch that does something'
c.action do |args, options|
# Do something or c.when_called Test::Commands::Bob
end
end
run!
end
end
MyApplication.new.run if $0 == __FILE__
Results in:
➜ ruby yourfile.rb --some-switch --help
invalid command. Use --help for more information
Is there any way to make this possible?
Does this even make sense?:
I'm building a simple Sinatra application builder with Commander. On my option to build with the inline method, I want to choose between Slim or Erb. It would go something like this:
$ sincab init --inline -s myapp
or
$ sincab init --inline -e myapp
Those two flags would only belong to the --inline option.
Thanks for any thoughts on this.
The features mention the use of multi-word commands / subcommands, but it's not immediately clear to those new to Ruby as to how that would be done.
Would it be possible to update the documentation to reflect subcommand examples?
Thank you in advance!
At https://github.com/commander-rb/commander#global-options, it says:
All global options regardless of providing a block are accessable at the command level. This
means that instead of the following:
global_option('--verbose') { $verbose = true }
...
c.action do |args, options|
say 'foo' if $verbose
...
You may:
global_option '--verbose'
...
c.action do |args, options|
say 'foo' if options.verbose
...
but I have been unable to get this to work.
I have:
global_option('-s', '--server SERVER', 'Host name or IP address') do |server|
$server = server
end
...
command :repo_package_query do |c|
c.syntax = 'aptly-cli repo_package_query [options]'
c.summary = 'List all packages in local repository or perform search on repository contents and return result., requires --name'
c.description = 'List all packages or search on repo contents, requires --name'
c.example 'description', 'aptly-cli repo_package_query --name megatronsoftware -query geoipupdate'
c.option '--name NAME', String, 'Local repository name, required'
c.option '--query QUERY', String, 'Package to query'
c.option '--with_deps', 'Return results with dependencies'
c.option '--format FORMAT', String, 'Format type to return, compact by default. "details" is an option'
c.action do |args, options|
require 'pry'; binding.pry
...
end
And then I do this:
$ aptly-cli --server 10.3.0.46 repo_package_query --name develop --query 'Name (~ anonweb)'
From: /usr/local/lib/ruby/gems/2.3.0/gems/aptly_cli-0.2.9/bin/aptly-cli @ line 158 :
153: c.option '--query QUERY', String, 'Package to query'
154: c.option '--with_deps', 'Return results with dependencies'
155: c.option '--format FORMAT', String, 'Format type to return, compact by default. "details" is an option'
156: c.action do |args, options|
157: require 'pry'; binding.pry
=> 158: config = AptlyCli::AptlyLoad.new.configure_with($config_file)
159: aptly_command = AptlyCli::AptlyRepo.new(config)
160: if options.query
161: repo_options = { :name => options.name.to_s, :query => options.query.to_s }
162: elsif options.with_deps and options.query.nil?
163: repo_options = { :name => options.name.to_s, :with_deps => options.with_deps.to_s }
[1] pry(main)> options
=> <Commander::Command::Options name="develop", query="Name (~ anonweb)">
[2] pry(main)> $server
=> "10.3.0.46"
[3] pry(main)> options.server
=> nil
Note that $server
is set, but options.server
is not set. Shouldn't it be? Or am I misunderstanding how it works?
Same behavior if I simply do:
global_option '--server SERVER'
and it also occurs with commands that don't take options of their own:
command :repo_list do |c|
c.syntax = 'aptly-cli repo_list [options]'
c.summary = 'Show list of currently available local repositories'
c.description = 'Show list of currently available local repositories'
c.example 'description', 'aptly-cli repo_list'
c.action do |args, options|
require 'pry'; binding.pry
...
end
Running it:
$ aptly-cli --server 10.3.0.46 repo_list
From: /usr/local/lib/ruby/gems/2.3.0/gems/aptly_cli-0.2.9/bin/aptly-cli @ line 141 :
136: c.summary = 'Show list of currently available local repositories'
137: c.description = 'Show list of currently available local repositories'
138: c.example 'description', 'aptly-cli repo_list'
139: c.action do |args, options|
140: require 'pry'; binding.pry
=> 141: config = AptlyCli::AptlyLoad.new.configure_with($config_file)
142: aptly_command = AptlyCli::AptlyRepo.new(config, options)
143: puts aptly_command.repo_list()
144: end
145: end
146:
[1] pry(main)> options
=> <Commander::Command::Options >
[2] pry(main)> $server
=> "10.3.0.46"
[3] pry(main)> options.server
=> nil
$ gem list commander
*** LOCAL GEMS ***
commander (4.4.0)
$ ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin14]
Global options are ignored when additional command line arguments are also provided.
Using the test harness below, I get the following results.
In this scenario without extra arguments provided, the command correctly uses the provided global option value.
./command.rb experiment --config config-value
args: []
config: "config-value"
However with arguments provided after the configuration value, the command incorrectly falls back to the default value.
./command.rb experiment --config config-value arg1 arg2
args: ["arg1", "arg2"]
config: "default"
Similarly with arguments provided before the configuration value, the command incorrectly falls back to the default value.
./command.rb experiment arg1 arg2 --config config-value
args: ["arg1", "arg2"]
config: "default"
command.rb
test harness#!/usr/bin/env ruby
require 'rubygems'
require 'commander'
class MyApplication
include Commander::Methods
def run
program :name, 'Example with global option'
program :description, 'Example with global option'
program :version, '1.0.0'
global_option '-c', '--config CONFIG', String, 'A global option'
command :experiment do |c|
c.action do |args, options|
options.default {config: 'default'}
say "args: #{args.inspect}"
say "config: #{options.config.inspect}"
end
end
run!
end
end
MyApplication.new.run if $0 == __FILE__
In v4.4.4 and before, i could access Commander::Runner.instance&.active_command&.proxy_option_struct
from within my library code called by a command, and get access to the options that were handed to the actively running command.
v4.4.5 seems to have broken that functionality. Is there an alternative way that I should use instead?
I would like to run a command that works like this:
command --foo true --bar true
but look like this:
command --foo --bar
Is this possible?
The -v
and --version
default global options prevent me from defining my own -v
and --version
parameters to commands. (As the tool I'm writing deals with versions, this is a bummer.)
Is it really impossible to prevent Commander from adding these defaults, or have I missed something? In the former case, I'll be happy to submit a patch.
Commander is really great, thanks!
Given a sample program:
require 'commander/import'
program :name, 'Name'
program :version, '0.1'
program :description, 'Issue with Global Option parsing.'
command :cmd do |c|
c.action do
puts 'Success'
end
end
Previously you could use the global --help
anywhere on the line but now you can't. This used to provide the help for cmd
, but no longer does:
$ ruby foo.rb cmd a --help
invalid command. Use --help for more information
Seems like a recent regression.
Ruby 2.4 throws deprecation errors when running Commander:
/2.4.0/gems/commander-4.4.2/lib/commander/user_interaction.rb:333: warning: constant ::NIL is deprecated
/2.4.0/gems/commander-4.4.2/lib/commander/user_interaction.rb:333: warning: constant ::TRUE is deprecated
/2.4.0/gems/commander-4.4.2/lib/commander/user_interaction.rb:333: warning: constant ::FALSE is deprecated
/2.4.0/gems/commander-4.4.2/lib/commander/user_interaction.rb:333: warning: constant ::Fixnum is deprecated
/2.4.0/gems/commander-4.4.2/lib/commander/user_interaction.rb:333: warning: constant ::Bignum is deprecated
The relevant parts of the docs are here:
https://ruby-doc.org/core-2.4.0/Object.html
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.