/* * grunt * http://gruntjs.com/ * * Copyright (c) 2013 "Cowboy" Ben Alman * Licensed under the MIT license. * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT */ 'use strict'; var grunt = require('../grunt'); // Get/set config data. If value was passed, set. Otherwise, get. var config = module.exports = function(prop, value) { if (arguments.length === 2) { // Two arguments were passed, set the property's value. return config.set(prop, value); } else { // Get the property's value (or the entire data object). return config.get(prop); } }; // The actual config data. config.data = {}; // Escape any . in name with \. so dot-based namespacing works properly. config.escape = function(str) { return str.replace(/\./g, '\\.'); }; // Return prop as a string. config.getPropString = function(prop) { return Array.isArray(prop) ? prop.map(config.escape).join('.') : prop; }; // Get raw, unprocessed config data. config.getRaw = function(prop) { if (prop) { // Prop was passed, get that specific property's value. return grunt.util.namespace.get(config.data, config.getPropString(prop)); } else { // No prop was passed, return the entire config.data object. return config.data; } }; // Match '<%= FOO %>' where FOO is a propString, eg. foo or foo.bar but not // a method call like foo() or foo.bar(). var propStringTmplRe = /^<%=\s*([a-z0-9_$]+(?:\.[a-z0-9_$]+)*)\s*%>$/i; // Get config data, recursively processing templates. config.get = function(prop) { return config.process(config.getRaw(prop)); }; // Expand a config value recursively. Used for post-processing raw values // already retrieved from the config. config.process = function(raw) { return grunt.util.recurse(raw, function(value) { // If the value is not a string, return it. if (typeof value !== 'string') { return value; } // If possible, access the specified property via config.get, in case it // doesn't refer to a string, but instead refers to an object or array. var matches = value.match(propStringTmplRe); var result; if (matches) { result = config.get(matches[1]); // If the result retrieved from the config data wasn't null or undefined, // return it. if (result != null) { return result; } } // Process the string as a template. return grunt.template.process(value, {data: config.data}); }); }; // Set config data. config.set = function(prop, value) { return grunt.util.namespace.set(config.data, config.getPropString(prop), value); }; // Initialize config data. config.init = function(obj) { grunt.verbose.write('Initializing config...').ok(); // Initialize and return data. return (config.data = obj || {}); }; // Test to see if required config params have been defined. If not, throw an // exception (use this inside of a task). config.requires = function() { var p = grunt.util.pluralize; var props = grunt.util.toArray(arguments).map(config.getPropString); var msg = 'Verifying propert' + p(props.length, 'y/ies') + ' ' + grunt.log.wordlist(props) + ' exist' + p(props.length, 's') + ' in config...'; grunt.verbose.write(msg); var failProps = config.data && props.filter(function(prop) { return config.get(prop) == null; }).map(function(prop) { return '"' + prop + '"'; }); if (config.data && failProps.length === 0) { grunt.verbose.ok(); return true; } else { grunt.verbose.or.write(msg); grunt.log.error().error('Unable to process task.'); if (!config.data) { throw grunt.util.error('Unable to load config.'); } else { throw grunt.util.error('Required config propert' + p(failProps.length, 'y/ies') + ' ' + failProps.join(', ') + ' missing.'); } } };