diff --git a/Gruntfile.js b/Gruntfile.js index 6639f3f..947c7c6 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -67,6 +67,21 @@ module.exports = function (grunt) { files: { 'tmp/assignToVar.js': ['test/fixtures/default.js'] } + }, + dynamicReplacement: { + options: { + vars: { + FOO_BAR: { + key: 'foo.bar', + callback : function(newV, oldV) { + return oldV + ' ' + newV; + } + } + } + }, + files: { + 'tmp/dynamicReplacement.js': ['test/fixtures/default.js'] + } } }, @@ -90,7 +105,7 @@ module.exports = function (grunt) { // Whenever the "test" task is run, first clean the "tmp" dir, then run this // plugin's task(s), then test the result. - grunt.registerTask('test', ['env:default', 'clean', 'envtojson', 'nodeunit', ]); + grunt.registerTask('test', ['env:default', 'clean', 'envtojson', 'nodeunit', 'clean']); // By default, lint and run all tests. grunt.registerTask('default', ['jshint', 'test']); diff --git a/tasks/envToJson.js b/tasks/envToJson.js index 10b9ab6..a3665e2 100644 --- a/tasks/envToJson.js +++ b/tasks/envToJson.js @@ -21,7 +21,7 @@ module.exports = function (grunt) { // Merge task-specific and/or target-specific options with these defaults. options = this.options({ vars: {}, - assignToVar: 'module.exports', + assignToVar: false, whiteSpace: 4 }); @@ -38,43 +38,53 @@ module.exports = function (grunt) { }).map(function (filepath) { // Read file source. var modulePath = path.resolve(filepath); - var js = require(modulePath); - writeFile(f, JSON.stringify(updateValues(js, options.vars), null, (options.whiteSpace)), options.assignToVar); + var js = _.clone(require(modulePath), true); + writeFile(f.dest, JSON.stringify(updateValues(js, options.vars), null, (options.whiteSpace)), options.assignToVar); }); }); }); var updateValues = function (js, vars) { - _.each(vars, function (path, key) { + _.each(vars, function (replace, key) { var val = process.env[key]; if (val) { - js = updateValue(js, path.split('.'), val) || js; + var keyPath, cb; + if (typeof replace === 'string') { + keyPath = replace; + cb = function(newV, oldV) { + return newV; + }; + } else { + keyPath = replace.key; + cb = replace.callback; + } + js = updateValue(js, keyPath.split('.'), _.bind(cb, this, val)) || js; } }); return js; }; - var updateValue = function (object, segments, val) { + var updateValue = function (object, segments, cb) { if (object && segments.length) { var segment = segments.shift(); if (segments.length === 0) { - object[segment] = val; + object[segment] = cb(object[segment]); return object; } else { - object[segment] = updateValue((object[segment] || {}), segments, val); + object[segment] = updateValue((object[segment] || {}), segments, cb); return object; } } }; - var writeFile = function(file, content, assignToVar) { + var writeFile = function(dest, content, assignToVar) { if (assignToVar) { content = _.template("<%=assignToVar%>=<%=content%>;")({ content: content, assignToVar: assignToVar }); } - grunt.file.write(file.dest, content); + grunt.file.write(dest, content); }; }; diff --git a/test/envToJson_test.js b/test/envToJson_test.js index 2fca94b..187eb35 100644 --- a/test/envToJson_test.js +++ b/test/envToJson_test.js @@ -55,6 +55,16 @@ exports.envtojson = { var expected = grunt.file.read('test/expected/noWhiteSpace.js'); test.equal(actual, expected, 'plain javascript object with altered/created keys no whitespace output'); + test.done(); + }, + + dynamic: function(test) { + test.expect(1); + + var actual = grunt.file.read('tmp/dynamicReplacement.js'); + var expected = grunt.file.read('test/expected/dynamicReplacement.js'); + test.equal(actual, expected, 'plain javascript object with first key dynamically altered'); + test.done(); } }; diff --git a/test/expected/default.js b/test/expected/default.js index 4097741..47d9825 100644 --- a/test/expected/default.js +++ b/test/expected/default.js @@ -1,4 +1,4 @@ -module.exports={ +{ "foo": { "bar": "altered" }, @@ -13,4 +13,4 @@ module.exports={ "stones": "newProp" } } -}; \ No newline at end of file +} \ No newline at end of file diff --git a/test/expected/dynamicReplacement.js b/test/expected/dynamicReplacement.js new file mode 100644 index 0000000..c114b3b --- /dev/null +++ b/test/expected/dynamicReplacement.js @@ -0,0 +1,11 @@ +{ + "foo": { + "bar": "howdy altered" + }, + "spam": { + "eggs": { + "parrot": "grail" + } + }, + "beer": "good" +} \ No newline at end of file diff --git a/test/expected/noWhiteSpace.js b/test/expected/noWhiteSpace.js index b9b191f..206e0e5 100644 --- a/test/expected/noWhiteSpace.js +++ b/test/expected/noWhiteSpace.js @@ -1 +1 @@ -module.exports={"foo":{"bar":"altered"},"spam":{"eggs":{"parrot":"altered"}},"beer":"altered","one":{"hundred":{"stones":"newProp"}}}; \ No newline at end of file +{"foo":{"bar":"altered"},"spam":{"eggs":{"parrot":"altered"}},"beer":"altered","one":{"hundred":{"stones":"newProp"}}} \ No newline at end of file