From a77139b4d23b02302686b367508dd99bdd3ba575 Mon Sep 17 00:00:00 2001 From: Roy Riojas Date: Wed, 25 Sep 2013 18:10:12 -0700 Subject: [PATCH 1/5] Attempt to always execute the task if the any-newer prefix is present --- tasks/newer.js | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/tasks/newer.js b/tasks/newer.js index 4c3ce13..f89831a 100644 --- a/tasks/newer.js +++ b/tasks/newer.js @@ -80,18 +80,25 @@ function createTask(grunt, any) { * created. In this case, we don't need to re-run src files that map * to dest files that were already created. */ - if (obj.dest && grunt.file.exists(obj.dest)) { - time = Math.max(fs.statSync(obj.dest).mtime, previous); - } else { - time = previous; + var existsDest = grunt.file.exists(obj.dest); + if (!existsDest && prefix === 'any-newer') { + modified = true; } - var src = obj.src.filter(function(filepath) { - var newer = fs.statSync(filepath).mtime > time; - if (newer) { - modified = true; + else { + if (obj.dest && existsDest) { + time = Math.max(fs.statSync(obj.dest).mtime, previous); + } else { + time = previous; } - return newer; - }); + var src = obj.src.filter(function(filepath) { + var newer = fs.statSync(filepath).mtime > time; + if (newer) { + modified = true; + } + return newer; + }); + } + return {src: src, dest: obj.dest}; }).filter(function(obj) { return obj.src && obj.src.length > 0; From 5493e42bec25ab71ceea045876838f52f1948e3a Mon Sep 17 00:00:00 2001 From: Roy Riojas Date: Wed, 25 Sep 2013 18:58:30 -0700 Subject: [PATCH 2/5] Fix issue where newer task refuses to run a task with a deleted target file --- tasks/newer.js | 45 +++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/tasks/newer.js b/tasks/newer.js index f89831a..5f7952a 100644 --- a/tasks/newer.js +++ b/tasks/newer.js @@ -28,8 +28,9 @@ function pluckConfig(id) { function createTask(grunt, any) { return function(name, target) { var tasks = []; + var prefix = this.name; if (!target) { - var prefix = this.name; + Object.keys(grunt.config(name)).forEach(function(target) { if (!/^_|^options$/.test(target)) { tasks.push(prefix + ':' + name + ':' + target); @@ -80,23 +81,35 @@ function createTask(grunt, any) { * created. In this case, we don't need to re-run src files that map * to dest files that were already created. */ - var existsDest = grunt.file.exists(obj.dest); - if (!existsDest && prefix === 'any-newer') { - modified = true; + // when dest is undefined the task fails... + // better verify first + var existsDest = obj.dest && grunt.file.exists(obj.dest); + + if (obj.dest && existsDest) { + time = Math.max(fs.statSync(obj.dest).mtime, previous); + } else { + // if the destination file is set, but does not exists + // we do want to run the task. + // This fixes a bug where the clean task delete the generated files + // and since there are not new files the task is not run + // which let the build in an inconsistent state + if (obj.dest) { + modified = true + } + else { + time = previous; + } } - else { - if (obj.dest && existsDest) { - time = Math.max(fs.statSync(obj.dest).mtime, previous); - } else { - time = previous; + var src = obj.src.filter(function(filepath) { + var newer = fs.statSync(filepath).mtime > time; + if (newer) { + modified = true; } - var src = obj.src.filter(function(filepath) { - var newer = fs.statSync(filepath).mtime > time; - if (newer) { - modified = true; - } - return newer; - }); + return newer; + }); + + if (!existsDest && prefix === 'any-newer') { + modified = true; } return {src: src, dest: obj.dest}; From 824feff7e66a3a105e14b15d6e48ae27a1d80031 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Thu, 26 Sep 2013 12:34:40 +0200 Subject: [PATCH 3/5] Lint --- tasks/newer.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/tasks/newer.js b/tasks/newer.js index 5f7952a..bb02170 100644 --- a/tasks/newer.js +++ b/tasks/newer.js @@ -30,7 +30,6 @@ function createTask(grunt, any) { var tasks = []; var prefix = this.name; if (!target) { - Object.keys(grunt.config(name)).forEach(function(target) { if (!/^_|^options$/.test(target)) { tasks.push(prefix + ':' + name + ':' + target); @@ -84,20 +83,19 @@ function createTask(grunt, any) { // when dest is undefined the task fails... // better verify first var existsDest = obj.dest && grunt.file.exists(obj.dest); - if (obj.dest && existsDest) { time = Math.max(fs.statSync(obj.dest).mtime, previous); } else { // if the destination file is set, but does not exists // we do want to run the task. // This fixes a bug where the clean task delete the generated files - // and since there are not new files the task is not run + // and since there are not new files the task is not run // which let the build in an inconsistent state if (obj.dest) { - modified = true + modified = true; } else { - time = previous; + time = previous; } } var src = obj.src.filter(function(filepath) { @@ -106,12 +104,11 @@ function createTask(grunt, any) { modified = true; } return newer; - }); + }); if (!existsDest && prefix === 'any-newer') { modified = true; } - return {src: src, dest: obj.dest}; }).filter(function(obj) { return obj.src && obj.src.length > 0; From b2b307e006bbd4ccb933c7e6d7a211949923d666 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Thu, 26 Sep 2013 12:49:47 +0200 Subject: [PATCH 4/5] Create dest files in tests --- test/tasks/index.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/tasks/index.js b/test/tasks/index.js index e0e8bf3..848ec7c 100644 --- a/test/tasks/index.js +++ b/test/tasks/index.js @@ -51,6 +51,12 @@ module.exports = function(grunt) { if (files.length > 0) { this.data.getLog().push(files); } + // create all dest files + files.forEach(function(obj) { + if (obj.dest) { + grunt.file.write(obj.dest, ''); + } + }); }); From da00be6d30ef93c24660cc0233e8c16a159ebfb4 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Thu, 26 Sep 2013 13:17:46 +0200 Subject: [PATCH 5/5] Integration tests for cleaning dest files --- package.json | 3 +- tasks/newer.js | 15 +-- test/fixtures/newer-clean-dest/gruntfile.js | 110 ++++++++++++++++++ test/fixtures/newer-clean-dest/src/one.coffee | 3 + test/fixtures/newer-clean-dest/src/two.coffee | 3 + test/newer-clean-dest.spec.js | 23 ++++ 6 files changed, 145 insertions(+), 12 deletions(-) create mode 100644 test/fixtures/newer-clean-dest/gruntfile.js create mode 100644 test/fixtures/newer-clean-dest/src/one.coffee create mode 100644 test/fixtures/newer-clean-dest/src/two.coffee create mode 100644 test/newer-clean-dest.spec.js diff --git a/package.json b/package.json index 73113e0..946bc79 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,8 @@ "chai": "1.7.2", "grunt-cafe-mocha": "0.1.8", "wrench": "1.5.1", - "tmp": "0.0.21" + "tmp": "0.0.21", + "grunt-contrib-clean": "0.5.0" }, "peerDependencies": { "grunt": "~0.4.1" diff --git a/tasks/newer.js b/tasks/newer.js index bb02170..54d8d0f 100644 --- a/tasks/newer.js +++ b/tasks/newer.js @@ -80,21 +80,14 @@ function createTask(grunt, any) { * created. In this case, we don't need to re-run src files that map * to dest files that were already created. */ - // when dest is undefined the task fails... - // better verify first var existsDest = obj.dest && grunt.file.exists(obj.dest); - if (obj.dest && existsDest) { + if (existsDest) { time = Math.max(fs.statSync(obj.dest).mtime, previous); } else { - // if the destination file is set, but does not exists - // we do want to run the task. - // This fixes a bug where the clean task delete the generated files - // and since there are not new files the task is not run - // which let the build in an inconsistent state if (obj.dest) { - modified = true; - } - else { + // The dest file may have been removed. Run with all src files. + time = 0; + } else { time = previous; } } diff --git a/test/fixtures/newer-clean-dest/gruntfile.js b/test/fixtures/newer-clean-dest/gruntfile.js new file mode 100644 index 0000000..4c61f9a --- /dev/null +++ b/test/fixtures/newer-clean-dest/gruntfile.js @@ -0,0 +1,110 @@ +var path = require('path'); + + +/** + * @param {Object} grunt Grunt. + */ +module.exports = function(grunt) { + + var log = []; + + grunt.initConfig({ + newer: { + options: { + timestamps: path.join(__dirname, '.cache') + } + }, + clean: { + one: 'dest/one.js', + all: 'dest' + }, + modified: { + one: { + files: [{ + expand: true, + cwd: 'src/', + src: 'one.coffee', + dest: 'dest/', + ext: '.js' + }] + }, + all: { + files: [{ + expand: true, + cwd: 'src/', + src: '**/*.coffee', + dest: 'dest/', + ext: '.js' + }] + }, + none: { + src: [] + } + }, + log: { + all: { + files: [{ + expand: true, + cwd: 'src/', + src: '**/*.coffee', + dest: 'dest/', + ext: '.js' + }], + getLog: function() { + return log; + } + } + }, + assert: { + that: { + getLog: function() { + return log; + } + } + } + }); + + grunt.loadTasks('../../../node_modules/grunt-contrib-clean/tasks'); + + grunt.loadTasks('../../../tasks'); + grunt.loadTasks('../../../test/tasks'); + + grunt.registerTask('default', function() { + + grunt.task.run([ + // run the log task with newer, expect all files + 'newer:log', + 'assert:that:modified:all', + + // HFS+ filesystem mtime resolution + 'wait:1001', + + // modify one file + 'modified:one', + + // run assert task again, expect one file + 'newer:log', + 'assert:that:modified:one', + + // HFS+ filesystem mtime resolution + 'wait:1001', + + // modify nothing, expect no files + 'newer:log', + 'assert:that:modified:none', + + // remove one dest file, expect one file + 'clean:one', + 'newer:log', + 'assert:that:modified:one', + + // remove all dest file, expect all + 'clean:all', + 'newer:log', + 'assert:that:modified:all' + + ]); + + }); + +}; diff --git a/test/fixtures/newer-clean-dest/src/one.coffee b/test/fixtures/newer-clean-dest/src/one.coffee new file mode 100644 index 0000000..aa0ae5a --- /dev/null +++ b/test/fixtures/newer-clean-dest/src/one.coffee @@ -0,0 +1,3 @@ +coffee = + is: 'good' + hot: true diff --git a/test/fixtures/newer-clean-dest/src/two.coffee b/test/fixtures/newer-clean-dest/src/two.coffee new file mode 100644 index 0000000..2f77f36 --- /dev/null +++ b/test/fixtures/newer-clean-dest/src/two.coffee @@ -0,0 +1,3 @@ +semicolons = true +coffee = true +semicolons = false if coffee diff --git a/test/newer-clean-dest.spec.js b/test/newer-clean-dest.spec.js new file mode 100644 index 0000000..883e437 --- /dev/null +++ b/test/newer-clean-dest.spec.js @@ -0,0 +1,23 @@ +var path = require('path'); + +var helper = require('./helper'); + +var name = 'newer-clean-dest'; +var gruntfile = path.join(name, 'gruntfile.js'); + +describe(name, function() { + var fixture; + + it('runs the default task (see ' + gruntfile + ')', function(done) { + this.timeout(3000); + helper.buildFixture(name, function(error, dir) { + fixture = dir; + done(error); + }); + }); + + after(function(done) { + helper.afterFixture(fixture, done); + }); + +});