refactor: Use jq instead of custom posix complient json.sh
Some checks failed
Lint / lint (push) Failing after 14s
Lint / lint (pull_request) Failing after 15s

While json.sh worked decently for reading json files, I didn't want to
implement writing to json files as well and make it completely
unreadable due to the added complexity.

So, I think its better to just use jq and keep things relatively simple
with the tradeoff of a lightweight dependency
This commit is contained in:
2026-06-26 18:19:23 +05:30
parent 780e79364f
commit 7f3ff45f05
4 changed files with 16 additions and 124 deletions

View File

@@ -1,68 +0,0 @@
#!/usr/bin/env bash
# generic JSON parser in pure bash and awk.
# reads JSON from stdin and outputs a flattened list of key-value pairs.
# example input: {"plugins": {"my_plugin": {"version": "1.0", "arr": [1, 2]}}}
# example output:
# plugins.my_plugin.version="1.0"
# plugins.my_plugin.arr[0]=1
# plugins.my_plugin.arr[1]=2
# pardon my french
parse_json() {
# Tokenize the JSON using grep
grep -oE '"([^"\\]|\\.)*"|true|false|null|[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?|[][}{:,]' | \
awk '
BEGIN {
depth=0;
key=""
}
{
token = $0
if (token == "{") {
depth++
is_key[depth] = 1
array_idx[depth] = ""
} else if (token == "}") {
delete path[depth]
delete array_idx[depth]
depth--
} else if (token == "[") {
depth++
is_key[depth] = 0
array_idx[depth] = 0
} else if (token == "]") {
delete array_idx[depth]
delete path[depth]
depth--
} else if (token == ":") {
is_key[depth] = 0
} else if (token == ",") {
if (array_idx[depth] != "") {
array_idx[depth]++
} else {
is_key[depth] = 1
}
} else {
if (is_key[depth] == 1) {
# Remove quotes from the key
gsub(/^"|"$/, "", token)
path[depth] = token
} else {
# It is a value
p = ""
for (i=1; i<=depth; i++) {
if (array_idx[i] != "") {
p = p "[" array_idx[i] "]"
} else if (path[i] != "") {
p = p "." path[i]
}
}
# Remove leading dot
sub(/^\./, "", p)
print p "=" token
}
}
}
'
}

View File

@@ -1,50 +1,13 @@
#!/usr/bin/env bash
if [ -f "$BOOTSTRAP_DIR/lib/json.sh" ]; then
. "$BOOTSTRAP_DIR/lib/json.sh"
fi
# Parses a plugin manifest using the generic json parser and outputs bash array assignments
# Parses a plugin manifest using jq and outputs bash array assignments
parse_plugin_manifest() {
# The generic parser outputs lines like:
# plugins.myplugin.version="1.0"
# plugins.myplugin.url="https://..."
# We want to extract myplugin and the keys to build:
# PLUGIN_VERSIONS["myplugin"]="1.0"
# PLUGIN_URLS["myplugin"]="https://..."
parse_json | awk -F'=' '
{
path = $1
val = $2
# Remove quotes around value for bash array assignment
gsub(/^"|"$/, "", val)
# Match paths starting with "plugins."
if (match(path, /^plugins\./)) {
rest = substr(path, RLENGTH + 1)
# Find the last dot to separate plugin name from the property key
last_dot = 0
for (i=length(rest); i>0; i--) {
if (substr(rest, i, 1) == ".") {
last_dot = i
break
}
}
if (last_dot > 0) {
plugin_name = substr(rest, 1, last_dot - 1)
prop = substr(rest, last_dot + 1)
if (prop == "version") {
print "PLUGIN_VERSIONS[\"" plugin_name "\"]=\"" val "\""
} else if (prop == "url") {
print "PLUGIN_URLS[\"" plugin_name "\"]=\"" val "\""
} else if (prop == "bootstrap") {
print "PLUGIN_BOOTSTRAP_VERSIONS[\"" plugin_name "\"]=\"" val "\""
}
}
}
}'
jq -r '
.plugins | to_entries[] |
(if .value.version then "PLUGIN_VERSIONS[\"" + .key + "\"]=\"" + .value.version + "\"" else empty end),
(if .value.url then "PLUGIN_URLS[\"" + .key + "\"]=\"" + .value.url + "\"" else empty end),
(if .value.bootstrap then "PLUGIN_BOOTSTRAP_VERSIONS[\"" + .key + "\"]=\"" + .value.bootstrap + "\"" else empty end)
'
}
# Ensures that the plugin sources file exists, initializing it with the official repository by default