Состояние выхода Ruby/Thor в случае ошибки

Я новичок в 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), иначе сценарий продолжит работать, даже если он завершится. Последующие ошибки могут быть трудно анализировать.

Я должен что-то упустить, отсюда и мои вопросы:

  • Есть ли простой способ получить ненулевой статус по умолчанию в случае ошибки (файл конфигурации и т. Д.)?

  • Если нет, что я должен сделать, чтобы сделать это правильно?

Спасибо.

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

Написано, как указано выше, оно ведет себя так же, как и раньше (я считаю). Теперь, после удаления # от Thor#ough, он должен выйти со статусом 1, если Тор поднял Error, таким образом позволяя некоторый контроль, например, от нерубиновой оболочки.

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: Интересно, много ли таких ошибок в Торе? Если это ожидаемое поведение, его цель / философия несовместимы с потребностями моего проекта... хаки не являются надежным решением.

Я знаю, что на этот вопрос уже дан ответ, но я думаю, что это лучший ответ, поэтому я решил, что все равно внесу его.

У Thor есть метод, который вы можете использовать для изменения поведения, чтобы ошибки вызывали ненулевые коды выхода. Это не очень хорошо задокументировано (ИМХО).

class Test < Thor
  def self.exit_on_failure?
    true
  end

  desc "example", "an example task"
  def example
    puts "I'm a thor task!"
  end
end

По умолчанию это необъяснимо false, Я не знаю, почему кто-то хотел бы, чтобы он так себя вел. Это касается и проблемы 244.

Хороший вопрос. Я также заметил это, когда смотрел 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
Другие вопросы по тегам