即使一个失败,也要继续执行grunt中的某些任务

时间:2013-05-17 15:13:24

标签: javascript gruntjs grunt-contrib-qunit

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

  1. 创建一些临时文件
  2. 运行一些涉及这些临时文件的单元测试
  3. 清理这些临时文件
  4. 我可以这样做:

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

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

5 个答案:

答案 0 :(得分:18)

为了后人的缘故,这可能是一个改进的黑客攻击,而我们等待来自@explunit的that PR落入咕噜声:

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"
]);

答案 1 :(得分:17)

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

您创建了两个额外的任务,您可以在任何序列的开头/结尾处包装,即使失败也要继续。检查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提交了feature request来支持这种本地化。

答案 2 :(得分:3)

也许您可以连续创建async grunt任务和grunt.util.spawn所需任务。然后,您可以为成功/错误代码编写一些条件逻辑。类似于question

的答案

答案 3 :(得分:3)

回应Marius的评论,grunt-force-task plugin现在提供此功能。按照上面的链接详细说明,但简而言之,这是达到预期效果所需要的

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

然后将其导入您的gruntfile

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

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

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

现在即使测试失败,removeTempFiles也会一直运行。

答案 4 :(得分:1)

使用上面提到的grunt-force-task plugin的一个问题是,grunt进程现在将无条件退出0(表示通过)。

如果您想在CI(持续集成)环境中使用grunt,并且根据您的测试/构建(OP中的qunit)是否通过而导致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.requireshttp://gruntjs.com/api/inside-tasks#this.requires。基本上它将失败当前任务,除非所有指定的“必需”任务已经运行并通过。