1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

lib/optparse.rb: Show a did_you_mean hint for unknown option

```
require 'optparse'

OptionParser.new do |opts|
  opts.on("-f", "--foo", "foo") {|v| }
  opts.on("-b", "--bar", "bar") {|v| }
  opts.on("-c", "--baz", "baz") {|v| }
end.parse!
```

```
$ ruby test.rb --baa
Traceback (most recent call last):
test.rb:7:in `<main>': invalid option: --baa (OptionParser::InvalidOption)
Did you mean?  baz
               bar
```
This commit is contained in:
Yusuke Endoh 2019-10-16 16:31:41 +09:00
parent 5ca5529d22
commit c3b64a86bc
Notes: git 2019-10-18 12:21:20 +09:00
2 changed files with 38 additions and 2 deletions

View file

@ -866,6 +866,10 @@ class OptionParser
__send__(id).complete(opt, icase, *pat, &block)
end
def get_candidates(id)
yield __send__(id).keys
end
#
# Iterates over each option, passing the option to the +block+.
#
@ -1766,7 +1770,17 @@ XXX
end
raise AmbiguousOption, catch(:ambiguous) {
visit(:complete, typ, opt, icase, *pat) {|o, *sw| return sw}
raise InvalidOption, opt
if defined? DidYouMean::SpellChecker
all_candidates = []
visit(:get_candidates, typ) do |candidates|
all_candidates.concat(candidates)
end
all_candidates.select! {|cand| cand.is_a?(String) }
suggestions = DidYouMean::SpellChecker.new(dictionary: all_candidates).correct(opt)
raise InvalidOption.new(opt, "\nDid you mean? #{suggestions.join("\n ")}")
else
raise InvalidOption, opt
end
}
end
private :complete
@ -2048,7 +2062,7 @@ XXX
# Default stringizing method to emit standard error message.
#
def message
reason + ': ' + args.join(' ')
reason + ': ' + args.join(" ").gsub(/\s+$/, "")
end
alias to_s message

View file

@ -0,0 +1,22 @@
# frozen_string_literal: false
require_relative 'test_optparse'
require "did_you_mean" rescue return
class TestOptionParser::DidYouMean < TestOptionParser
def setup
super
@opt.def_option("--foo", Integer) { |v| @foo = v }
@opt.def_option("--bar", Integer) { |v| @bar = v }
@opt.def_option("--baz", Integer) { |v| @baz = v }
end
def test_did_you_mean
assert_raise(OptionParser::InvalidOption) do
begin
@opt.permute!(%w"--baa")
ensure
assert_equal("invalid option: --baa\nDid you mean? baz\n bar", $!.message)
end
end
end
end