如果某些文件被更改,则有条件地在grunt中运行任务

时间:2013-06-18 11:00:05

标签: gruntjs

我是Grunt的新手,从我理解到现在为止,Grunt有“监视”任务,它不断检查文件是否有修改,每次修改都会执行相应的任务。

我正在寻找的是一种离散版本 - 一个任务,当其他任务运行时,当且仅当自上次构建以来某些文件被更改时。

似乎是一件很自然的事情,但我找不到这个。它只是我,还是这真的是一个问题?

配置文件应如下所示:

grunt.initConfig({
  foo: {
    files: "foo/*"
    // some task
  },
  bar: {
    files: "bar/*"
    // some other task
  },
  ifModified: {
    foo: {
      files: "foo/*",
      tasks: ['foo']
    },
    bar: {
      files: 'bar/*',
      tasks: ['bar', 'foo']
    }
  }
});

grunt.registerTask('default', ['bar', 'foo']);

运行grunt应该始终执行任务'bar', 'foo',而运行grunt ifModified只有在自上次构建以来实际更改了某些文件时才应执行任何任务。

3 个答案:

答案 0 :(得分:4)

为此完成了我自己的任务。事实证明并不难,这是代码:

构建/任务/ IF-modified.js:

var fs = require('fs');
var crypto = require('crypto');

module.exports = function (grunt) {

    grunt.registerMultiTask('if-modified', 'Conditionally running tasks if files are changed.', function () {

        var options = this.options({});

        grunt.verbose.writeflags(options, 'Options');

        var hashes = {};
        if (grunt.file.exists(options.hashFile)) {
            try {
                hashes = grunt.file.readJSON(options.hashFile);
            }
            catch (err) {
                grunt.log.warn(err);
            }
        }
        grunt.verbose.writeflags(hashes, 'Hashes');

        var md5 = crypto.createHash('md5');

        this.files.forEach(function (f) {
            f.src.forEach(function (filepath) {
                var stats = fs.statSync(filepath);
                md5.update(JSON.stringify({
                    filepath: filepath,
                    isFile: stats.isFile(),
                    size: stats.size,
                    ctime: stats.ctime,
                    mtime: stats.mtime
                }));
            });
        });

        var hash = md5.digest('hex');
        grunt.verbose.writeln('Hash: ' + hash);

        if (hash != hashes[this.target]) {
            grunt.log.writeln('Something changed, executing tasks: ' + JSON.stringify(options.tasks));

            grunt.task.run(options.tasks);

            hashes[this.target] = hash;
            grunt.file.write(options.hashFile, JSON.stringify(hashes));
        }
        else
            grunt.log.writeln('Nothing changed.');

    });
};

Gruntfile.js:

grunt.initConfig({
  foo: {
    src: ["foo/**/*"],
    dest: "foo-dest"
    // some task
  },
  bar: {
    src: ["bar/**/*", "foo-dest"]
    // some other task
  },
  'if-modified': {
    options: {
      hashFile: 'build/hashes.json'
    },
    foo: {
      src: ['foo/**/*', 'Gruntfile.js', 'package.json'],
      options: {tasks: ['foo']}
    },
    bar: {
      src: ['bar/**/*', "foo-dest", 'Gruntfile.js', 'package.json'],
      options: {tasks: ['bar']}
    }
  }
});

grunt.loadTasks('build/tasks'); // if-modified.js in this dir

grunt.registerTask('default', ['foo', 'bar']);

运行:

grunt if-modified

答案 1 :(得分:0)

您可以创建一个有条件地运行其他任务的任务,来自https://github.com/gruntjs/grunt/wiki/Creating-tasks

grunt.registerTask('foo', 'My "foo" task.', function() {
  // Enqueue "bar" and "baz" tasks, to run after "foo" finishes, in-order.
  grunt.task.run('bar', 'baz');
  // Or:
  grunt.task.run(['bar', 'baz']);
});

答案 2 :(得分:0)

你需要什么可能是咕噜咕噜的新人:

  

较新的任务将配置另一个任务以使用src文件运行,这些文件比a文件更新或b)比上次成功运行更新(如果没有dest文件)。请参阅下面的示例和更多详细信息。

https://github.com/tschaub/grunt-newer