├── Dockerfile ├── Makefile ├── README.md ├── json2env └── test ├── docker-compose.test.yaml ├── run_tests.sh └── testfiles ├── badkey.json ├── case.json ├── complex.json ├── newline.json ├── string.json └── test.sh /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:latest 2 | 3 | COPY json2env /usr/local/bin/json2env 4 | 5 | RUN set -e -u -o pipefail -x; \ 6 | apk --no-cache update; \ 7 | apk --no-cache upgrade; \ 8 | apk --no-cache add --no-scripts jq; \ 9 | cd /usr/local/bin; \ 10 | echo '#!/bin/sh' >entrypoint.sh; \ 11 | echo '/usr/local/bin/json2env "$@"' >>entrypoint.sh; \ 12 | chmod +x entrypoint.sh json2env 13 | 14 | ENTRYPOINT [ "/usr/local/bin/entrypoint.sh" ] 15 | 16 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | build: clean 3 | docker build . --progress=plain -t decknroll/json2env:build 4 | 5 | show-test: clean show-test-run clean 6 | 7 | show-test-run: 8 | cd test && docker-compose -f docker-compose.test.yaml up --abort-on-container-exit 9 | 10 | test: FORCE docker-run-test 11 | cd test && docker-compose -f docker-compose.test.yaml run --rm sut 12 | 13 | docker-run-test: 14 | echo '{"docker-run-test":"success"}' | docker run -i decknroll/json2env:build 15 | 16 | FORCE: 17 | # https://www.gnu.org/software/make/manual/html_node/Force-Targets.html 18 | 19 | push: 20 | docker tag decknroll/json2env:build decknroll/json2env:latest 21 | docker push decknroll/json2env:latest 22 | 23 | clean: 24 | docker image rm decknroll/json2env:build --force || true 25 | docker image rm decknroll/json2env:test --force || true 26 | cd test && docker-compose -f docker-compose.test.yaml down --rmi all 27 | 28 | build-test-push: build test push 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # json2env 2 | 3 | [![](https://images.microbadger.com/badges/image/decknroll/json2env.svg)](https://microbadger.com/images/decknroll.com/json2env) 4 | [![](https://img.shields.io/docker/pulls/decknroll/json2env.svg?style=plastic)](https://hub.docker.com/r/decknroll/json2env/) 5 | [![](https://img.shields.io/docker/stars/decknroll/json2env.svg?style=plastic)](https://hub.docker.com/r/decknroll/json2env/) 6 | [![](https://img.shields.io/badge/docker_build-automated-blue.svg?style=plastic)](https://hub.docker.com/repository/docker/decknroll/json2env/builds) 7 | 8 | DockerHub: [json2env](https://hub.docker.com/r/decknroll/json2env/) 9 | GitHub: [json2env](https://github.com/decknroll/json2env) 10 | 11 | Kilna's swiss army knife for turning JSON objects into eval-able environment 12 | shell code for setting environment variables. 13 | 14 | There are a few projects named `json2env` out there, this one attempts to 15 | meet the following goals: 16 | 17 | * Runs under Alpine Linux 18 | * Has only POSIX or busybox tools, plus `jq` as its preprequisites 19 | * Runs under `dash` (busybox/alpine), `bash`, `ksh` and `zsh` shells 20 | * Can output JSON arrays as: 21 | * Native shell arrays 22 | * Delimited strings 23 | * JSON string (compact or pretty) 24 | * Can output JSON objects (dicts/maps) as: 25 | * Bash-style associative arrays 26 | * Delimited strings 27 | * JSON string (compact or pretty) 28 | * Processes input from files or STDIN 29 | * Outputs to STDOUT or a file 30 | * Environment variable name options 31 | * Change case of the var name(s) 32 | * Prefix the var name(s) 33 | * Translate all or only one variable 34 | * Optionally use a different name than the JSON key 35 | * Can select a subpath of the JSON to export 36 | * Translate with or without export of environment variables 37 | 38 | This covers the majority of the use cases for shell-based build and 39 | automation that needs access to JSON data. 40 | 41 | ## Usage 42 | 43 | ``` 44 | USAGE: json2env [ OPTIONS ] [ FILENAMES ] 45 | 46 | Kilna's swiss army knife for turning key-values in a JSON object into eval-able 47 | shell code for setting environment variables. 48 | 49 | Processes FILENAMES as JSON documents if provided, otherwise processes standard 50 | input as a JSON document. 51 | 52 | --export : Export shell variables 53 | -x (prepend each key=val with shell's export keyword) 54 | 55 | --path PATH : JSON sub-path in jq .path.to.the.object dot-prefix notation 56 | -p PATH (e.g '.env_vars') - defaults to '.' for the root JSON object. 57 | The referenced path must only be a JSON object (dict/map/hash), 58 | not an array, string, etc. 59 | 60 | --prefix PREFIX : Prepend this string the to names of output shell variables 61 | -p PREFIX 62 | 63 | --upper : Translate JSON keys into uppercase shell environment vars 64 | -u 65 | 66 | --lower : Translate JSON keys into lowercase shell environment vars 67 | -l 68 | 69 | --key KEY : Only output this single key in the object 70 | -k KEY (defaults to all keys) 71 | 72 | --env-name NAME : When outputting a single key with --key, force this value 73 | -e NAME as the environment variable name 74 | 75 | --text : JSON objects and arrays become newline delimited text 76 | -t rather than the default behavior of setting the shell 77 | environment variable to a JSON string representation 78 | 79 | --kv-sep STRING : Key-value separator for list-style translation of JSON 80 | -K STRING objects (defaults to ':') 81 | 82 | --list-sep STRING : Record separator for list-style translation 83 | -L STRING (defaults to newline) 84 | 85 | --array : JSON arrays are translated into POSIX shell native arrays 86 | -a (overrides --text) 87 | 88 | --assoc : JSON objects are tranlated into bash-style native 89 | -a associative arrays (overrides --text) 90 | 91 | --force : Output shell native for --array or --assoc even if the 92 | -f current shell does not support it 93 | 94 | --strict : Fail on JSON keys which aren't alphanumeric + underscore 95 | -s (defaults to translating keys) 96 | 97 | --out-file FILE : Output to a file instead of STDOUT 98 | -o FILE 99 | 100 | --compact : Output JSON strings in compact mode 101 | -c 102 | 103 | --help : Show help 104 | -h 105 | ``` 106 | ## Docker 107 | 108 | This project also builds an associated docker image `decknroll/json2env`, so 109 | you can run `json2env` without installing locally: 110 | 111 | ``` 112 | $ cat env.json | docker run -i decknroll/json2env > env.sh 113 | ``` 114 | 115 | All of the command line parameters are supported, pass them as options to 116 | `docker run` the same as if you were calling the script directly: 117 | 118 | ``` 119 | $ cat foo.json | docker run -i decknroll/json2env --lower --prefix env_ --text > foo.sh 120 | ``` 121 | 122 | The Docker image is only 4mb in size. 123 | 124 | ## Examples 125 | 126 | ### Saving to a `.env` file 127 | 128 | Many tools use a `.env` file to set properties for a given directory. If you 129 | have a bunch of parameters in an `environment.json` file: 130 | 131 | ``` 132 | { 133 | "profile": "main", 134 | "mode": "init" 135 | } 136 | ``` 137 | 138 | ...and you want to create `.env` file from it, simply: 139 | 140 | ``` 141 | $ json2env --out-file .env environment.json 142 | $ cat .env 143 | profile=main 144 | mode=init 145 | ``` 146 | 147 | ### Setting environment variables for immediate use 148 | 149 | If you need the environment variables available in the currently-running shell, 150 | simply `eval` the output of this script: 151 | 152 | ``` 153 | $ eval $(json2env --export env-vars.json) 154 | ``` 155 | 156 | Make sure to use `--export` so that any commands run by your shell will inherit 157 | the set values. 158 | 159 | ### Selecting a JSON sub-path 160 | 161 | If you want to set environment variables only for a certain object in the JSON 162 | document `config.json`: 163 | 164 | ``` 165 | { 166 | "project": "foo", 167 | "environ": { 168 | "SERVICE_TOKEN": "ynubAEtfyHue2DZfNPRSAfSDN34zuvbh" 169 | } 170 | } 171 | ``` 172 | 173 | Then you can export only the `environ` key by: 174 | 175 | ``` 176 | $ json2env --export --path .environ config.json 177 | export SERVICE_TOKEN=ynubAEtfyHue2DZfNPRSAfSDN34zuvbh 178 | ``` 179 | 180 | The `--path` is provided in `jq` style .path.to.the.object syntax. 181 | 182 | ### Changing variable names 183 | 184 | If you want to change the case of the var names you can use `--lower` or 185 | `--upper`: 186 | 187 | ``` 188 | $ json2env --export --lower .environ config.json 189 | export service_token=ynubAEtfyHue2DZfNPRSAfSDN34zuvbh 190 | ``` 191 | 192 | If you only need one key as opposed to all keys in a JSON document path, you 193 | can specify it using `--key`, and if you want to set an environment variable 194 | name other than one based on the key, use the `--env-name` option. 195 | 196 | You can also prefix all keys with `--prefix` to avoid name collisions and/or to 197 | group the environment variables. 198 | 199 | ### Arrays 200 | 201 | Given a file `letters.json` 202 | ``` 203 | { 204 | "alpha": [ 205 | "a", 206 | "b", 207 | "c" 208 | ] 209 | } 210 | ``` 211 | 212 | We can see that JSON arrays are by default translated to JSON strings for the 213 | environment: 214 | 215 | ``` 216 | $ json2env letters.json 217 | alpha='[ 218 | "a", 219 | "b", 220 | "c" 221 | ]' 222 | ``` 223 | 224 | You can also compact the JSON syntax: 225 | 226 | ``` 227 | $ json2env --compact letters.json 228 | alpha='["a","b","c"]' 229 | ``` 230 | 231 | JSON isn't very handy for manipulating in the shell, so you can also 232 | use `--array` to output as a shell array: 233 | 234 | ``` 235 | $ json2env --array letters.json 236 | alpha=('a' 'b' 'c') 237 | ``` 238 | 239 | Which you can then use in a `for` loop. 240 | 241 | Some minimalist shells don't support arrays (like `dash` which comes with 242 | Alpine Linux), or sometimes you just want to flatten to a text-based list, 243 | and that's what `--text` is for: 244 | 245 | ``` 246 | $ json2env --text letters.json 247 | alpha='a 248 | b 249 | c' 250 | ``` 251 | 252 | The default delimiter is newline, if you want to use for example spaces 253 | or commas instead, use `--list-sep`: 254 | 255 | ``` 256 | $ json2env --text --list-sep ' ' letters.json 257 | alpha='a b c' 258 | $ json2env --text --list-sep , letters.json 259 | alpha='a,b,c' 260 | ``` 261 | 262 | ### Objects 263 | 264 | Likewise given a file `translate.json` 265 | ``` 266 | { 267 | "words": { 268 | "uno": "one", 269 | "dos": "two", 270 | "tres": "three" 271 | } 272 | } 273 | ``` 274 | 275 | Much the same, JSON objects are by default translated to JSON strings for the 276 | environment: 277 | 278 | ``` 279 | $ json2env translate.json 280 | words='{ 281 | "uno": "one", 282 | "dos": "two", 283 | "tres": "three" 284 | }' 285 | ``` 286 | 287 | Just like with arrays, you can also compact the JSON syntax: 288 | 289 | ``` 290 | $ json2env --compact translate.json 291 | words='{"uno":"one","dos":"two","tres":"three"}' 292 | ``` 293 | 294 | If you have a modern bash-like shell, you can also use `--assoc` to output an 295 | associative array: 296 | 297 | ``` 298 | $ json2env --assoc translate.json 299 | declare -A words=( 300 | [dos]=two 301 | [tres]=three 302 | [uno]=one 303 | ) 304 | ``` 305 | 306 | Many shells don't support bash-style associative arrays. So, as with arrays, 307 | you can also use `--text` to output objects as lists. The default is a space 308 | between the key and the value, with a newline between each entry. 309 | 310 | ``` 311 | $ json2env --text translate.json 312 | words='dos two 313 | tres three 314 | uno one' 315 | ``` 316 | 317 | And you can change the separators as well with `--list-sep` and `--kv-sep`: 318 | 319 | ``` 320 | $ json2env --text --list-sep ';' --kv-sep '=' translate.json 321 | words='dos=two;tres=three;uno=one' 322 | ``` 323 | 324 | ## Known issues 325 | 326 | * Input files must come last on the command line 327 | * Needs better input validation & error messaging on bad input 328 | 329 | -------------------------------------------------------------------------------- /json2env: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Dependencies: jq tr sed 4 | # Tested with: busybox bourne bash zsh 5 | 6 | # TODO: 7 | # Add license 8 | # Check --path is correct 9 | # Prevent --env-name unless --key is being used 10 | # Fix it so options and filenames can be mixed (right now input files must be last) 11 | # Enable --key=val style params in addition to --key value 12 | # Shell escape key names passed into jq 13 | # Defaults environment variable / rcfile 14 | # Fix chomped ending newlines from using $() 15 | # Finish tests/ 16 | # Enable DockerHub automated tests? 17 | # Create initial release tag 18 | # Create dockerhub build from tag 19 | # Create make target for release of tag 20 | 21 | name="${0##*/}" 22 | 23 | usage() { 24 | if [ "${1:-}" ]; then echo "$1" >&2; fi 25 | cat <&2; }; 100 | 101 | die() { echo "$1" >&2; [ -e "$outfile" ] && rm "$outfile"; exit "${2:-1}"; }; 102 | 103 | shell_quote() { 104 | if [ "$(echo "$1" | tr -c -d a-zA-Z0-9)" = "$1" ]; then 105 | echo "$1" # Simple shell values don't need quoting 106 | else 107 | echo "'$(echo "$1" | sed -e "s/'/'\\\\''/")'" 108 | fi 109 | } 110 | 111 | c='' # jq -c flag 112 | case='as-is' 113 | export debug='' 114 | env_name='' 115 | evaluate='' 116 | force='' 117 | kv_sep=' ' 118 | list_sep=$'\n' 119 | native_array='' 120 | native_assoc='' 121 | outfile='' 122 | json_path='.' 123 | prefix='' 124 | strict='' 125 | text='' 126 | only_key='' 127 | x='' # declare -x flag 128 | 129 | while [ $# -gt 0 ]; do case "$1" in 130 | -a|--array) native_array=true;; 131 | -A|--assoc) native_assoc=true;; 132 | -c|--compact) c='c';; 133 | -d|--debug) debug=true;; 134 | -e|--env-name) env_name="$2"; shift;; 135 | -f|--force) force=true;; 136 | -h|--help) usage;; 137 | -k|--key) only_key="$2"; shift;; 138 | -K|--kv-sep) kv_sep="$2"; shift;; 139 | -l|--lower) case='lower';; 140 | -L|--list-sep) list_sep="$2"; shift;; 141 | -o|--out-file) outfile="$2"; shift;; 142 | -p|--path) json_path="$2"; shift;; 143 | -P|--prefix) prefix="$2"; shift;; 144 | -s|--strict) strict=true;; 145 | -t|--text) text=true;; 146 | -u|--upper) case='upper';; 147 | -x|--export) x='x';; 148 | -*) usage "Unknown flag: $1";; 149 | *) break;; 150 | esac; shift; done 151 | 152 | if [ "${#@}" -eq 0 ]; then 153 | if [ -t 0 ]; then 154 | usage "Must be piped into or a JSON filename provided on command line" 3 155 | else 156 | set -- '-' 157 | fi 158 | fi 159 | 160 | if [ "$native_array" ] && [ ! "$force" ]; then 161 | if ! (eval 'declare -a zzz=(a b) && [ "${zzz[1]}" = "b" ]' >/dev/null 2>&1); then 162 | die "$SHELL does not support arrays with --array, use --force to output anyway" 163 | fi 164 | fi 165 | 166 | if [ "$native_assoc" ] && [ ! "$force" ]; then 167 | if ! (eval 'declare -A zzz=([a]=b) && [ "${zzz[a]}" = "b" ]' >/dev/null 2>&1); then 168 | die "$SHELL does not support associative arrays with --assoc, use --force to output anyway" 169 | fi 170 | fi 171 | 172 | process_key() { 173 | 174 | key="$1" 175 | json="$(cat -)" 176 | 177 | debug '' 178 | debug " KEY: $key" 179 | 180 | if [ "$env_name" ]; then varname="$env_name"; else varname="$key"; fi 181 | # Clean up varname to translate space and - to underscore, and 182 | # remove non-alphanum + underscore chars 183 | varname="$(echo "$varname" | tr ' -' '__' | tr -c -d a-zA-Z0-9_)" 184 | # If we're in strict mode, fail if the key has been changed 185 | if [ "$strict" ] && [ "$varname" != "$key" ]; then 186 | die "Invalid key '$(shell_quote "$key")'" 6 187 | fi 188 | if [ "$case" = 'lower' ]; then 189 | varname="$(echo "$varname" | tr A-Z a-z)" 190 | fi 191 | if [ "$case" = 'upper' ]; then 192 | varname="$(echo "$varname" | tr a-z A-Z)" 193 | fi 194 | varname="$prefix$varname" 195 | debug " VARNAME: $varname" 196 | 197 | translate='raw' 198 | type="$(echo "$json" | jq -r "$json_path | .[\"$key\"] | type")" 199 | debug " TYPE: $type" 200 | if [ "$type" = "array" ]; then 201 | [ "$text" ] && translate=text-array 202 | [ "$native_array" ] && translate=native-array 203 | elif [ "$type" = "object" ]; then 204 | [ "$text" ] && translate=text-assoc 205 | [ "$native_assoc" ] && translate=native-assoc 206 | fi 207 | debug " TRANSLATE: $translate" 208 | 209 | case "$translate" in 210 | raw) 211 | [ "$x" ] && printf '%s' 'export '; 212 | val="$(echo "$json" | jq -${c}r "$json_path | .[\"$key\"]")"; 213 | echo "$varname=$(shell_quote "$val")"; 214 | ;; 215 | native-assoc) 216 | echo "declare -A$x $varname=("; 217 | echo "$json" | jq -j "$json_path | .[\"$key\"] | keys[] | (. + \"\u0000\")" | \ 218 | while read -r -d '' objkey; do 219 | objval="$(echo "$json" | jq -${c}r "$json_path | .[\"$key\"] | .[\"$objkey\"]")"; 220 | echo " [$(shell_quote "$objkey")]=$(shell_quote "$objval")"; 221 | done; 222 | echo ')'; 223 | ;; 224 | native-array) 225 | [ "$x" ] && printf '%s' 'export '; 226 | echo "$varname=($(echo "$json" | jq -${c}r "$json_path | .[\"$key\"] | @sh"))"; 227 | ;; 228 | text-array) 229 | [ "$x" ] && printf '%s' 'export '; 230 | val="$( 231 | echo "$json" | jq -j "$json_path | .[\"$key\"] | .[] | (. + \"\u0000\")" | \ 232 | while read -r -d '' thisval; do 233 | printf '%s' "${thisval}${list_sep}" 234 | done 235 | )" 236 | echo "$varname=$(shell_quote "${val%"${list_sep}"}")"; 237 | ;; 238 | text-assoc) 239 | [ "$x" ] && printf '%s' 'export '; 240 | val="$( 241 | echo "$json" | jq -j "$json_path | .[\"$key\"] | keys[] | (. + \"\u0000\")" | \ 242 | while read -r -d '' thiskey; do 243 | thisval="$(echo "$json" | jq -${c}r "$json_path | .[\"$key\"] | .[\"$thiskey\"]")" 244 | printf '%s' "${thiskey}${kv_sep}${thisval}${list_sep}" 245 | done 246 | )" 247 | echo "$varname=$(shell_quote "${val%"${list_sep}"}")"; 248 | ;; 249 | esac 250 | 251 | } 252 | 253 | for file in "$@"; do 254 | 255 | debug "FILE: $file" 256 | json="$(cat "$file")" 257 | debug "JSON:" 258 | debug "$json" 259 | 260 | out="$( 261 | if [ "$only_key" ]; then 262 | echo "$json" | process_key "$only_key" 263 | else 264 | echo "$json" | jq -j "$json_path | keys[] | (. + \"\u0000\")" | \ 265 | while read -r -d '' key; do 266 | echo "$json" | process_key "$key" 267 | done 268 | fi 269 | )" 270 | 271 | if [ "$outfile" ]; then 272 | echo "$out" >"$outfile" 273 | else 274 | echo "$out" 275 | fi 276 | 277 | done 278 | 279 | -------------------------------------------------------------------------------- /test/docker-compose.test.yaml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | sut: 4 | build: 5 | context: .. 6 | image: decknroll/json2env:test 7 | container_name: json2env 8 | hostname: json2env 9 | entrypoint: [ "/bin/sh", "/run_tests.sh" ] 10 | volumes: 11 | - ./testfiles:/testfiles 12 | - ./run_tests.sh:/run_tests.sh 13 | 14 | -------------------------------------------------------------------------------- /test/run_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | sed -i '/edge/s/^#//' /etc/apk/repositories 6 | apk --no-cache update 7 | apk --no-cache upgrade 8 | 9 | cd /testfiles 10 | 11 | echo ========================================================================= 12 | echo '/bin/sh (dash)' 13 | echo ========================================================================= 14 | ./test.sh 15 | echo 16 | 17 | echo ========================================================================= 18 | echo '/bin/bash' 19 | echo ========================================================================= 20 | apk --no-cache add bash 21 | echo ------------------------------------------------ 22 | bash ./test.sh 'bash /usr/local/bin/json2env' 23 | echo 24 | 25 | echo ========================================================================= 26 | echo '/bin/mksh' 27 | echo ========================================================================= 28 | apk --no-cache add mksh 29 | echo ------------------------------------------------ 30 | mksh ./test.sh 'mksh /usr/local/bin/json2env' 31 | echo 32 | 33 | echo ========================================================================= 34 | echo '/bin/zsh' 35 | echo ========================================================================= 36 | apk --no-cache add zsh 37 | echo ------------------------------------------------ 38 | ./test.sh 'zsh /usr/local/bin/json2env' 39 | echo 40 | 41 | -------------------------------------------------------------------------------- /test/testfiles/badkey.json: -------------------------------------------------------------------------------- 1 | { 2 | "bad\nkey": "This key can't be used as-is shell environment variable" 3 | } 4 | -------------------------------------------------------------------------------- /test/testfiles/case.json: -------------------------------------------------------------------------------- 1 | { 2 | "Key": "a" 3 | } 4 | 5 | -------------------------------------------------------------------------------- /test/testfiles/complex.json: -------------------------------------------------------------------------------- 1 | { 2 | "str": "s", 3 | "ar": ["a","b","c"], 4 | "obj": { 5 | "k1": "v1", 6 | "k2": "v2" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/testfiles/newline.json: -------------------------------------------------------------------------------- 1 | { 2 | "newline": "this\nhas\nnewlines!" 3 | } 4 | -------------------------------------------------------------------------------- /test/testfiles/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": "value" 3 | } 4 | -------------------------------------------------------------------------------- /test/testfiles/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | cd "${0%/*}" 6 | 7 | json2env="${1:-json2env}" 8 | 9 | n=$'\n' 10 | 11 | errors=0 12 | 13 | shell_quote() { echo \'"$(echo "$1" | sed -e "s/'/'\\\\''/g")"\'; }; 14 | 15 | t() { 16 | name="$1" 17 | code="$2" 18 | op="$3" 19 | if [ -e "$4" ]; then val="$(cat "$4")" 20 | else val="$4"; fi 21 | out="$(eval "$code")" 22 | if eval "[ $(shell_quote "$out") $op $(shell_quote "$val") ]"; then 23 | echo "$name: ok" 24 | else 25 | errors=$(( errors + 1 )) 26 | echo "$name: fail" 27 | echo " ran: \`$code\`" 28 | echo " got: [$out]" 29 | echo " comparison: $op" 30 | echo " expected: [$val]" 31 | fi 32 | } 33 | 34 | #t 'fail' 'echo 1' == 0 35 | 36 | t 'help exit code' \ 37 | '$json2env --help >/dev/null 2>&1; echo $?' == 0 38 | 39 | t 'help content length' \ 40 | '$json2env --help 2>/dev/null | wc -l' -eq 69 41 | 42 | t 'from stdin' \ 43 | 'cat string.json | $json2env' == string=value 44 | 45 | t 'from files' \ 46 | '$json2env string.json case.json' == "string=value${n}Key=a" 47 | 48 | [ -e /tmp/out.sh ] && rm /tmp/out.sh 49 | 50 | t 'output-to-file empty stdout' \ 51 | '$json2env -o /tmp/out.sh string.json' == '' 52 | 53 | t 'output-to-file contents' \ 54 | 'cat /tmp/out.sh' == string=value 55 | 56 | [ -e /tmp/out.sh ] && rm /tmp/out.sh 57 | 58 | t 'mixed-case to lowercase key translation' \ 59 | '$json2env -l case.json' == key=a 60 | 61 | t 'mixed-case to uppercase key translation' \ 62 | '$json2env -u case.json' == KEY=a 63 | 64 | t 'array as JSON compact' \ 65 | '$json2env -k ar -c complex.json' == ar=\''["a","b","c"]'\' 66 | 67 | t 'object as JSON compact' \ 68 | '$json2env -k obj -c complex.json' == obj=\''{"k1":"v1","k2":"v2"}'\' 69 | 70 | t 'array as text default' \ 71 | '$json2env -t -k ar complex.json' == "ar='a${n}b${n}c'" 72 | 73 | t 'array as text with delimiter' \ 74 | '$json2env -t -L , -k ar complex.json' == "ar='a,b,c'" 75 | 76 | t 'object as text default' \ 77 | '$json2env -t -k obj complex.json' == "obj='k1 v1${n}k2 v2'" 78 | 79 | t 'object as text with delimiters' \ 80 | '$json2env -t -L , -K = -k obj complex.json' == "obj='k1=v1,k2=v2'" 81 | 82 | # --prefix 83 | # --env-name 84 | # --array 85 | # --assoc 86 | # --force 87 | # --strict 88 | # non-strict 89 | # --path 90 | 91 | if [ "$errors" -gt 0 ]; then 92 | echo "ERRORS: $errors" 93 | fi 94 | 95 | exit $errors 96 | 97 | --------------------------------------------------------------------------------