22

有没有办法配置一系列任务,以便特定的后续任务(我不希望 --force 在整个批次上运行)即使一个失败也能运行?例如,考虑这样的情况

  1. 创建一些临时文件
  2. 运行一些涉及这些临时文件的单元测试
  3. 清理那些临时文件

我可以做这个:

grunt.registerTask('testTheTemp', ['makeTempFiles', 'qunit', 'removeTempFiles']);

但如果 qunit 失败,则 removeTempFiles 任务永远不会运行。

4

5 回答 5

19

为了子孙后代,当我们等待来自@explunit 的PR登陆 grunt 时,这可能是一个改进的 hack:

var previous_force_state = grunt.option("force");

grunt.registerTask("force",function(set){
    if (set === "on") {
        grunt.option("force",true);
    }
    else if (set === "off") {
        grunt.option("force",false);
    }
    else if (set === "restore") {
        grunt.option("force",previous_force_state);
    }
});

// .....

grunt.registerTask("foobar",[
    "task1",
    "task2",
    "force:on",     // temporarily turn on --force
    "task3",        // will run with --force in effect
    "force:restore",// restore previous --force state
    "task4"
]);
于 2013-10-30T04:01:14.717 回答
19

这是一种解决方法。它不漂亮,但它确实解决了问题。

您创建了两个额外的任务,您可以将它们包装在您想要继续的任何序列的开头/结尾,即使失败也是如此。检查现有值grunt.option('force')是为了不覆盖--force从命令行传递的任何值。

grunt.registerTask('usetheforce_on',
 'force the force option on if needed', 
 function() {
  if ( !grunt.option( 'force' ) ) {
    grunt.config.set('usetheforce_set', true);
    grunt.option( 'force', true );
  }
});
grunt.registerTask('usetheforce_restore', 
  'turn force option off if we have previously set it', 
  function() {
  if ( grunt.config.get('usetheforce_set') ) {
    grunt.option( 'force', false );
  }
});
grunt.registerTask( 'myspecialsequence',  [
  'usetheforce_on', 
  'task_that_might_fail_and_we_do_not_care', 
  'another_task', 
  'usetheforce_restore', 
  'qunit', 
  'task_that_should_not_run_after_failed_unit_tests'
] );

我还向 Grunt 提交了一个功能请求以支持本机。

于 2013-06-06T21:57:37.277 回答
3

也许您可以创建一个异步grunt 任务并grunt.util.spawn串行执行您想要的任务。然后,您可以为成功/错误代码编写一些条件逻辑。类似于这个问题的答案

于 2013-05-21T01:12:43.460 回答
3

呼应 Marius 的评论,grunt-force-task 插件现在提供此功能。通过上面的链接查看完整的详细信息,但简而言之,这是实现预期效果所需要的

npm install grunt-force-task --save-dev

然后将其导入您的 gruntfile

grunt.loadNpmTasks('grunt-force-task');

最后,只需将 force: 前缀添加到您一直想要运行的任务之前。

grunt.registerTask('testTemp', ['makeTempFiles', 'force:qunit', 'removeTempFiles']);

现在即使测试失败,removeTempFiles 也将始终运行。

于 2016-02-02T17:26:57.123 回答
1

使用上面提到的grunt-force-task 插件的一个问题是 grunt 进程现在将无条件退出 0(这意味着通过)。

如果您想在 CI(持续集成)环境中使用 grunt 并根据您的测试/构建(qunit在 OP 中)是通过还是失败来使 CI 任务失败,这是一个问题。我通过添加一个新任务来解决这个问题,该任务使用 grunt 的this.requires函数来测试是qunit通过还是失败:

grunt.registerTask('exitWithQunitStatus', function() {
  this.requires(['qunit']);
  return true;
})

grunt.registerTask('testTheTemp', ['makeTempFiles', 'force:qunit', 'removeTempFiles', 'exitWithQunitStatus']);

现在,如果qunit失败,grunt 将退出 3,表示Task Error. 如果没有exitWithQunitStatus,grunt 进程将以 0 退出。

this.requires记录在这里: http: //gruntjs.com/api/inside-tasks#this.requires。基本上,除非所有指定的“必需”任务都已运行并通过,否则它将使当前任务失败。

于 2016-06-17T06:45:57.070 回答