From 7ffe2b342223307bec8a4c9cfa480443753281d4 Mon Sep 17 00:00:00 2001 From: Martin Date: Sun, 19 Jun 2016 15:15:17 +0500 Subject: [PATCH 1/2] add failing test to demonstrate #1436 --- test/grunt/config_test.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/grunt/config_test.js b/test/grunt/config_test.js index 6da5422e2..cb99faf23 100644 --- a/test/grunt/config_test.js +++ b/test/grunt/config_test.js @@ -18,6 +18,7 @@ exports.config = { bar: 'bar', arr: ['foo', '<%= obj.foo2 %>'], arr2: ['<%= arr %>', '<%= obj.Arr %>'], + arr3: ['<%= meta %>'], buffer: new Buffer('test'), }); done(); @@ -61,7 +62,7 @@ exports.config = { test.done(); }, 'config.get': function(test) { - test.expect(10); + test.expect(13); test.equal(grunt.config.get('foo'), 'bar', 'Should process templates.'); test.equal(grunt.config.get('foo2'), 'bar', 'Should process templates recursively.'); test.equal(grunt.config.get('obj.foo2'), 'bar', 'Should process deeply nested templates recursively.'); @@ -73,6 +74,9 @@ exports.config = { var buf = grunt.config.get('buffer'); test.ok(Buffer.isBuffer(buf), 'Should retrieve Buffer instances as Buffer.'); test.deepEqual(buf, new Buffer('test'), 'Should return buffers as-is.'); + test.deepEqual(grunt.config.get('arr3.0'), {foo: 'bar', baz: [1, 2, 3]}); + test.deepEqual(grunt.config.get('arr3.0').foo, 'bar'); + test.deepEqual(grunt.config.get('arr3.0.foo'), 'bar'); test.done(); }, 'config.set': function(test) { From 89da42d4a5888217b967dde6cbf2a1cde78862c4 Mon Sep 17 00:00:00 2001 From: Martin Date: Sun, 19 Jun 2016 21:41:09 +0500 Subject: [PATCH 2/2] fix(config.get): process intermediate templates in path --- lib/grunt/config.js | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/grunt/config.js b/lib/grunt/config.js index ef2bf8094..8249a2e3b 100644 --- a/lib/grunt/config.js +++ b/lib/grunt/config.js @@ -43,7 +43,28 @@ 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)); + var props = getParts(config.getPropString(prop)); + var currentData = config.data; + // from https://github.com/cowboy/node-getobject/blob/master/lib/getobject.js + // Split strings on dot, but only if dot isn't preceded by a backslash. Since + // JavaScript doesn't support lookbehinds, use a placeholder for "\.", split + // on dot, then replace the placeholder character with a dot. + function getParts(str) { + return str.replace(/\\\./g, '\uffff').split('.').map(function(s) { + return s.replace(/\uffff/g, '.'); + }); + } + + props.forEach(function(item) { + currentData = currentData[item]; + // if current value is template -- expand it + if (typeof currentData === 'string' && + currentData.match(propStringTmplRe)) { + currentData = config.process(currentData); + } + }); + + return config.process(currentData); }; // Expand a config value recursively. Used for post-processing raw values