diff --git a/scripts/jq-template.awk b/scripts/jq-template.awk new file mode 100644 index 00000000..d67cfe1d --- /dev/null +++ b/scripts/jq-template.awk @@ -0,0 +1,127 @@ +# this script assumes gawk! (busybox "awk" is not quite sufficient) + +# see https://github.com/docker-library/php or https://github.com/docker-library/golang for examples of usage ("apply-templates.sh") + +# escape an arbitrary string for passing back to jq as program input +function jq_escape(str, # parameters + prog, e, out) # locals +{ + prog = "jq --raw-input --slurp ." + printf "%s", str |& prog + close(prog, "to") + prog |& getline out + e = close(prog) + if (e != 0) { + exit(e) + } + return out +} + +BEGIN { + jq_expr_defs = "" + jq_expr = "" + agg_jq = "" + agg_text = "" + + OPEN = "{{" + CLOSE = "}}" + CLOSE_EAT_EOL = "-" CLOSE ORS +} + +function trim(str) { + sub(/^[[:space:]]+/, "", str) + sub(/[[:space:]]+$/, "", str) + return str +} +function append(str) { + if (jq_expr && jq_expr !~ /\($/ && str !~ /^\)/) { + jq_expr = jq_expr "\n+ " + } else if (jq_expr) { + jq_expr = jq_expr "\n" + } + jq_expr = jq_expr str +} +function append_string(str) { + if (!str) return + str = jq_escape(str) + append(str) +} +function append_jq(expr) { + if (!expr) return + expr = trim(expr) + if (!expr) return + if (expr ~ /^(def|include|import)[[:space:]]/) { # a few things need to go at the start of our "script" + jq_expr_defs = jq_expr_defs expr ";\n" + return + } + # if expr doesn't begin with ")" or end with "(", wrap it in parenthesis (so our addition chain works properly) + if (expr !~ /^\)/) expr = "(" expr + if (expr !~ /\($/) expr = expr ")" + append(expr) +} + +{ + line = $0 ORS + + i = 0 + if (agg_jq || (i = index(line, OPEN))) { + if (i) { + agg_text = agg_text substr(line, 1, i - 1) + line = substr(line, i) + } + append_string(agg_text) + agg_text = "" + + agg_jq = agg_jq line + line = "" + + if (!index(agg_jq, CLOSE)) { + next + } + + while (i = index(agg_jq, OPEN)) { + line = substr(agg_jq, 1, i - 1) + agg_jq = substr(agg_jq, i + length(OPEN)) + if (i = index(agg_jq, CLOSE_EAT_EOL)) { + expr = substr(agg_jq, 1, i - 1) + agg_jq = substr(agg_jq, i + length(CLOSE_EAT_EOL)) + } + else { + i = index(agg_jq, CLOSE) + expr = substr(agg_jq, 1, i - 1) + agg_jq = substr(agg_jq, i + length(CLOSE)) + } + append_string(line) + append_jq(expr) + } + line = agg_jq + agg_jq = "" + } + + if (line) { + agg_text = agg_text line + } +} + +END { + append_string(agg_text) + agg_text = "" + + append_jq(agg_jq) + agg_jq = "" + + jq_expr = "if env.version then .[env.version] else . end | (\n" jq_expr "\n)" + jq_expr = jq_expr_defs jq_expr + + if (ENVIRON["DEBUG"]) { + print jq_expr > "/dev/stderr" + } + + prog = "jq --join-output --from-file /dev/stdin versions.json" + printf "%s", jq_expr | prog + + e = close(prog) + if (e != 0) { + exit(e) + } +}