UNPKG

3.87 kBJavaScriptView Raw
1/*
2 * grunt
3 * https://github.com/cowboy/grunt
4 *
5 * Copyright (c) 2012 "Cowboy" Ben Alman
6 * Licensed under the MIT license.
7 * http://benalman.com/about/license/
8 */
9
10var grunt = require('../grunt');
11
12// The actual config data.
13var data;
14
15// Get/set config data. If data hasn't been set, return null. If value was
16// passed, set value. If props string wasn't passed, return all data. Otherwise,
17// return the prop's value.
18var config = module.exports = function(prop, value) {
19 if (arguments.length === 2) {
20 // Two arguments were passed, set the property's value.
21 return config.set(prop, value);
22 } else {
23 // Get the property's value (or the entire data object).
24 return config.get(prop);
25 }
26};
27
28// If prop is an array, convert it to a props string.
29function getPropString(prop) {
30 if (grunt.utils.kindOf(prop) === 'array') {
31 return prop.map(config.escape).join('.');
32 }
33 return prop;
34}
35
36// Recursively expand config directives.
37function processDirectives() {
38 // These directives should be processed now.
39 var toProcess = ['config', 'json'];
40 data = grunt.utils.recurse(data, function(value) {
41 if (typeof value !== 'string') { return value; }
42 var parts = grunt.task.getDirectiveParts(value) || [];
43 return toProcess.indexOf(parts[0]) !== -1 ? grunt.task.directive(value) : value;
44 });
45}
46
47// Get config data.
48config.get = function(prop) {
49 // Abort if no config data exists.
50 if (!data) { return null; }
51 // If prop is an array, convert it to a prop string.
52 prop = getPropString(prop);
53
54 if (prop) {
55 // A property string/array was passed, get that property's value.
56 return grunt.utils.namespace.get(data, prop);
57 } else {
58 // Nothing was passed. Return a shalow clone of the actual config data.
59 return grunt.utils._.clone(data);
60 }
61};
62
63// Set config data.
64config.set = function(prop, value) {
65 // Abort if no config data exists.
66 if (!data) { return null; }
67 // If prop is an array, convert it to a prop string.
68 prop = getPropString(prop);
69 // Set the property's value.
70 var result = grunt.utils.namespace.set(data, prop, value);
71 // Process directives.
72 processDirectives();
73 // Return result.
74 return result;
75};
76
77// Get config data, processing it as a template if necessary.
78config.process = function(prop) {
79 return grunt.utils.recurse(config.get(prop), function(value) {
80 if (typeof value !== 'string') { return value; }
81 return grunt.template.process(value, data);
82 });
83};
84
85// Initialize config data.
86config.init = function(obj) {
87 grunt.verbose.write('Initializing config...').ok();
88 // Initialize data.
89 data = obj || {};
90 // Process directives.
91 processDirectives();
92 // Return data.
93 return data;
94};
95
96// Escape any . in name with \. so dot-based namespacing works properly.
97config.escape = function(str) {
98 return str.replace(/\./g, '\\.');
99};
100
101// Test to see if required config params have been defined. If not, throw an
102// exception (use this inside of a task).
103config.requires = function() {
104 var p = grunt.utils.pluralize;
105 var props = grunt.utils.toArray(arguments).map(getPropString);
106 var msg = 'Verifying propert' + p(props.length, 'y/ies') +
107 ' ' + grunt.log.wordlist(props) + ' exist' + p(props.length, 's') +
108 ' in config...';
109 grunt.verbose.write(msg);
110 var failProps = data && props.filter(function(prop) {
111 return config.get(prop) === undefined;
112 }).map(function(prop) {
113 return '"' + prop + '"';
114 });
115 if (data && failProps.length === 0) {
116 grunt.verbose.ok();
117 return true;
118 } else {
119 grunt.verbose.or.write(msg);
120 grunt.log.error().error('Unable to process task.');
121 if (!data) {
122 throw grunt.task.taskError('Unable to load config.');
123 } else {
124 throw grunt.task.taskError('Required config propert' +
125 p(failProps.length, 'y/ies') + ' ' + failProps.join(', ') +
126 ' missing.');
127 }
128 }
129};