2

我正在开发一个应该用作CLI实用程序的 Ruby gem。

我决定使用Thor,它被rails命令使用并且似乎非常灵活(与rake: link的区别)。

问题是我找不到如何处理输入错误。例如,如果我输入了错误的选项,Thor 会自动返回一个很好的警告:

$ myawesomescript blabla
Could not find command "blabla".

但是,如果我使用无法解决的命令,事情就会变得很糟糕。例如,有一个“帮助”默认命令,我已经定义了一个“hello”命令。如果我只输入“h”,这就是我得到的:

$ myawesomescript h
/Users/Tom/.rvm/gems/ruby-2.0.0-p0/gems/thor-0.18.1/lib/thor.rb:424:in `normalize_command_name': Ambiguous command h matches [hello, help] (ArgumentError)
    from /Users/Tom/.rvm/gems/ruby-2.0.0-p0/gems/thor-0.18.1/lib/thor.rb:340:in `dispatch'
    from /Users/Tom/.rvm/gems/ruby-2.0.0-p0/gems/thor-0.18.1/lib/thor/base.rb:439:in `start'
    from /Users/Tom/Documents/ruby/myawesomescript/bin/myawesomescript:9:in `<top (required)>'
    from /Users/Tom/.rvm/gems/ruby-2.0.0-p0/bin/myawesomescript:23:in `load'
    from /Users/Tom/.rvm/gems/ruby-2.0.0-p0/bin/myawesomescript:23:in `<main>'
    from /Users/Tom/.rvm/gems/ruby-2.0.0-p0/bin/ruby_noexec_wrapper:14:in `eval'
    from /Users/Tom/.rvm/gems/ruby-2.0.0-p0/bin/ruby_noexec_wrapper:14:in `<main>'
myawesomescript $

现在,我知道只输入“h”是愚蠢的,我可以重命名我的命令,但我不希望用户看到这类错误消息。

我试图用以下方法覆盖该方法:

def normalize_command_name(meth)
  super(meth)
rescue ArgumentError => e
  puts "print something useful"
end

...但它不起作用


新细节:

好的,我注意到该方法是在类上声明的,而不是在实例上。我尝试了以下方法,似乎效果很好,但这并不理想,而且有点 hacky:

文件:lib/myawesomescript/thor_overrides.rb

require 'thor'

class Thor
  class << self

    protected
      def normalize_command_name(meth)
        return default_command.to_s.gsub('-', '_') unless meth

        possibilities = find_command_possibilities(meth)
        if possibilities.size > 1
          raise ArgumentError, "Ambiguous command #{meth} matches [#{possibilities.join(', ')}]"
        elsif possibilities.size < 1
          meth = meth || default_command
        elsif map[meth]
          meth = map[meth]
        else
          meth = possibilities.first
        end

        meth.to_s.gsub('-','_') # treat foo-bar as foo_bar
      rescue ArgumentError => e
        # do nothing
      end
      alias normalize_task_name normalize_command_name
  end
end

在那里我添加了以下几行:

rescue ArgumentError => e
  # do nothing

它可以解决问题,因为似乎在其他地方有一些代码负责处理错误消息:

$ myawesomescript h
Could not find command "h".

无论如何,有没有更好的方法?

4

1 回答 1

1

如果您查看错误消息:

 Ambiguous command h matches [hello, help]

上面的意思是, for h, thor 找到多个匹配项。这是由于help命令已经定义(内置)。

我建议您使用内置的帮助命令来显示有关 CLI 工具功能的帮助和选项,而不是尝试修补它。

要使一个字母的命令快捷方式起作用-您应该将命令命名为不以字母开头h,例如fooor baryo& 等等。

如果您想要从 letter 开始的命令h,请更具体。

于 2016-11-27T04:20:50.650 回答