[Vuejs]-Override json file values with environment variables docker

2👍

The task can be solved using jq.
The version is robust against settings that do not match a path in the document.

Variables

SETTINGS__APIS__PAYMENT__BASE_URL=https://example2.com
SETTINGS__AVAILABLELOCALES__0=cs
SETTINGS__UNAVAILABLE__PATH=1

Code

jq 'def settings:
      def prepareVariables:
        [$ENV | to_entries[] | select(.key | startswith("SETTINGS__"))]   # select all variables that starts with "SETTINGS__"
        | map(.key |= (. / "__" | map(tonumber? // .))[1:]);              # convert variable names to path arrays

      [paths(scalars) | [., map(ascii_upcase? // .)]] |                   # collect all leaf paths from input file and add uppercase path
      reduce .[] as $leafPath                                             # add leaf paths to corresponding settings
             (prepareVariables; map(select($leafPath[1] == .key) |= . + {path: $leafPath[0]})) |
      map(select(has("path")));                                           # drop settings for unknown paths

    . as $input |
    reduce settings[] as $setting                                         # apply new settings from variables to input file
           ($input; . | setpath($setting["path"]; $setting["value"]))
' input.json

Output

{
  "apis": {
    "payment": {
      "base_url": "https://example2.com"
    },
    "order": {
      "base_url": "https://example.com/"
    }
  },
  "features": {
    "authentication": {
      "authProviders": true,
      "registration": false
    }
  },
  "availableLocales": [
    "cs",
    "es"
  ]
}
👤jpseng

2👍

I’m a jq novice, and I’d be very interested in a better jq script, but here’s one way to use environment variables to modify a settings.json file.

$ cat settings.json 
{
  "apis": {
    "payment": {
      "base_url": "https://example.com/"
    },
    "order": {
      "base_url": "https://example.com/"
    }
  },
  "features": {
    "authentication": {
      "authProviders": true,
      "registration": false
    }
  },
  "availableLocales": [
    "en",
    "es"
  ]
}

$ printenv|grep SETTINGS__
SETTINGS__APIS__PAYMENT__BASE_URL=https://example2.com
SETTINGS__AVAILABLELOCALES__0=cs

$ jq -n '
inputs as $i
| [ $i
    | ..
    | keys_unsorted?
    | .[]
    | strings
  ]
| unique as $allKeys
|
def fixCase:
  . as $w
  | reduce ($allKeys[]|select(length == ($w|length))) as $k
      ("";. + $k|match($w;"i").string)
;
def envpaths:
  [
    $ENV
    | to_entries[]
    | select(.key | startswith("SETTINGS__"))
    | [[ (.key|split("__"))[1:][]
         | if test("^[0-9]+$") then tonumber else fixCase end
       ],
         .value
      ]
  ]
;
reduce envpaths[] as $p ($i; .|setpath($p[0];$p[1]))' settings.json
# the output
{
  "apis": {
    "payment": {
      "base_url": "https://example2.com"
    },
    "order": {
      "base_url": "https://example.com/"
    }
  },
  "features": {
    "authentication": {
      "authProviders": true,
      "registration": false
    }
  },
  "availableLocales": [
    "cs",
    "es"
  ]
}

See it work on jqplay.org.

Leave a comment