node-compiler
Version:
Single page application compiler that supports a number of popular integrations.
130 lines (106 loc) • 4.57 kB
JavaScript
var Crypto = require("crypto");
var Path = require("path");
var FS = require("fs-extra");
// This function is used to cache a file once it has been created.
function cache(target, path, data) {
var cachePath = getCachePath(target, path, true);
FS.writeFileSync(cachePath, data);
};
// This function first hashes the profile name and uses it as a folder name within the cache directory. A file name made
// up of an object containing the directory and compile options is stringified and hashed to produce a file name.
function getCachePath(target, path, create, extension) {
var name = hash(target.profile.name);
var compiler = target.profile.compiler;
var profileCache = Path.join(compiler.directory, ".cache", name);
if (create) { FS.mkdirsSync(profileCache); }
var filename = JSON.stringify({dir: path, options: target.plugin.options});
var cachePath = Path.join(profileCache, hash(filename) + (extension || ".cache"));
target.logger.silent("Converted path '" + path + "' to '" + cachePath + "'.");
return cachePath;
};
// This function is used to return a cache copy of a given file path
function getCache(target, path, encoding) {
var cachePath = getCachePath(target, path);
if (FS.existsSync(cachePath) && FS.existsSync(path)) {
if (compareFileDates(cachePath, path) == cachePath) {
return FS.readFileSync(cachePath, (typeof encoding !== "undefined" ? encoding : "utf-8"));
}
FS.unlinkSync(cachePath);
}
return null;
};
function deleteCache(target, path) {
var cachePath = getCachePath(target, path);
if (FS.existsSync(cachePath)) {
FS.unlinkSync(cachePath);
}
}
function compareFileDates(fileA, fileB) {
var fileAModified = FS.statSync(fileA).mtime.getTime();
var fileBModified = FS.statSync(fileB).mtime.getTime();
return (fileAModified >= fileBModified) ? fileA : fileB;
}
function hash(value) {
var md5 = Crypto.createHash("md5")
return md5.update(value).digest("hex");
}
function checkIntegrity(cache, current) {
if (cache.length != current.length) { return false; }
for (var i = 0; i < cache.length; i += 1) {
if (cache[i] != current[i].dir) { return false; }
}
return true;
}
function diveSync(dir, filter) {
// Ensure the directory passed is valid.
if (!FS.existsSync(dir)) { return []; }
// Get a list of files and folders within the directory.
var items = FS.readdirSync(dir);
var orderItems = (items.indexOf(".order") != -1) ? FS.readFileSync(Path.join(dir, ".order"), "utf-8").split(/\r?\n/) : [];
var directories = [];
// loop through each order file cross checking with the items array for validation.
// If it's already in items, remove it else we assume that it's an invalid path.
for (var i = orderItems.length - 1; i >= 0; i--) {
var orderItem = orderItems[i];
var itemsIndex = items.indexOf(orderItem);
if (itemsIndex != -1) {
items.splice(itemsIndex, 1);
} else {
orderItems.splice(i, 1);
}
}
// Join the two arrays up with the order files first.
var files = orderItems.concat(items);
// Loop through all the files checking if it's a directory. These will later be crawled
// giving the concept of files in current directory > folders. If the file isn't a directory,
// validate it against an option filter function. If it doesn't pass, it will be removed.
for (var i = files.length - 1; i >= 0; i--) {
var file = files[i];
var path = Path.join(dir, file);
var stat = (FS.existsSync(path) ? FS.statSync(path) : null);
if (stat && stat.isDirectory()) {
directories.push(path);
files.splice(i, 1);
} else {
if (filter && !filter(path, stat)) {
files.splice(i, 1);
continue;
}
files[i] = {dir: path, date: ((stat && stat.mtime) || 0)};
}
}
// Loop through each directory to recursivly crawl the rest of the directories passing down
// the filter function if given.
directories.forEach(function(directory) {
files = files.concat(diveSync(directory, filter));
});
return files;
}
module.exports.cache = cache;
module.exports.getCachePath = getCachePath;
module.exports.getCache = getCache;
module.exports.deleteCache = deleteCache;
module.exports.compareFileDates = compareFileDates;
module.exports.hash = hash;
module.exports.checkIntegrity = checkIntegrity;
module.exports.diveSync = diveSync;