Coder Social home page Coder Social logo

cri's People

Contributors

bastelfreak avatar bmesuere avatar boutil avatar denisdefreyne avatar mackuba avatar marcandre avatar rodjek avatar rous avatar rrrene avatar vstone avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

cri's Issues

combined options where the last option has an argument fails

When you combine options, and the last option has an argument, the argument is ignored.

For example, I think the following code should run fine, but results in an error:

    def test_combined_options_with_argument
      input       = %w( foo -ab xxx bar )
      definitions = [
        { :long => 'aaa', :short => 'a', :argument => :forbidden },
        { :long => 'bbb', :short => 'b', :argument => :required },
      ]

      parser = Cri::OptionParser.parse(input, definitions)
      assert(parser.options[:aaa])
      assert_equal({ :bbb => 'xxx' },  parser.options)
      assert_equal(%w(foo bar), parser.arguments)
    end

error:

Cri::OptionParserTestCase#test_combined_options_with_argument:
Cri::OptionParser::OptionRequiresAnArgumentError: b
    /Users/bart/Code/ruby/cri/lib/cri/option_parser.rb:230:in `block in handle_dash_option'
    /Users/bart/Code/ruby/cri/lib/cri/option_parser.rb:223:in `each'
    /Users/bart/Code/ruby/cri/lib/cri/option_parser.rb:223:in `handle_dash_option'
    /Users/bart/Code/ruby/cri/lib/cri/option_parser.rb:173:in `run'
    /Users/bart/Code/ruby/cri/lib/cri/option_parser.rb:105:in `parse'
    /Users/bart/Code/ruby/cri/test/test_option_parser.rb:289:in `test_combined_options_with_argument'

2.15.8 breaks nanoc

When using 2.15.8+ with nanoc and a port is specifed, nanoc errors out:

$ bundle exec nanoc live -p 3005
#<Thread:0x00007fda5490b380@/Users/ash/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/guard-nanoc-2.1.6/lib/guard/../nanoc/cli/commands/live.rb:22 run> terminated with exception (report_on_exception is true):
/Users/ash/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/nanoc-4.11.5/lib/nanoc/cli/commands/view.rb:34:in `fetch': key not found: :host (KeyError)
	from /Users/ash/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/nanoc-4.11.5/lib/nanoc/cli/commands/view.rb:34:in `run'
	from /Users/ash/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/guard-nanoc-2.1.6/lib/guard/../nanoc/cli/commands/live.rb:26:in `block in run'

Captain! We’ve been hit!

KeyError: key not found: :host

  0. /Users/ash/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/nanoc-4.11.5/lib/nanoc/cli/commands/view.rb:34:in `fetch'
  1. /Users/ash/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/nanoc-4.11.5/lib/nanoc/cli/commands/view.rb:34:in `run'
  2. /Users/ash/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/guard-nanoc-2.1.6/lib/guard/../nanoc/cli/commands/live.rb:26:in `block in run'

A detailed crash log has been written to ./crash.log.

Looking into the problem, I created the following which takes the Cri defintions straight from https://github.com/nanoc/nanoc/blob/4.11.5/nanoc/lib/nanoc/cli/commands/view.rb#L3-L15

nanoc_example.rb

#!/usr/bin/env ruby

require 'cri'
require 'nanoc'
require 'nanoc/cli'

command = Cri::Command.define do
  summary 'start the web server that serves static files'
  description <<~EOS
    Start the static web server. Unless specified, the web server will run on port
    3000 and listen on all IP addresses. Running this static web server requires
    `adsf` (not `asdf`!).
  EOS

  required :H, :handler, 'specify the handler to use (webrick/mongrel/...)'
  required :o, :host,    'specify the host to listen on (default: 127.0.0.1)', default: '127.0.0.1'
  required :p, :port,    'specify the port to listen on (default: 3000)', transform: Nanoc::CLI::Transform::Port, default: 3000
  flag :L, :'live-reload', 'reload on changes'
  no_params

  run do |opts, args|
    p opts.fetch(:port)
  end
end

command.run(ARGV)

Gemfile

source "https://rubygems.org"

gem 'cri'
gem 'nanoc'

2.15.7

$ bundle exec ./nanoc_example.rb
3000

2.15.9

$ bundle exec ./nanoc_example.rb
bundler: failed to load command: ./nanoc_example.rb (./nanoc_example.rb)
KeyError: key not found: :port
  /private/tmp/nanoc_example.rb:22:in `fetch'
  /private/tmp/nanoc_example.rb:22:in `block (2 levels) in <top (required)>'
  /Users/ash/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/cri-2.15.9/lib/cri/command.rb:360:in `run_this'
  /Users/ash/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/cri-2.15.9/lib/cri/command.rb:296:in `run'
  /private/tmp/nanoc_example.rb:26:in `<top (required)>'

Edit: Updated to reflect issue is present since 2.15.8+ and final example was for 2.15.9.

Display help for sub-commands that require an argument?

Is it possible to make sub-commands accept -h even if the wrong number of arguments to it are provided? Right now I just get the wrong number of arguments, but -h/--help should be there to help them find out what arguments are needed I would think?

Make colors optional and/or configurable

The colours are nice but they tend to hurt my eyes after a while.

It would be nice to be able to theme/change the colours to my liking and/or disable them. Possibly by using a switch.

I tried working on this a little while, but I'm still getting used to ruby so I probably made a mess. Maybe I'll send a pull request later unless you have an elegant solution in mind.

Splitting commands up?

Trying to split my command up in to separate files with the sub-commands each in their own file. However, this seems to not work as you can't pass in root_cmd when you require (so you could do the add_command in each file) and if you set a variable in the sub-command file it won't exist in the root_cmd file...

So, is it possible to create classes instead, or am I missing something else obvious?

Invalid syntax in command.rb

/usr/local/share/gems/gems/r10k-2.6.0.dev/lib/r10k/cli.rb:9:in `command': /usr/local/share/gems/gems/cri-2.9.1/lib/cri/command.rb:46: syntax error, unexpected ')' (SyntaxError)

def initialize(is_error:)

Allow array of names for options

I'd like to have a --force option with no shorter version, but I can't figure out how to do it.

I've had the desire to have multiple long-form names for an option, as well.

Both of these might be addressed by being able to pass the option names as an array, and

short_form = options.find { |o| o.to_s.length == 1 }
long_forms = options - [ short_form ]

or something like that.

Thanks!

Command help output with supercommand is not consistent on Ruby 1.8

On Ruby 1.8.7, order for Hash#each_pair is not deterministic, which can lead to the order of options and options for #{supercommand} in the help output to intermittently switch. I found out about this at puppetlabs/r10k#26 (comment) . When building Cri::Command#help, each_pair which can cause the order to switch.

Ruby 1.9 has consistent hash ordering that's based on insertion so this only affects Ruby 1.8.7. If Ruby 1.8.7 is fully supported I would be very happy to fix this, although testing this could prove difficult because of the nondeterministic duplication of the issue.

example code in readme contains error?

command.run(ARGS) should be command.run(ARGV), no?

probot :: Projects/Personal/testing % ruby critest.rb
critest.rb:29:in `<main>': uninitialized constant ARGS (NameError)

Feature: Parameters with default value

Idea: allow parameters to be defined with a default value. For example:

param :host
param :port, transform: method(:Integer), default: 3000

For simplicity, allow parameters with a default value to only appear at the end. The following would therefore not be possible:

param :foo, default: 'xxx'
param :bar
param :foo
param :bar, default: 'xxx'
param :qux
param :abc, default: 'yyy'

I image that this restriction will be fine, because the CLI will become complicated to use otherwise anyway.

Allow splitting positional arguments by `--`

It would be super useful to be able to split positional arguments using a --. This is often used to disambiguate positional arguments, for example:

git checkout origin/master    # branch master on origin
git checkout -- origin/master # local file master in origin directory

In my case, I'd like to split arbitrary arguments:

mycommand foo bar -- baz -- qux

The ideal backwards-compatible way to implement this is probably to make the arguments list a subclass of Array, with an accessor for getting groups of arguments. In the above example:

mycommand.arguments
=> ['foo', 'bar', 'baz', 'qux']

mycommand.argument_groups
=> ['foo', 'bar'], ['baz'], ['qux']

Or something. I'm not 100% sold on the accessor name :)

[doc] name for @param missing

Hi!

This is really a minor issue, but I noticed a warning when building the doc:

[warn]: @param tag has unknown parameter name: The 
    in file `lib/cri/command.rb' near line 96

Indeed, line 93 of lib/cri/command.rb, the name for the @param is missing.

Cédric

Wrong empty argument group check

Since -- is used to separate argument groups and stop option parsing, using both at the same time can lead to conflicting requirements.

Imagine having rm -f -- -blah to delete the file “-blah”. The -- stops option parsing and starts a new argument group. Currently, cri only creates a new argument group if the previous one is not empty. So the argument groups in this case will be

[
  [ '-blah' ]
]

which is expected and good.

However, in the case of git checkout -- blah, the argument_groups will be

[
  [ 'blah' ]
]

and not, as expected,

[
  [],
  [ 'blah' ],
]

The latter is necessary, because there is no way to disambiguate the blah argument otherwise.

A solution would be to remove the empty argument group check.

CC @bobthecow

How to use '--' to signal arbitrary passthrough args/flags/options?

I have an involved command suite defined using x = Cri::Command.define and x..add_command().

One of the subcommands needs to be able to accept arbitrary arguments and options to be passed through to a shell script. Usually, this is done by using '--' to signal 'don't process the rest of this line.'

I can see getting access to the unprocessed bits using the #unprocessed_arguments_and_options attribute, but I can't figure out how to spot -- in order to stop the parser and leave the rest of the commandline accessible that way. Nor can i find any examples or documentation on how to do it.

The parse/processing is begun with root_command.run(ARGV)

Is the mechanism actually in there somewhere and I'm just too thick to find it?

Thans!

Feature: Varargs parameter definitions

Idea: support parameter definitions for more than one argument. For example:

param :host
param :port, transform: method(:Integer)
param :filenames, varargs: true

varargs: true defines the parameter as corresponding to zero or more arguments.

For the time being, allowing it only as the last defined parameter is probably fine.

Add docs badge to README

Hi Denis,

I tried to add the Inch Pages badge to your README, but unfortunately my AsciiDoc-fu is not strong enough.

I tried image::http://inch-pages.github.io/github/ddfreyne/cri.png, but that did not seem to render right. Would mind adding this one yourself?

The badge looks like this Inline docs (looking good!) and the URL of the Inch Page would be http://inch-pages.github.io/github/ddfreyne/cri/

Consider making it clearer that --verbose is an option for the help subcommand itself

When using the basic help command, the way the --verbose option is currently presented can be a bit confusing for users:

$ mycommand help new

<snip>

OPTIONS FOR NEW
    -d --debug                     Enable debug output.
    -h --help                      Show help for this command.
    -v --verbose                   show more detailed help
       --version                   Show version of mycommand.

It would be clearer if --verbose was listed in it's own section labelled OPTIONS FOR HELP or something similar:

$ mycommand help new

<snip>

OPTIONS FOR NEW
    -d --debug                     Enable debug output.
    -h --help                      Show help for this command.

OPTIONS FOR HELP
    -v --verbose                   show more detailed help

Allow the use of single newlines in help output

Due to the text reflow in the help output, single newlines are ignored, double newlines are used to indicate the start of a new paragraph and paragraphs are joined with a double newline. This means it's not possible to use a line break in the description without introducing an empty line. When using lists, this results in ugly output:

This command has 3 features:

- awesome feature 1

- awesome feature 2

- awesome feature 3

We also have a lot of options.

preferred output:

This command has 3 features:
- awesome feature 1
- awesome feature 2
- awesome feature 3

We also have a lot of options.

Subcommand where the root command has an option

Is it possible to implement something like command --option subcommand --another-option?

There is an option in my design that is "common" to all subcommands, for me it makes sense to be passed to the root command instead of repeating its definition in all subcommand blocks. For sure I could use a helper, but the pattern I am proposing looks better to me. Thanks in advance.

Options propagation on subcommand tree

Having this command and subcommand configuration:

base_cmd = Cri::Command.define do
  name        'base_cmd'
  usage       'base_cmd [options]'
  summary     'does stuff'
  description 'This command does a lot of stuff. I really mean a lot.'
  flag   :a, :aaaa,  'do even more stuff'
end

level1_cmd = Cri::Command.define do
  name        'level1_cmd'
  usage       'level1_cmd [options]'
  summary     'does stuff'
  description 'This command does a lot of stuff. I really mean a lot.'
end

level2_cmd = Cri::Command.define do
  name        'level2_cmd'
  usage       'level2_cmd [options]'
  summary     'does stuff'
  description 'This command does a lot of stuff. I really mean a lot.'
  run do |opts, args, cmd|
    puts opts.to_s
  end
end

level1_cmd.add_command(level2_cmd)
base_cmd.add_command(level1_cmd)
base_cmd.run(ARGV)

Note that there is a flag a configured on the base command base_cmd and lowest level subcommand prints in stdout available opts

I find this behavior unexpected:

$ base_cmd -a level1_cmd level2_cmd
{}
$ base_cmd level1_cmd -a level2_cmd
{:aaaa=>true}
$ base_cmd level1_cmd level2_cmd -a
{:aaaa=>true}

Is this the expected behavior?

Move defaults to declaration

Please add a way to specify the default value for an option in a way that gets exposed to --help, e.g.:

optional nil, :source, 'The source repository to load templates from.', default: '[email protected]:puppetlabs/modulesync_configs.git'
options:

    -h --help      show help for this command
       --summary   The source repository to load templates from.
                   Default value: [email protected]:puppetlabs/modulesync_configs.git

instead of

optional nil, :source, 'The source repository to load templates from.'
run do |opts, args, cmd|
  source = opts.fetch(:source, '[email protected]:puppetlabs/modulesync_configs.git')

uninitialized constant Cri::Error

When running r10k puppetfile check, this library cast an exception
Version installed cri-2.13.0
Version working cri-2.12.0
r10k version installed 3.0.0

Traceback (most recent call last):
        13: from /usr/local/bin/r10k:23:in `<main>'
        12: from /usr/local/bin/r10k:23:in `load'
        11: from /var/lib/gems/2.5.0/gems/r10k-3.0.0/bin/r10k:3:in `<top (required)>'
        10: from /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'
         9: from /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'
         8: from /var/lib/gems/2.5.0/gems/r10k-3.0.0/lib/r10k/cli.rb:3:in `<top (required)>'
         7: from /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'
         6: from /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'
         5: from /var/lib/gems/2.5.0/gems/r10k-3.0.0/lib/r10k/cli/ext/logging.rb:1:in `<top (required)>'
         4: from /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'
         3: from /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'
         2: from /var/lib/gems/2.5.0/gems/cri-2.13.0/lib/cri/command_dsl.rb:3:in `<top (required)>'
         1: from /var/lib/gems/2.5.0/gems/cri-2.13.0/lib/cri/command_dsl.rb:6:in `<module:Cri>'
/var/lib/gems/2.5.0/gems/cri-2.13.0/lib/cri/command_dsl.rb:9:in `<class:CommandDSL>': uninitialized constant Cri::Error (NameError)
Did you mean?  IOError
               Errno

I am not sure if this is a r10k issue or cri issue.

Specify default command

In Nanoc, nanoc is a shorthand for nanoc compile. The behavior of nanoc differs slightly from nanoc compile, as options are not passed through, and Cri has no method of doing so.

Suggestion: Let Cri support default subcommand properly, e.g. through

default_subcommand :compile

Color output on windows

If the terminal doesn't support colored output, it should not be shown.

This is mostly a problem on Windows.

Prevent options from clashing

Cri should provide a way to ensure that long and short options don’t clash between subcommand and supercommand.

Quick question

Is there a way to exec the run block from a subcommand ? for instance

if I'm in a subcommand to do something like

run do |opts, args, cmd|
cmd.supercommand.run(opts)
end
thanks in advance for any help

Forbidden optional parameters set to ` nil` when not present in command line

Currently, forbidden optional parameters set to nil when not present in command line. From documentation, it is expected to return false

option :f, :force, 'push with force', argument: :forbidden

run do |opts, args, cmd|
  puts "Force? #{opts[:force].inspect}!"
end
% ./push
Force? nil!

% ./push --force
Force? true!

iterating over arguments fails since 2.12

Due to changes introduced in cri 2.12, my way of iterating over arguments no longer works. (This might very well be a bug in my code and not in cri).

My code extending the commandRunner:

    # Returns an input iterator to use for the request.
    # - if arguments are given, uses arguments
    # - if the input file option is given, uses file input
    # - if none of the previous are given, uses stdin
    def input_iterator
      return arguments.each unless arguments.empty?
      return IO.foreach(options[:input]) if options[:input]
      $stdin.each_line
    end

This now throws a LocalJumpError, probably because the array was swapped for an argument_list in the underlying code:

LocalJumpError: no block given (yield)
    /Users/bart/.rvm/gems/ruby-2.6.0/gems/cri-2.12.0/lib/cri/argument_list.rb:39:in `block in each'
    /Users/bart/.rvm/gems/ruby-2.6.0/gems/cri-2.12.0/lib/cri/argument_list.rb:39:in `each'
    /Users/bart/.rvm/gems/ruby-2.6.0/gems/cri-2.12.0/lib/cri/argument_list.rb:39:in `each'
    /Users/bart/Code/Rails/unipept-cli/lib/commands/unipept/api_runner.rb:41:in `input_iterator'
    /Users/bart/Code/Rails/unipept-cli/lib/commands/unipept/api_runner.rb:116:in `run'
    /Users/bart/.rvm/gems/ruby-2.6.0/gems/cri-2.12.0/lib/cri/command_runner.rb:34:in `call'
    /Users/bart/.rvm/gems/ruby-2.6.0/gems/cri-2.12.0/lib/cri/command_dsl.rb:257:in `block in runner'
    /Users/bart/.rvm/gems/ruby-2.6.0/gems/cri-2.12.0/lib/cri/command.rb:337:in `run_this'
    /Users/bart/.rvm/gems/ruby-2.6.0/gems/cri-2.12.0/lib/cri/command.rb:275:in `run'
    /Users/bart/.rvm/gems/ruby-2.6.0/gems/cri-2.12.0/lib/cri/command.rb:293:in `run'

Do you have a suggestion on how to resolve this?

`help --verbose` lists hidden commands at the bottom

The ordering of commands in nanoc help is not alphabetical. The hidden commands appear at the bottom:

    check              run issue checks
    compile            compile items of this site
[...]
    update             update the data stored by the data source to a newer version
    view               start the web server that serves static files
    autocompile        start the autocompiler
    validate-css       validate the site’s CSS
    validate-html      validate the site’s HTML
    validate-links     validate links in site
    watch              start the watcher

colored breaks awesome_print

Great gem! I've been using cri on a couple projects and it's been working great. A user reported a bug on my rspec_n gem (which uses cri) and stated rspec_n breaks awesome_print when both gems are listed in a Gemfile. I traced the issue back to the colored gem that cri uses and thought I would make sure you were aware (especially since awesome_print is such a popular gem).

colored adds colorize, green, red, etc... methods directly on String. awesome_print does the same thing. The gem that gets listed last in a Gemfile has their implementation loaded by Bundler. If colored is listed last, it breaks awesome_print.

Based on this comment in the awesome_print code, awesome_print seems to have compatibility with the colorize gem (an alternative to colored), but it doesn't seem to know about colored.

Is the argument: option required when using multiple: true

I'm trying to use multiple arguments and I have a option block that looks like this:

option :g, :groups, "specify the groups", argument: :required, multiple: true do |value, cmd|
  puts value
end

It works fine if argument: :required or argument: optional is present. If I remove that, value is just an array of true elements. Should argument: be present when using multiple: or is this a bug? I couldn't figure it out from the docs.

Make option requiredness more clear

From the option description, is it not clear whether an argument is required or not.

Actual:

    -f --format     define the output format

Expected:

    -f --format=[value]    define the output format

Allow `--help --verbose`

Currently, --help --verbose does not print the help verbosely, because both options are independent and do not know about each other.

Not sure how to solve this.

Cri::CommandRunner usage understanding

Is there some extended example/documentation how to use Cri::CommandRunner? I want to build a command in a class.
It clear it will call run. But where arguments coming from? How this class can be loaded/declared?

Thanks in advance.

Kirby

Version 2.15.7 causes runtime error

r10k: Runtime error: #<ArgumentError: R10K::Action::Puppetfile::Install cannot handle option 'help'>
Error while running: #<RuntimeError: r10k could not install all required modules>

FREQ: a #skip_subcommand_parsing method to allow options but arbitrary parameters

The #skip_option_parsing is good as far as it goes, but (IMHO) it addresses only half of the issue.

As far as I can tell, there is no way to define a command that will accept ab arbitrary number of arbitrary parameters without trying to treat them as subcommands. For examine, I don't see any way to do this:

configure set -v user=foo server=http://example.com/

because it gritches about user=foo not being a valid subcommand.

Is there a trick to this, or is it actually not currently supported?

Thanks!

Commands without `summary` does not even show command name

A simple command like this:

require 'cri'

c = Cri::Command.define do
  name 'test'
  #summary 'foo'

  run do |opts, args, cmd|
    puts cmd.help
  end
end

c.run(ARGV)

Will not output anything:

$ ruby wat.rb

Once I uncomment the summary call, then it starts showing. I understand that summaries are useful for the end-user, but it would be nice if it at least showed the command name (instead of a blank line).

Line wrapping for CRI help text?

Cri creates really nicely formatted help output. Since it already does indenting so nicely, is there currently any way to control line-wrapping, so options with long summaries don't go past, say, the 80th column, but are wrapped and indented instead? (Substitute 'a configurable' for '80th'.)

Thanks!

`--help --verbose` does not enable verbose mode

When passing both --help and --verbose, the --verbose option has no effect on the help output:

[..]
COMMANDS
[..]
    update            update the data stored by the data source to a newer version
    view              start the web server that serves static files
    (5 hidden commands ommitted; show them with --verbose)
[..]

Run block executes even if --help option is specified

Help flag takes a block and then we have a run block which executes the command. If the command has --help option specified, the help block executes and then the run block also executes. Ideally if help option is specified then run block should not execute.
Again, coming from my application which is using Cri in a command loop. I cannot exit in the help block and have no control in Cri to stop execution of run block. Currently Im checking the presence of help option inside run block and just return if it is present.

Add be_hidden variant for options

I'd like my application to be able to have an option set, without it being visible to regular users. A be_hidden variant as already exists for commands would be helpful here.

Pass an arbitrary set of parameters to command definition

I am trying to build a set of subcommands in a kind of modular way, something like:

class Whatever

    def initialize
      @root = self.class.root
      @root.add_command(self.class.subcommand)
    end

    def config
      @root
    end

    private

    def self.root`
      subcommand = Cri::Command.define do
         ...
      end 
      subcommand
   end

    def self.subcommand`
      subcommand = Cri::Command.define do
         ...
      end 
      subcommand
   end

end

I would like to do some initializations in the main class and pass parameters to the methods to make them available to the command definitions. Cri::Command.define could use an additional parameter (it has three now) that is an arbitrary hash. Not sure if this is the intended usage, or maybe I am missing a pattern to build a subcommand set in a modular fashion.

Allow specifying default values for non-provided options

See #52.

The current implementation of default values only works for optional options, and the default value will not be used if the option is not provided. This is counter-intuitive; the default value should be the one that is used even when the option is not specified.

Missing feature for parsing and validation of options and arguments

Would love to see feature for parsing, validation and transformation of options.

Something like delegate of Cri::OptionParser but exposed to be used.

Some food for thought

option :p, :port, 'port number' do |val, _cmd|  
  Integer(val)
end

or even part of call to option

option :p, :port, 'port number', Integer do |val, _cmd|  
  val.is_a? Integer => true
end

or

required :c, 'config-file', 'configuration file' do |val, _cmd|  
  Configuration.new(val)
end

And validation

required :n, :number, 'some number' do |val, _cmd|  
  raise SomeException if val.to_i) > 5
end

Arguments could also be validated. Some way to say, this command expects one positional argument, if not there, command is not executed and error message shown.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.