From f7e8e986389c68c72e22b61472174ce7fe24f516 Mon Sep 17 00:00:00 2001 From: Stephen Duncan Jr Date: Tue, 21 Jan 2014 11:31:05 -0800 Subject: [PATCH] Support searching and replacing for refererences to previously hashed files. --- tasks/hashresHelper.js | 43 ++++++++++++++++++++---------------------- tasks/hashresUtils.js | 34 +++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 23 deletions(-) diff --git a/tasks/hashresHelper.js b/tasks/hashresHelper.js index 43a4c5a..3032db4 100644 --- a/tasks/hashresHelper.js +++ b/tasks/hashresHelper.js @@ -12,22 +12,6 @@ var fs = require('fs'), path = require('path'), utils = require('./hashresUtils'); -function preg_quote (str, delimiter) { - // http://kevin.vanzonneveld.net - // + original by: booeyOH - // + improved by: Ates Goral (http://magnetiq.com) - // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // + bugfixed by: Onno Marsman - // + improved by: Brett Zamir (http://brett-zamir.me) - // * example 1: preg_quote("$40"); - // * returns 1: '\$40' - // * example 2: preg_quote("*RRRING* Hello?"); - // * returns 2: '\*RRRING\* Hello\?' - // * example 3: preg_quote("\\.+*?[^]$(){}=!<>|:"); - // * returns 3: '\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:' - return (str + '').replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\' + (delimiter || '') + '-]', 'g'), '\\$&'); -} - exports.hashAndSub = function(grunt, options) { var src = options.src, @@ -36,7 +20,9 @@ exports.hashAndSub = function(grunt, options) { fileNameFormat = options.fileNameFormat, renameFiles = options.renameFiles, nameToHashedName = {}, - formatter = null; + nameToNameSearch = {}, + formatter = null, + searchFormatter = null; grunt.log.debug('files: ' + options.files); grunt.log.debug('Using encoding ' + encoding); @@ -44,20 +30,28 @@ exports.hashAndSub = function(grunt, options) { grunt.log.debug(renameFiles ? 'Renaming files' : 'Not renaming files'); formatter = utils.compileFormat(fileNameFormat); + searchFormatter = utils.compileSearchFormat(fileNameFormat); if (options.files) { options.files.forEach(function(f) { f.src.forEach(function(src) { - var md5 = utils.md5(src).slice(0, 8), - fileName = path.basename(src), - lastIndex = fileName.lastIndexOf('.'), - renamed = formatter({ + var md5 = utils.md5(src).slice(0, 8), + fileName = path.basename(src), + lastIndex = fileName.lastIndexOf('.'), + renamed = formatter({ hash: md5, name: fileName.slice(0, lastIndex), - ext : fileName.slice(lastIndex + 1, fileName.length) }); + ext : fileName.slice(lastIndex + 1, fileName.length) + }), + nameSearch = searchFormatter({ + hash: /[0-9a-f]{8}/, + name: fileName.slice(0, lastIndex), + ext: fileName.slice(lastIndex + 1, fileName.length) + }); // Mapping the original name with hashed one for later use. nameToHashedName[fileName] = renamed; + nameToNameSearch[fileName] = nameSearch; // Renaming the file if (renameFiles) { @@ -71,7 +65,10 @@ exports.hashAndSub = function(grunt, options) { var destContents = fs.readFileSync(f, encoding); for (var name in nameToHashedName) { grunt.log.debug('Substituting ' + name + ' by ' + nameToHashedName[name]); - destContents = destContents.replace(new RegExp(preg_quote(name)+"(\\?[0-9a-z]+)?", "g"), nameToHashedName[name]); + destContents = destContents.replace(new RegExp(utils.preg_quote(name)+"(\\?[0-9a-z]+)?", "g"), nameToHashedName[name]); + + grunt.log.debug('Substituting ' + nameToNameSearch[name] + ' by ' + nameToHashedName[name]); + destContents = destContents.replace(new RegExp(nameToNameSearch[name], "g"), nameToHashedName[name]); } grunt.log.debug('Saving the updated contents of the outination file'); fs.writeFileSync(f, destContents, encoding); diff --git a/tasks/hashresUtils.js b/tasks/hashresUtils.js index 34192c8..149e169 100644 --- a/tasks/hashresUtils.js +++ b/tasks/hashresUtils.js @@ -11,6 +11,28 @@ var crypto = require('crypto'), fs = require('fs'); +function preg_quote (str, delimiter) { + // http://kevin.vanzonneveld.net + // + original by: booeyOH + // + improved by: Ates Goral (http://magnetiq.com) + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + bugfixed by: Onno Marsman + // + improved by: Brett Zamir (http://brett-zamir.me) + // * example 1: preg_quote("$40"); + // * returns 1: '\$40' + // * example 2: preg_quote("*RRRING* Hello?"); + // * returns 2: '\*RRRING\* Hello\?' + // * example 3: preg_quote("\\.+*?[^]$(){}=!<>|:"); + // * returns 3: '\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:' + return (str + '').replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\' + (delimiter || '') + '-]', 'g'), '\\$&'); +} + +exports.preg_quote = preg_quote; + +function escapeNonRegex(input) { + return (input instanceof RegExp) ? input.source : preg_quote(input); +} + // Generates a function for the given format // Valid format variables: ${hash}, ${name} and ${ext} exports.compileFormat = function(format) { @@ -22,6 +44,18 @@ exports.compileFormat = function(format) { }; }; +// Generates a function for the given format as a regex string +// Valid format variables: ${hash}, ${name} and ${ext} +exports.compileSearchFormat = function(format) { + format = preg_quote(format); + return function(options) { + var output = format.split('\\$\\{hash\\}').join(escapeNonRegex(options.hash)); + output = output.split('\\$\\{name\\}').join(escapeNonRegex(options.name)); + output = output.split('\\$\\{ext\\}').join(escapeNonRegex(options.ext)); + return output; + }; +}; + // Generates the md5 for the given file exports.md5 = function(filepath) { var hash = crypto.createHash('md5');