You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
124 lines
3.2 KiB
124 lines
3.2 KiB
let fs = require('fs'); |
|
let Task = require('./task').Task; |
|
|
|
function isFileOrDirectory(t) { |
|
return (t instanceof FileTask || |
|
t instanceof DirectoryTask); |
|
} |
|
|
|
function isFile(t) { |
|
return (t instanceof FileTask && !(t instanceof DirectoryTask)); |
|
} |
|
|
|
/** |
|
@name jake |
|
@namespace jake |
|
*/ |
|
/** |
|
@name jake.FileTask |
|
@class` |
|
@extentds Task |
|
@description A Jake FileTask |
|
|
|
@param {String} name The name of the Task |
|
@param {Array} [prereqs] Prerequisites to be run before this task |
|
@param {Function} [action] The action to perform to create this file |
|
@param {Object} [opts] |
|
@param {Array} [opts.asyc=false] Perform this task asynchronously. |
|
If you flag a task with this option, you must call the global |
|
`complete` method inside the task's action, for execution to proceed |
|
to the next task. |
|
*/ |
|
class FileTask extends Task { |
|
constructor(...args) { |
|
super(...args); |
|
this.dummy = false; |
|
if (fs.existsSync(this.name)) { |
|
this.updateModTime(); |
|
} |
|
else { |
|
this.modTime = null; |
|
} |
|
} |
|
|
|
isNeeded() { |
|
let prereqs = this.prereqs; |
|
let prereqName; |
|
let prereqTask; |
|
|
|
// No repeatsies |
|
if (this.taskStatus == Task.runStatuses.DONE) { |
|
return false; |
|
} |
|
// The always-make override |
|
else if (jake.program.opts['always-make']) { |
|
return true; |
|
} |
|
// Default case |
|
else { |
|
|
|
// We need either an existing file, or an action to create one. |
|
// First try grabbing the actual mod-time of the file |
|
try { |
|
this.updateModTime(); |
|
} |
|
// Then fall back to looking for an action |
|
catch(e) { |
|
if (typeof this.action == 'function') { |
|
return true; |
|
} |
|
else { |
|
throw new Error('File-task ' + this.fullName + ' has no ' + |
|
'existing file, and no action to create one.'); |
|
} |
|
} |
|
|
|
// Compare mod-time of all the prereqs with its mod-time |
|
// If any prereqs are newer, need to run the action to update |
|
if (prereqs && prereqs.length) { |
|
for (let i = 0, ii = prereqs.length; i < ii; i++) { |
|
prereqName = prereqs[i]; |
|
prereqTask = this.namespace.resolveTask(prereqName) || |
|
jake.createPlaceholderFileTask(prereqName, this.namespace); |
|
// Run the action if: |
|
// 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) && prereqTask.modTime > this.modTime)) { |
|
return true; |
|
} |
|
} |
|
} |
|
} |
|
// File/dir has no prereqs, and exists -- no need to run |
|
else { |
|
// Effectively done |
|
this.taskStatus = Task.runStatuses.DONE; |
|
return false; |
|
} |
|
} |
|
} |
|
|
|
updateModTime() { |
|
let stats = fs.statSync(this.name); |
|
this.modTime = stats.mtime; |
|
} |
|
|
|
complete() { |
|
if (!this.dummy) { |
|
this.updateModTime(); |
|
} |
|
// Hackity hack |
|
Task.prototype.complete.apply(this, arguments); |
|
} |
|
|
|
} |
|
|
|
exports.FileTask = FileTask; |
|
|
|
// DirectoryTask is a subclass of FileTask, depends on it |
|
// being defined |
|
let DirectoryTask = require('./directory_task').DirectoryTask; |
|
|
|
|