2013-06-21 23 views
8

我是Thor(和Ruby)的新手,我正在考虑在构建脚本中使用它,因为它表示它可以替代Rake(因此可以替换为Rake )。但是经过短暂的试用后,我对它返回的错误状态感到困惑。我很快浏览了wiki,但没有看到任何提及。如果发生错误,Ruby/Thor退出状态

只需第一 “简单实施例”,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的状态退出......意味着我宁愿不用它在(n on-ruby)脚本,否则脚本会继续运行,即使应该终止。随后的错误可能难以分析。

我必须失去了一些东西,所以我的问题:

  • 有一种简单的方法来获得在发生错误的情况下默认为非零状态(配置文件等)?

  • 如果不是,我应该怎么做才能正确吗?

谢谢。

回答

2

(非常感谢@fontno),并在我的身边更多的调查,这里是一个黑客为了让它与一个普通的shell一起工作。警告:它不是优雅的,打印出异常堆栈垃圾,但我认为这是可行的(请不要犹豫,告诉我否则)。

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移除#之后,如果Thor已经提出了Error,则它应该退出状态1,从而允许来自例如一个非红宝石外壳。

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有很多这样的陷阱吗?如果这是一种预期的行为,其目的/理念与我的项目需求不相容......黑客并不是可靠的解决方案。

1

好问题。当看到thor用于项目时,我也注意到了这一点。据我所知,这是预期的行为。这pull request for 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 
+0

+1因为它导致了黑客(请参阅我的答案),尽管这不是直接可用的,特别是作为Ruby之外的解决方案。 – eruve

18

我知道这已经得到了回答,但我认为这是一个更好的答案,所以我想我会贡献它无论如何。

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。我不知道为什么有人会希望它的行为像个人。 Thor issue 244也解决了这个问题。

+0

这应该是被接受的答案 –