Skip to content

Commit

Permalink
Merge pull request #2 from tschaub/dest-mtime
Browse files Browse the repository at this point in the history
Check mtime of dest file if present.  This only has an effect in cases where a target has multiple dest files and a previous run failed after one or more of the dest files had been created.
  • Loading branch information
tschaub committed Sep 7, 2013
2 parents 993052a + 6a104e6 commit 82fca06
Show file tree
Hide file tree
Showing 10 changed files with 166 additions and 19 deletions.
1 change: 0 additions & 1 deletion fixtures/one.js

This file was deleted.

1 change: 0 additions & 1 deletion fixtures/two.js

This file was deleted.

15 changes: 10 additions & 5 deletions gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ module.exports = function(grunt) {
var gruntfileSrc = 'gruntfile.js';
var tasksSrc = 'tasks/**/*.js';
var testSrc = 'test/**/*.spec.js';
var fixturesJs = 'test/fixtures/**/*.js';
var fixturesAll = 'test/fixtures/**/*';

grunt.initConfig({

Expand All @@ -33,11 +35,14 @@ module.exports = function(grunt) {
tasks: {
src: tasksSrc
},
fixtures: {
tests: {
options: {
jshintrc: 'test/.jshintrc'
},
src: testSrc
},
fixturesJs: {
src: fixturesJs
}
},

Expand All @@ -50,12 +55,12 @@ module.exports = function(grunt) {
files: testSrc,
tasks: ['newer:cafemocha']
},
fixtures: {
files: 'test/fixtures/**/*',
fixturesAll: {
files: fixturesAll,
tasks: ['cafemocha']
},
all: {
files: [gruntfileSrc, tasksSrc, testSrc],
allJs: {
files: [gruntfileSrc, tasksSrc, testSrc, fixturesJs],
tasks: ['newer:jshint']
}
}
Expand Down
15 changes: 14 additions & 1 deletion tasks/newer.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,21 @@ function createTask(grunt, any) {
// look for files that have been modified since last run
var previous = fs.statSync(stamp).mtime;
newerFiles = files.map(function(obj) {
var time;
/**
* It is possible that there is a dest file that has been created
* more recently than the last successful run. This would happen if
* a target with multiple dest files failed before all dest files were
* 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 src = obj.src.filter(function(filepath) {
var newer = fs.statSync(filepath).mtime > previous;
var newer = fs.statSync(filepath).mtime > time;
if (newer) {
modified = true;
}
Expand Down
94 changes: 94 additions & 0 deletions test/fixtures/newer-dest/gruntfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
var path = require('path');


/**
* @param {Object} grunt Grunt.
*/
module.exports = function(grunt) {

var log = [];

grunt.initConfig({
newer: {
options: {
timestamps: path.join(__dirname, '.cache')
}
},
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('../../../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'

]);

});

};
3 changes: 3 additions & 0 deletions test/fixtures/newer-dest/src/one.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
coffee =
is: 'good'
hot: true
3 changes: 3 additions & 0 deletions test/fixtures/newer-dest/src/two.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
semicolons = true
coffee = true
semicolons = false if coffee
4 changes: 0 additions & 4 deletions test/fixtures/newer-modify-one/gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,6 @@ module.exports = function(grunt) {
grunt.loadTasks('../../../tasks');
grunt.loadTasks('../../../test/tasks');

grunt.registerTask('fail', function() {
throw new Error('see above');
});

grunt.registerTask('default', function() {

grunt.task.run([
Expand Down
23 changes: 23 additions & 0 deletions test/newer-dest.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
var path = require('path');

var helper = require('./helper');

var name = 'newer-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);
});

});
26 changes: 19 additions & 7 deletions test/tasks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,42 @@ function prune(obj) {
}


/**
* Remove files config objects with no src files.
* @param {Array} files Array of files config objects.
* @return {Array} Filtered array of files config objects.
*/
function filter(files) {
return files.map(prune).filter(function(obj) {
return obj.src && obj.src.length > 0;
});
}


/** @param {Object} grunt Grunt. */
module.exports = function(grunt) {

grunt.registerMultiTask('assert', function(name, target) {
var config = grunt.config([name, target]);
var expected = grunt.task.normalizeMultiTaskFiles(config, target)
.map(prune);
var expected = filter(grunt.task.normalizeMultiTaskFiles(config, target));
var log = this.data.getLog();

if (expected.length === 0 || expected[0].src.length === 0) {
if (expected.length === 0) {
assert.equal(log.length, 0, 'No log entries');
} else {
assert.equal(log.length, 1, 'One log entry');
var actual = log[0].map(prune);
var actual = log[0];
assert.deepEqual(actual, expected);
log.length = 0;
}

});


grunt.registerMultiTask('log', function() {
var log = this.data.getLog();
log.push(this.files.map(prune));
var files = filter(this.files);
if (files.length > 0) {
this.data.getLog().push(files);
}
});


Expand Down

0 comments on commit 82fca06

Please sign in to comment.