diff --git a/config-merge.js b/config-merge.js index 4b468df..24f88e7 100644 --- a/config-merge.js +++ b/config-merge.js @@ -1,6 +1,6 @@ const fs = require('fs') const glob = require('glob') -const merge = require('lodash.merge') +const mergeWith = require('lodash.mergewith') const path = require('path') const YAML = require('yaml') const toml = require('toml-j0.4') @@ -20,6 +20,7 @@ const envReserved = new Set(["_", "SHLVL"]) // prints the help message function printHelp() { console.error("boxboat/config-merge [flags] file1 [file2] ... [fileN]") + console.error("-a, --array merge|overwrite|concat whether to merge, overwrite, or concatenate arrays. defaults to merge") console.error("-f, --format json|toml|yaml whether to output json, toml, or yaml. defaults to yaml") console.error("-h --help print the help message") console.error(" files ending in .env and .sh will be sourced and used for environment variable substitution") @@ -57,6 +58,7 @@ function readFileAndSubEnv(file) { let args = process.argv.slice(2) let processPositional = true let setFlag = null +let array = 'merge' let format = 'yaml' let obj = {} @@ -76,7 +78,16 @@ for (let arg of args) { printHelp() process.exit(0) } - if (setFlag == "f") { + if (setFlag == "a") { + if (arg == "merge" || arg == "overwrite" || arg == "concat") { + array = arg + setFlag = null + } else { + console.error(`Array should be "merge", "overwrite", or "concat", invalid: ${arg}`) + printHelp() + process.exit(1) + } + } else if (setFlag == "f") { if (arg == "json" || arg == "toml" || arg == "yaml") { format = arg setFlag = null @@ -85,10 +96,13 @@ for (let arg of args) { printHelp() process.exit(1) } + } else if (arg == "-a" || arg == "--array") { + setFlag = "a" } else if (arg == "-f" || arg == "--foramt") { setFlag = "f" - } else { + } + else { break } positionalArgCount++ @@ -110,6 +124,18 @@ for (let arg of args) { } } +// merge customizer +function customizer(objValue, srcValue) { + if (Array.isArray(objValue)) { + if (array == "overwrite") { + return srcValue + } else if (array == "concat") { + return objValue.concat(srcValue) + } + } + return undefined +} + // process files for (arg of globArgs) { // check that file exists @@ -152,13 +178,13 @@ for (arg of globArgs) { } } else if (arg.match(mergeJsonRe)) { - merge(obj, JSON.parse(readFileAndSubEnv(arg))) + mergeWith(obj, JSON.parse(readFileAndSubEnv(arg)), customizer) } else if (arg.match(mergeTomlRe)) { - merge(obj, toml.parse(readFileAndSubEnv(arg))) + mergeWith(obj, toml.parse(readFileAndSubEnv(arg)), customizer) } else if (arg.match(mergeYamlRe)) { - merge(obj, YAML.parse(readFileAndSubEnv(arg))) + mergeWith(obj, YAML.parse(readFileAndSubEnv(arg)), customizer) } else { console.error(`Invalid file extension: ${arg}`) printHelp() diff --git a/package.json b/package.json index 3451d24..e47be38 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "dependencies": { "fast-json-patch": "2.0.6", "glob": "7.1.2", - "lodash.merge": "4.6.2", + "lodash.mergewith": "4.6.2", "toml-j0.4": "1.1.1", "tomlify-j0.4": "3.0.0", "yaml": "1.10.0" diff --git a/test.sh b/test.sh index 3ab951f..d375f00 100755 --- a/test.sh +++ b/test.sh @@ -16,13 +16,27 @@ docker run --rm \ -f toml "*" echo "" -echo "YAML:" +echo "YAML array merge:" docker run --rm \ -v "$(pwd)/test/mix/:/home/node/" \ boxboat/config-merge \ "*" echo "" +echo "YAML array overwrite:" +docker run --rm \ + -v "$(pwd)/test/mix/:/home/node/" \ + boxboat/config-merge \ + -a overwrite "*" +echo "" + +echo "YAML array concat:" +docker run --rm \ + -v "$(pwd)/test/mix/:/home/node/" \ + boxboat/config-merge \ + -a concat "*" +echo "" + echo "Docker Compose" docker run --rm \ -v "$(pwd)/test/docker-compose/:/home/node/" \ diff --git a/test/mix/10.yaml b/test/mix/10.yaml index 6bad445..190015e 100644 --- a/test/mix/10.yaml +++ b/test/mix/10.yaml @@ -1 +1,3 @@ -override-yaml: override \ No newline at end of file +override-yaml: override +array-obj: + - key3: key3 diff --git a/yarn.lock b/yarn.lock index 129e863..6411514 100644 --- a/yarn.lock +++ b/yarn.lock @@ -53,9 +53,10 @@ inherits@2: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" -lodash.merge@4.6.2: +lodash.mergewith@4.6.2: version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55" + integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ== minimatch@^3.0.4: version "3.0.4" @@ -85,7 +86,7 @@ wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" -yaml@^1.10.0: +yaml@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e" integrity sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==