Skip to content

Commit

Permalink
Merge pull request #99 from ddfreyne/default-false
Browse files Browse the repository at this point in the history
Don’t set default options as explicit keys
  • Loading branch information
denisdefreyne committed Jun 8, 2019
2 parents d1fda31 + 8c3c6ca commit a8d4cef
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 17 deletions.
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,33 @@ OPTIONS
-a --animal[=<value>] add animal (default: giraffe)
```

If the option is not given on the command line, the `options` hash will not have key for this option, but will still have a default value:

```ruby
option :a, :animal, 'add animal', default: 'giraffe', argument: :required

run do |opts, args, cmd|
puts "Animal = #{opts[:animal]}"
puts "Option given? #{opts.key?(:animal)}"
end
```

```sh
% ./run --animal=donkey
Animal = donkey
Option given? true

% ./run --animal=giraffe
Animal = giraffe
Option given? true

% ./run
Animal = giraffe
Option given? false
```

This can be useful to distinguish between an explicitly-passed-in value and a default value. In the example above, the `animal` option is set to `giraffe` in the second and third cases, but it is possible to detect whether the value is a default or not.

#### Multivalued options (`multiple:`)

The `:multiple` parameter allows an option to be specified more than once on the command line. When set to `true`, multiple option valus are accepted, and the option values will be stored in an array.
Expand Down
19 changes: 13 additions & 6 deletions lib/cri/command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ def run_this(opts_and_args, parent_opts = {})
handle_errors_while { parser.run }
local_opts = parser.options
global_opts = parent_opts.merge(parser.options)
add_defaults(global_opts)
global_opts = add_defaults(global_opts)

# Handle options
handle_options(local_opts)
Expand Down Expand Up @@ -435,14 +435,21 @@ def handle_errors_while
end

def add_defaults(options)
all_opt_defns.each do |opt_defn|
key = (opt_defn.long || opt_defn.short).to_sym
all_opt_defns_by_key =
all_opt_defns.each_with_object({}) do |opt_defn, hash|
key = (opt_defn.long || opt_defn.short).to_sym
hash[key] = opt_defn
end

next if opt_defn.default.nil?
next if options.key?(key)
new_options = Hash.new do |hash, key|
hash.fetch(key) { all_opt_defns_by_key[key]&.default }
end

options[key] = opt_defn.default
options.each do |key, value|
new_options[key] = value
end

new_options
end
end
end
22 changes: 11 additions & 11 deletions test/test_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def test_invoke_simple_without_opts_or_args
simple_cmd.run(%w[])
end

assert_equal ['Awesome moo!', '', 'ddd=false,eee=false'], lines(out)
assert_equal ['Awesome moo!', '', ''], lines(out)
assert_equal [], lines(err)
end

Expand All @@ -135,7 +135,7 @@ def test_invoke_simple_with_args
simple_cmd.run(%w[abc xyz])
end

assert_equal ['Awesome moo!', 'abc,xyz', 'ddd=false,eee=false'], lines(out)
assert_equal ['Awesome moo!', 'abc,xyz', ''], lines(out)
assert_equal [], lines(err)
end

Expand All @@ -144,7 +144,7 @@ def test_invoke_simple_with_opts
simple_cmd.run(%w[-c -b x])
end

assert_equal ['Awesome moo!', '', 'bbb=x,ccc=true,ddd=false,eee=false'], lines(out)
assert_equal ['Awesome moo!', '', 'bbb=x,ccc=true'], lines(out)
assert_equal [], lines(err)
end

Expand Down Expand Up @@ -216,7 +216,7 @@ def test_invoke_simple_with_opt_with_block
simple_cmd.run(%w[-a 123])
end

assert_equal ['moo:123', 'Awesome moo!', '', 'aaa=123,ddd=false,eee=false'], lines(out)
assert_equal ['moo:123', 'Awesome moo!', '', 'aaa=123'], lines(out)
assert_equal [], lines(err)
end

Expand Down Expand Up @@ -246,7 +246,7 @@ def test_invoke_nested_with_correct_command_name
nested_cmd.run(%w[sub])
end

assert_equal ['Sub-awesome!', '', 'ddd=false,eee=false,ppp=false,qqq=false'], lines(out)
assert_equal ['Sub-awesome!', '', ''], lines(out)
assert_equal [], lines(err)
end

Expand Down Expand Up @@ -297,7 +297,7 @@ def test_invoke_nested_with_alias
nested_cmd.run(%w[sup])
end

assert_equal ['Sub-awesome!', '', 'ddd=false,eee=false,ppp=false,qqq=false'], lines(out)
assert_equal ['Sub-awesome!', '', ''], lines(out)
assert_equal [], lines(err)
end

Expand All @@ -306,7 +306,7 @@ def test_invoke_nested_with_options_before_command
nested_cmd.run(%w[-a 666 sub])
end

assert_equal ['super:666', 'Sub-awesome!', '', 'aaa=666,ddd=false,eee=false,ppp=false,qqq=false'], lines(out)
assert_equal ['super:666', 'Sub-awesome!', '', 'aaa=666'], lines(out)
assert_equal [], lines(err)
end

Expand Down Expand Up @@ -902,14 +902,14 @@ def test_flag_defaults_to_false
option :f, :force2, 'push with force', argument: :forbidden

run do |opts, _args, _cmd|
puts "Force? #{opts[:force2].inspect}!"
puts "Force? #{opts[:force2].inspect}! Key present? #{opts.key?(:force2)}!"
end
end

out, err = capture_io_while do
cmd.run(%w[])
end
assert_equal ['Force? false!'], lines(out)
assert_equal ['Force? false! Key present? false!'], lines(out)
assert_equal [], lines(err)
end

Expand All @@ -919,14 +919,14 @@ def test_required_option_defaults_to_given_value
option :a, :animal, 'specify animal', argument: :required, default: 'cow'

run do |opts, _args, _cmd|
puts "Animal = #{opts[:animal]}"
puts "Animal = #{opts[:animal]}! Key present? #{opts.key?(:animal)}!"
end
end

out, err = capture_io_while do
cmd.run(%w[])
end
assert_equal ['Animal = cow'], lines(out)
assert_equal ['Animal = cow! Key present? false!'], lines(out)
assert_equal [], lines(err)
end

Expand Down

0 comments on commit a8d4cef

Please sign in to comment.