9

私は Thor (および Ruby) が初めてで、ビルド スクリプト内で使用することを検討しています。Rake (したがって Make) の代わりになると言われているからです。ただし、短い試行の後、返されるエラーステータスについて混乱しています。私はすぐにウィキを調べましたが、それについての言及は見当たりませんでした。

最初の「簡単な例」だけで、次のようになりtest.thorます。

class Test < Thor
  desc "example", "an example task"
  def example
    puts "I'm a thor task!"
  end
end

バージョン #:

eruve>thor version
Thor 0.18.1

意図的に誤ったコマンドである次のことを試しました。

eruve>ruby --version; thor test:example badarg; echo exit status: $?

ruby 2.0.0p195 (2013-05-14 revision 40734) [x86_64-darwin10.8.0]
ERROR: thor example was called with arguments ["badarg"]
Usage: "thor test:example".
exit status: 0

したがって、エラーが発生しましたが、それでもステータス 0 で終了します...つまり、(Ruby 以外の) スクリプトでは使用したくないということです。その後のエラーは、分析が難しい場合があります。

私は何かが欠けているに違いないので、私の質問:

  • エラー (構成ファイルなど) が発生した場合にデフォルトでゼロ以外のステータスを取得する簡単な方法はありますか?

  • そうでない場合、それを正しくするために何をすべきですか?

ありがとうございました。

4

3 に答える 3

3

バンドラーのソリューション (@fontno に感謝します) と、私の側でのさらなる調査に基づいて、通常のシェルで動作させるためのハックを次に示します。警告: エレガントではなく、例外スタックのがらくたを出力しますが、うまくいくと思います (そうでない場合は遠慮なく教えてください)。

class Thorough < Thor
  ENV["THOR_DEBUG"] = "1"
  check_unknown_options!
private
  def subcommand(*_) super subcommand(*_)
  rescue Thor::Error => e
    $stderr.puts e.message
    exit 1
  end
end

class Test < Thor#ough
  desc "example", "an example task"
  def example
    puts "I'm a thor task!"
  end
end

上記のように書かれており、以前と同じ動作をしています(私は信じています)。#ここで、 fromを削除した後、Thor#oughThor が を発生させた場合はステータス 1 で終了する必要がありますError。これにより、たとえば非 ruby​​ シェルからの制御が可能になります。

eruve>thor test:example badarg; echo $?
/Users/eruve/.rvm/gems/ruby-2.0.0-p195/gems/thor-0.18.1/lib/thor/base.rb:482:in `handle_argument_error': ERROR: thor example was called with arguments ["badarg"] (Thor::InvocationError)
Usage: "thor test:example".
    from /Users/eruve/.rvm/gems/ruby-2.0.0-p195/gems/thor-0.18.1/lib/thor/command.rb:35:in `rescue in run'
    from /Users/eruve/.rvm/gems/ruby-2.0.0-p195/gems/thor-0.18.1/lib/thor/command.rb:21:in `run'
    from /Users/eruve/.rvm/gems/ruby-2.0.0-p195/gems/thor-0.18.1/lib/thor/invocation.rb:120:in `invoke_command'
    from /Users/eruve/.rvm/gems/ruby-2.0.0-p195/gems/thor-0.18.1/lib/thor.rb:363:in `dispatch'
    from /Users/eruve/.rvm/gems/ruby-2.0.0-p195/gems/thor-0.18.1/lib/thor/base.rb:439:in `start'
    from /Users/eruve/.rvm/gems/ruby-2.0.0-p195/gems/thor-0.18.1/lib/thor/runner.rb:36:in `method_missing'
    from /Users/eruve/.rvm/gems/ruby-2.0.0-p195/gems/thor-0.18.1/lib/thor/command.rb:29:in `run'
    from /Users/eruve/.rvm/gems/ruby-2.0.0-p195/gems/thor-0.18.1/lib/thor/command.rb:128:in `run'
    from /Users/eruve/.rvm/gems/ruby-2.0.0-p195/gems/thor-0.18.1/lib/thor/invocation.rb:120:in `invoke_command'
    from /Users/eruve/.rvm/gems/ruby-2.0.0-p195/gems/thor-0.18.1/lib/thor.rb:363:in `dispatch'
    from /Users/eruve/.rvm/gems/ruby-2.0.0-p195/gems/thor-0.18.1/lib/thor/base.rb:439:in `start'
    from /Users/eruve/.rvm/gems/ruby-2.0.0-p195/gems/thor-0.18.1/bin/thor:6:in `<top (required)>'
    from /Users/eruve/.rvm/gems/ruby-2.0.0-p195/bin/thor:23:in `load'
    from /Users/eruve/.rvm/gems/ruby-2.0.0-p195/bin/thor:23:in `<main>'
    from /Users/eruve/.rvm/gems/ruby-2.0.0-p195/bin/ruby_noexec_wrapper:14:in `eval'
    from /Users/eruve/.rvm/gems/ruby-2.0.0-p195/bin/ruby_noexec_wrapper:14:in `<main>'
1

eruve>thor test:example; echo $?
I'm a thor task!
0

eruve>thor test:example badarg 2>/dev/null; echo $?
1

乾杯。PS: トールには、このような落とし穴がたくさんあるのだろうか? それが期待される動作である場合、その目的/哲学は私のプロジェクトのニーズと互換性がありません.ハッキングは信頼できる解決策ではありません.

于 2013-06-22T05:28:20.077 に答える
1

良い質問。thorプロジェクトに使用するものを探しているときにもこれに気付きました。私が知る限り、これは予想される動作です。このプルリクエストにbundlerは、あなたに適した興味深い解決策があります。

彼らはトールデバッグフラグを有効にして、エラーをキャッチして適切な終了ステータスを設定できるようにしました

# bin/bundle

Bundler.with_friendly_errors {
    # Set debug flag so we can rescue Thor::error's
    # and set the correct exit code.
    ENV["THOR_DEBUG"] = "1"
    Bundler::CLI.start
}


# friendly_errors

rescue Thor::UndefinedCommandError => e
    Bundler.ui.error e.message
    exit 15
  rescue Thor::Error => e
    Bundler.ui.error e.message
    exit 1
于 2013-06-21T20:34:38.013 に答える