grunt-asset-compress
Version:
A lightweight plugin that makes sure your asset_compress does not contain duplicates!
185 lines (147 loc) • 5.51 kB
JavaScript
var parser = require('node-file-parser');
var fs = require('fs');
module.exports = function(grunt) {
'use strict';
var errors = 0;
var warnings = 0;
var default_options = {
src: undefined,
groups: undefined,
generated: [],
alias: {}
};
var options = default_options;
function prepare() {
errors = 0;
warnings = 0;
options = this.options(default_options);
if (!options.src || (typeof options.src !== 'string' && !(options.src instanceof String))) {
errors++;
grunt.fail.fatal('The value of options.src is invalid!');
}
if (!options.groups) {
errors++;
grunt.fail.fatal('The vaue of options.groups is invalid');
}
return !errors;
}
function skip(testname, previous) {
warnings++;
var base = '"%s": Duplicate of "%s"';
var message = template(base, testname, previous);
return grunt.verbose.ok(message);
}
function duplicate(testname, sectionA, sectionB, file) {
errors++;
var base = sectionA === sectionB
? '"%s": Duplicate definition of "%s" in section "%s"'
: '"%s": Duplicate definition of "%s" in sections "%s" and "%s"';
var message = template(base, testname, file, sectionA, sectionB);
return grunt.log.error('ERROR ', message);
}
function notFound(testname, section) {
errors++;
var base = '"%s": Could not find section "%s"';
var message = template(base, testname, section);
return grunt.log.error('ERROR ' + message);
}
function notFoundFile(testname, section, file) {
var base = '"%s": Could not find file "%s" in section "%s"';
var message = template(base, testname, file, section);
if (options.generated.indexOf(file) >= 0) {
warnings++;
grunt.log.writeln('WARNING ' + message);
} else {
errors++;
grunt.log.error('ERROR ' + message);
}
}
function template(message) {
for (var i = 1; i < arguments.length; i++) {
message = message.replace('%s', arguments[i]);
}
return message;
}
function run() {
if (prepare.call(this)) {
test();
}
if (errors) {
grunt.fail.warn(template('Finished with a total of %s errors and %s warnings!', errors, warnings));
} else if (warnings) {
grunt.log.error(template('Finished successfully with a total of %s warnings!', warnings));
}
}
function test() {
var assets = parser.link(options.src);
var data = assets.read().getContent().section;
var aliases = Object.keys(options.alias);
var tests = (function validate(result, groups, namespace) {
Object.keys(groups).forEach(function(key) {
var group = groups[key];
if (group instanceof Array) {
result[namespace + key] = group;
} else if (typeof group === 'string' || group instanceof String) {
result[namespace + key] = Array(group);
} else {
validate(result, group, namespace + key + '.');
}
});
return result;
}({}, options.groups, ''));
var done = {};
var checkedExistence = {};
function checkExistence(testname, section, file) {
if (checkedExistence[file]) {
return;
}
var success = false;
var type = (/\.(\w*)$/).exec(file)[1];
var paths = data[type].paths;
for (var i = 0; i < paths.length; i++) {
var path = paths[i];
var _file = path.replace('/*', '/') + file;
aliases.forEach(function(alias) {
_file = _file.replace(alias, options.alias[alias]);
});
try {
checkedExistence[_file] = 1;
fs.accessSync(_file, fs.F_OK);
success = true;
break;
} catch
(exception) {
}
}
if (!success) {
notFoundFile(testname, section, file);
}
}
Object.keys(tests).forEach(function(testname) {
var test = tests[testname];
var list = {};
if (done[test]) {
return skip(testname, done[test]);
} else {
done[test] = testname;
}
test.forEach(function(section) {
var files = data[section];
if (!files) {
return notFound(testname, section);
}
files.files.forEach(function parse(file) {
if (files[file] instanceof Array) {
files[file].forEach(parse);
} else if (list[file]) {
return duplicate(testname, section, list[file], file);
} else {
list[file] = section;
checkExistence(testname, section, file);
}
});
});
});
}
grunt.registerTask('asset_compress', 'Makes sure your asset_compress file has no duplicates!', run);
};