Skip to content

Instantly share code, notes, and snippets.

@stavxyz
Last active June 19, 2019 00:58
Show Gist options
  • Save stavxyz/769a73d53d68314de6233d8821c902b0 to your computer and use it in GitHub Desktop.
Save stavxyz/769a73d53d68314de6233d8821c902b0 to your computer and use it in GitHub Desktop.
JSON migrations with `jq`
{
"A": "1!",
"b": "2",
"Z": "spam!",
"?": [
83,
65,
84,
85,
82,
68,
65,
89
],
"_": "*__*",
"&": "eggs",
"falsy": false,
"": "wait, really?",
"no": null,
"hello": "world",
"waldo": "there",
"here": "reset",
"dontchangefalse": false
}
{
"a": "1",
"b": "2",
"z": "spam",
"?": "SATURDAY",
"_": "*__*",
"&": "eggs",
"falsy": false,
"": "wait, really?",
"yo": "hey!",
"no": null,
"rm": true,
"hello": "world",
"here": "hear",
"dontchangefalse": false
}
def default($checkKey; expr):
if has($checkKey) then . else expr end;
def _translate($DEATH_MAP):
if .key == "a" or .key == "z" then
{"key": (.key | ascii_upcase), "value": "\(.value)!"}
elif .key == "?" then
.value |= explode
elif .key == "here" then
# since we set .waldo when we see .here
# we should *not* see "oswald" as the value
{"key": "waldo", "value": "there"}
elif $DEATH_MAP[.key] then
empty
else
.
end;
def translate:
{"yo": true, "rm": true} as $DEATH_MAP |
with_entries(_translate($DEATH_MAP))
# Should not change existing non-null values
| default("dontchangefalse"; .dontchangeme = "wrong")
# Set defaults if they didn't get fixed during migration above
| default("hello"; .hello = "world")
| default("waldo"; .waldo = "oswald")
# You could even re-set .here
| default("here"; .here = "reset")
;
#!/usr/bin/env bash
set -euo pipefail
jq 'include "migration"; translate' input.json | tee output.json
printf 'Comparing to expected.json \n'
cmp <(jq -cS . output.json) <(jq -cS . expected.json) || true
diff <(jq -S . output.json) <(jq -S . expected.json)
printf '✅\n'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment