Permalink
Browse files

A bunch of fixes to file/directory task execution.

  • Loading branch information...
1 parent 418b95f commit 9cb81430ebd74768bd6b746b30415d754a7cacd0 @mde mde committed Dec 21, 2011
Showing with 60 additions and 32 deletions.
  1. +42 −26 lib/jake.js
  2. +9 −6 tests/Jakefile
  3. +9 −0 tests/file_task.js
View
@@ -277,9 +277,19 @@ jake = new function () {
, prereqs
, prereqName
, prereqTask
- , actionRan
+ , runAction = false
, stats
- , modTime;
+ , modTime
+ , isFileOrDirectory = function (t) {
+ return (t instanceof FileTask ||
+ t instanceof DirectoryTask);
+ }
+ , isFile = function (t) {
+ return t instanceof FileTask;
+ }
+ , prereqIsNewerThan = function (prereq, time) {
+ return _modTimes[prereq.name] > time;
+ };
// Finalize the mod-time of the previously processed file-task, if any
if (_taskIndex > 0) {
@@ -296,8 +306,8 @@ jake = new function () {
modTime = stats.ctime;
}
// If there's still no actual file after running the file-task,
- // treat this simply as a plain task -- the current time will be
- // the mod-time for anything that depends on this file-task
+ // treat this simply as a plain task -- the mod-time for anything
+ // that depends on this file-task will be the current time
catch (e) {
modTime = new Date();
}
@@ -310,6 +320,8 @@ jake = new function () {
if (invocation) {
name = invocation.taskName;
args = invocation.args;
+ stats = null;
+ modTime = null;
_taskIndex++;
@@ -328,51 +340,55 @@ jake = new function () {
// Flag this one as done, no repeatsies
task.done = true;
- if (task instanceof FileTask) {
+ // File/dir tasks
+ if (isFileOrDirectory(task)) {
try {
stats = fs.statSync(task.name);
modTime = stats.ctime;
}
catch (e) {
- // Assume there's a task to fall back to to generate the file
+ // Doesn't exist; we'll be running the task to generate it
}
- // Compare mod-time of all the prereqs with the mod-time of this task
- if (prereqs.length) {
- actionRan = false;
+ // If the file/dir exists, compare mod-time of all the prereqs
+ // with its mod-time
+ if (stats && prereqs.length) {
+ runAction = false;
for (var i = 0, ii = prereqs.length; i < ii; i++) {
prereqName = prereqs[i];
prereqTask = this.getTask(prereqName);
// Run the action if:
- // 1. The prereq is a normal task
- // 2. A file/directory task with a mod-date more recent than
- // the one for this file (or this file doesn't exist yet)
- if ((prereqTask && !(prereqTask instanceof FileTask || prereqTask instanceof DirectoryTask))
- || (!modTime || _modTimes[prereqName] >= modTime)) {
- actionRan = true;
- if (typeof task.action == 'function') {
- task.action.apply(task, args || []);
+ // 1. The prereq is a normal task (not file/dir)
+ // 2. The prereq is a file-task with a mod-date more recent than
+ // the one for this file/dir
+ if (prereqTask) {
+ if (!isFileOrDirectory(prereqTask) ||
+ (isFile(prereqTask) && prereqIsNewerThan(prereqTask, modTime))) {
+ runAction = true;
+ break;
}
- break;
}
}
}
+ // File/dir doesn't exist, or has no prereqs -- only run if it doesn't exist
else {
- if (typeof task.action == 'function') {
- actionRan = true;
- task.action.apply(task, args || []);
- modTime = new Date();
- }
+ runAction = !stats;
}
- _modTimes[name] = modTime;
+ // Run the action if we should and can
+ if (runAction && typeof task.action == 'function') {
+ task.action.apply(task, args || []);
+ }
- // Async tasks whose action has actually run call this themselves
- if (!task.async || !actionRan) {
+ // Kick the queue if this is a sync task, or the action didn't have to run
+ // Async tasks will call this themselves
+ if (!task.async || !runAction) {
complete();
}
}
+
+ // Regular tasks
else {
// Run this mofo
if (typeof task.action == 'function') {
View
@@ -113,23 +113,26 @@ namespace('fileTest', function () {
desc('File task, async creation with child_process.exec');
file('foo/src1.txt', function () {
fs.writeFile('foo/src1.txt', 'src1', function (err) {
+ if (err) {
+ throw err;
+ }
console.log('fileTest:foo/src1.txt task');
complete();
});
}, {async: true});
desc('File task, sync creation with writeFileSync');
- file({'foo/src2.txt': 'default'}, function () {
+ file('foo/src2.txt', ['default'], function () {
fs.writeFileSync('foo/src2.txt', 'src2');
console.log('fileTest:foo/src2.txt task');
});
desc('File task, do not run unless the prereq file changes');
- file({'foo/src2-foo.txt': ['fileTest:foo', 'fileTest:foo/src2.txt']}, function () {
- console.log('fileTest:foo/src2-foo.txt task');
- var data = fs.readFileSync('foo/src2.txt');
- fs.writeFileSync('foo/src2-foo.txt', data);
- });
+ file('foo/from-src1.txt', ['fileTest:foo', 'fileTest:foo/src1.txt'], function () {
+ console.log('fileTest:foo/from-src1.txt task');
+ var data = fs.readFileSync('foo/src1.txt');
+ fs.writeFileSync('foo/from-src1.txt', data);
+ }, {async: true});
});
View
@@ -24,6 +24,15 @@ var tests = new (function () {
});
};
+ this.testNoPrereqChange = function () {
+ h.exec('../bin/cli.js fileTest:foo/from-src2.txt', function (out) {
+ console.log(out);
+ h.exec('../bin/cli.js fileTest:foo/from-src2.txt', function (out) {
+ console.log(out);
+ });
+ });
+ };
+
})();
h.run(tests, function () {

0 comments on commit 9cb8143

Please sign in to comment.