UNPKG

grunt-ts

Version:

Compile and manage your TypeScript project

141 lines 4.89 kB
/// <reference path="../../defs/tsd.d.ts"/> // Source based on : https://github.com/tschaub/grunt-newer/blob/master/lib/util.js var fs = require('fs'); var _ = require('lodash'); var path = require('path'); var crypto = require('crypto'); var grunt = require('grunt'); var rimraf = require('rimraf'); ////////////////////// // Basic algo: // - We have a timestamp file per target. // - We use the mtime of this file to filter out // new files for this target // - Finally we can update the timestamp file with new time ///////////////////// exports.cacheDir = '.tscache'; ////////////////////////////// // File stamp based filtering ////////////////////////////// function getStampPath(targetName) { return path.join(exports.cacheDir, targetName, 'timestamp'); } function getLastSuccessfullCompile(targetName) { var stampFile = getStampPath(targetName); try { return fs.statSync(stampFile).mtime; } catch (err) { // task has never succeeded before return new Date(0); } } function getFilesNewerThan(paths, time) { var filtered = _.filter(paths, function (path) { var stats = fs.statSync(path); return stats.mtime > time; }); return filtered; } function anyNewerThan(paths, time) { return getFilesNewerThan(paths, time).length > 0; } exports.anyNewerThan = anyNewerThan; function filterPathsByTime(paths, targetName) { var time = getLastSuccessfullCompile(targetName); return getFilesNewerThan(paths, time); } exports.filterPathsByTime = filterPathsByTime; ////////////////////////////// // File hash based filtering ////////////////////////////// /** * Get path to cached file hash for a target. * @return {string} Path to hash. */ function getHashPath(filePath, targetName) { var hashedName = path.basename(filePath) + '-' + crypto.createHash('md5').update(filePath).digest('hex'); return path.join(exports.cacheDir, targetName, 'hashes', hashedName); } /** * Get an existing hash for a file (if it exists). */ function getExistingHash(filePath, targetName) { var hashPath = getHashPath(filePath, targetName); var exists = fs.existsSync(hashPath); if (!exists) { return null; } return fs.readFileSync(hashPath).toString(); } /** * Generate a hash (md5sum) of a file contents. * @param {string} filePath Path to file. */ function generateFileHash(filePath) { var md5sum = crypto.createHash('md5'); var data = fs.readFileSync(filePath); md5sum.update(data); return md5sum.digest('hex'); } /** * Filter files based on hashed contents. * @param {Array.<string>} paths List of paths to files. * @param {string} cacheDir Cache directory. * @param {string} taskName Task name. * @param {string} targetName Target name. * @param {function(Error, Array.<string>)} callback Callback called with any * error and a filtered list of files that only includes files with hashes * that are different than the cached hashes for the same files. */ function filterPathsByHash(filePaths, targetName) { var filtered = _.filter(filePaths, function (filePath) { var previous = getExistingHash(filePath, targetName); var current = generateFileHash(filePath); return previous !== current; }); return filtered; } function updateHashes(filePaths, targetName) { _.forEach(filePaths, function (filePath) { var hashPath = getHashPath(filePath, targetName); var hash = generateFileHash(filePath); grunt.file.write(hashPath, hash); }); } ////////////////////////////// // External functions ////////////////////////////// /** * Filter a list of files by target */ function getNewFilesForTarget(paths, targetName) { var step1 = filterPathsByTime(paths, targetName); var step2 = filterPathsByHash(step1, targetName); return step2; } exports.getNewFilesForTarget = getNewFilesForTarget; /** * Update the timestamp for a target to denote last successful compile */ function compileSuccessfull(paths, targetName) { // update timestamp grunt.file.write(getStampPath(targetName), ''); // update filehash updateHashes(paths, targetName); } exports.compileSuccessfull = compileSuccessfull; function clearCache(targetName) { var cacheDirForTarget = path.join(exports.cacheDir, targetName); try { if (fs.existsSync(cacheDirForTarget)) { rimraf.sync(cacheDirForTarget); grunt.log.writeln(('Cleared fast compile cache for target: ' + targetName).cyan); } } catch (ex) { grunt.log.writeln(('Failed to clear compile cache for target: ' + targetName).red); } } exports.clearCache = clearCache; //# sourceMappingURL=cacheUtils.js.map