module.exports = function(grunt) {
var path = require('path'),
tasks = {},
- cwd = process.env.PWD || process.cwd();
+ cwd = process.env.PWD || process.cwd(),
+ async = require('async'),
+ DOMParser = require('xmldom').DOMParser,
+ xpath = require('xpath');
// Windows users can't run grunt in a subdirectory, so allow them to set
// the root by passing --root=path/to/dir.
return destPath;
};
+ /**
+ * Find thirdpartylibs.xml and generate an array of paths contained within
+ * them (used to generate ignore files and so on).
+ *
+ * @return {array} The list of thirdparty paths.
+ */
+ var getThirdPartyPathsFromXML = function() {
+ var thirdpartyfiles = grunt.file.expand('*/**/thirdpartylibs.xml');
+ var libs = ['node_modules/', 'vendor/'];
+
+ thirdpartyfiles.forEach( function(file) {
+ var dirname = path.dirname(file);
+
+ var doc = new DOMParser().parseFromString(grunt.file.read(file));
+ var nodes = xpath.select("/libraries/library/location/text()", doc);
+
+ nodes.forEach(function(node) {
+ var lib = path.join(dirname, node.toString());
+ if (grunt.file.isDir(lib)) {
+ // Ensure trailing slash on dirs.
+ lib = lib.replace(/\/?$/, '/');
+ }
+
+ // Look for duplicate paths before adding to array.
+ if (libs.indexOf(lib) === -1) {
+ libs.push(lib);
+ }
+ });
+ });
+ return libs;
+ };
+
+ // An array of paths to third party directories.
+ var thirdPartyPaths = getThirdPartyPathsFromXML();
+
+ /**
+ * Determine if the file is a Moodle file, or its listed in
+ * the thirdpartylibs.xml file paths as a third party file.
+ *
+ * @param {string} file The file path to determine if thirdparty
+ * @return {bool} false If thid party file.
+ */
+ var isMoodleFile = function(file) {
+ if (grunt.file.isMatch(thirdPartyPaths, file)) {
+ return false;
+ }
+ return true;
+ };
+
// Project configuration.
grunt.initConfig({
jshint: {
amd: { src: amdSrc }
},
eslint: {
- // Even though warnings dont stop the build we don't display warnings by default because:
- // * At this moment we've got too many core warnings
- // * It will complain about ignored files (https://github.com/sindresorhus/grunt-eslint/issues/119)
- // * It's better experience to use editor integrations or eslint natively
+ // Even though warnings dont stop the build we don't display warnings by default because
+ // at this moment we've got too many core warnings.
options: { quiet: !grunt.option('show-lint-warnings') },
// Check AMD files. We add some stricter rules which we can't apply to the default configuration due
// to YUI rollups.
amd: {
src: amdSrc,
+ filter: isMoodleFile,
options: { rules: {'no-undef': 'error', 'no-unused-vars': 'error', 'no-empty': 'error', 'no-unused-expressions': 'error'} }
},
// Check YUI module source files.
yui: {
- src: ['**/yui/src/**/*.js']
+ src: ['**/yui/src/**/*.js', '!*/**/yui/src/*/meta/*.js'],
+ filter: isMoodleFile
}
},
uglify: {
}
});
+ /**
+ * Generate ignore files (utilising thirdpartylibs.xml data)
+ */
+ tasks.ignorefiles = function() {
+ // Generate .eslintignore.
+ var eslintIgnores = ['# Generated by "grunt ignorefiles"', '*/**/yui/src/*/meta/', '*/**/build/'].concat(thirdPartyPaths);
+ grunt.file.write('.eslintignore', eslintIgnores.join('\n'));
+ };
+
/**
* Shifter task. Is configured with a path to a specific file or a directory,
* in the case of a specific file it will work out the right module to be built.
* so be careful to to call done().
*/
tasks.shifter = function() {
- var async = require('async'),
- done = this.async(),
+ var done = this.async(),
options = grunt.config('shifter.options');
// Run the shifter processes one at a time to avoid confusing output.
// Register JS tasks.
grunt.registerTask('shifter', 'Run Shifter against the current directory', tasks.shifter);
+ grunt.registerTask('ignorefiles', 'Generate ignore files for linters', tasks.ignorefiles);
grunt.registerTask('yui', ['eslint:yui', 'shifter']);
grunt.registerTask('amd', ['eslint:amd', 'jshint', 'uglify']);
grunt.registerTask('js', ['amd', 'yui']);