UNPKG

task-master

Version:

A helper to make Grunt task declaration and organization cleaner.

133 lines (115 loc) 3.74 kB
var _ = require('lodash'); var loader = require('./loader'); var fm = require('file-manifest'); var extend = require('config-extend'); /** * Gets the options, either passed in or from a file * @param {string} root - The project root * @param {string|Object} opts - An options object, a file path for opts, or null */ exports.buildOpts = function(root, opts) { opts = opts || {}; var tasks = opts.tasks = opts.tasks || [ 'tasks' ]; // Load options etc. from files if they are strings opts = loader.load('opts', opts, root, tasks, true); opts.context = loader.load('context', opts.context, root, tasks); opts.alias = loader.load('alias', opts.alias, root, tasks); return exports.merge(opts); }; /** * Merge the options object with the defaults * @param {Object} opts - The option overrides */ exports.merge = function(opts) { // Merge efault options var options = _.extend({}, { devDependencies: true, dependencies: false, optionalDependencies: false, peerDependencies: false, pattern: /^grunt-/, include: [], exclude: [], ignore: [], tasks: ['tasks'] }, opts); // Make sure pattern is a regex if (!_.isRegExp(options.pattern)) { options.pattern = new RegExp(options.pattern); } // Make string options into arrays _.each(['tasks', 'include', 'exclude', 'ignore'], function(key) { options[key] = _.isArray(options[key]) ? options[key] : [options[key]]; }); return options; }; /** * Build the grunt configuration * @param {string} root - The project root * @param {Object} options - Task-master options * @param {Object} grunt - Grunt */ exports.buildConfig = function(root, options, grunt) { var config = {}; // Assign context keys directly to config for (var k in (options.context || {})) { config[k] = options.context[k]; } // Add any ignored files to the file-manifest pattern var patterns = ['**/*.{js,coffee,json,yml}', '!**/_*.*']; _.each(options.ignore, function(file) { patterns.push('!' + file); }); // Iterate over each task directory and build out // the grunt config using the results _.each(options.tasks, function(dir) { config = fm.generate(root + '/' + dir, { memo: config, match: patterns, reduce: function(manifest, file) { // Get main task config var contents = loader.get(file.abs(), grunt, manifest); // Get any config overrides var name = file.name(); var overrides = loader.load('override.' + name, null, root, [dir]); if (contents) { // Assign task configuration, recursively, to main config object exports.assignManifest(name, contents, manifest); } // Override configuration if provided var overrideConfig = {}; if (!_.isEmpty(overrides)) { overrideConfig[name] = overrides; } // Merge the overrides into the main config. return extend(manifest, overrideConfig); } }); }); return config; }; /** * Handles files of the type <task>.<target>.js * @param {String} name - The file name * @param {Object} contents - The file configuration * @param {Object} manifest - The current config manifest */ exports.assignManifest = function(name, contents, manifest) { var parts = name.split('.'); var task = parts[0]; var target = parts[1]; var obj = {}; // If we have a target-specific file, make a new object // with that key, otherwise use the whole config if (target) { obj[target] = contents; } else { obj = contents; } // If this task already exists in the config, extend if (manifest[task]) { extend(manifest[task], obj); } else { manifest[task] = obj; } };