-
Notifications
You must be signed in to change notification settings - Fork 0
/
make-json-files
executable file
·178 lines (149 loc) · 6.11 KB
/
make-json-files
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#!/usr/bin/env bash
set -euo pipefail
# This is invoked as part of the site deployment, whenever stable channel
# versions are bumped, and converts synadia-nats-channels.conf into other files
# in JSON format.
# The .sh installer is not allowed to rely upon JSON handling being available,
# and the core config supports that, but other installers should get something
# saner.
#
# This script was written in bash, because as a superset of POSIX sh it let me
# copy/paste the config extraction and templating functions I'd written and quickly
# massage data with jq. But any shell is not an ideal choice and this script is
# a candidate for being rewritten to another language. The initial development
# expediency has given us something which runs "within a couple of seconds"
# (instead of milliseconds) but which requires comfort with sh+jq which might
# become a maintenance headache for others.
progname="$(basename "$0" .sh)"
note() { printf >&2 '%s: %s\n' "$progname" "$*"; }
die() { note "$@"; exit 1; }
readonly DEPLOY_DIR="${1:-public}"
readonly SH_CHANNELS_FILE=synadia-nats-channels.conf
readonly NIGHTLY_DATE_URL='https://get-nats.io/current-nightly'
# These are the two files we make.
# The first is a straight reformatting of the .conf to JSON, still requiring expansion.
# The second is a system keyed by platform.
readonly OUT_CHANNELS="$DEPLOY_DIR/synadia-nats-channels.json"
readonly OUT_PLATFORMS="$DEPLOY_DIR/synadia-nats-platforms.json"
readonly -a SUPPORTED_PLATFORMS=(
darwin-amd64
darwin-arm64
freebsd-amd64
linux-386
linux-amd64
linux-arm64
linux-arm6
linux-arm7
windows-386
windows-amd64
windows-arm64
windows-arm6
windows-arm7
)
readonly -A PLATFORM_EXE_EXTENSION=(
[windows-arm6]='exe'
[windows-arm64]='exe'
)
# --------------------------8< End of Config >8---------------------------
# Defining this lets us use grab_channelfile_line unmodified from install.sh
chanfile="$SH_CHANNELS_FILE"
chan_origin="$SH_CHANNELS_FILE"
command -v jq >/dev/null || die "missing command: jq"
# From: install.sh {{{
grab_channelfile_line() {
local varname="${1:?need a file to get from the channel file}"
local t
# sed -E is not POSIX, so we're on BREs only
t="$(sed -n "s/${varname}[[:space:]]*=[[:space:]]*//p" < "${chanfile:?bug, chanfile not in calling context}")"
if [ -n "$t" ]; then
printf '%s\n' "$t"
else
die "missing '${varname}' in ${chan_origin:?}"
fi
}
expand_config_value() {
local val="$1"
local subst="$2"
local replace="$3"
local result=""
while [ "$val" != "${val#*\%${subst}\%}" ]; do
pre="${val%%\%${subst}\%*}"
post="${val#*\%${subst}\%}"
result="${result}${pre}${replace}"
val="$post"
done
result="${result}${val}"
printf '%s\n' "$result"
}
# From: install.sh }}}
expand_all() {
local val="$1"
shift
local tag lhs rhs
for tag; do
lhs="${tag%%:*}"
rhs="${tag#*:}"
val="$(expand_config_value "$val" "$lhs" "$rhs")"
done
printf '%s\n' "$val"
}
declare -a all_channels=() all_tools=() expansions=() platform_expands=() tool_jq=()
note "Building data (slowly, can be rewritten to Python to be faster)"
all_channels+=($(grab_channelfile_line CHANNELS))
all_tools+=($(grab_channelfile_line TOOLS))
# jchdata goes into synadia-nats-channels.json
jchdata='{}'
# jplatformdata goes into synadia-nats-platforms.json
jplatformdata='{}'
for channel in "${all_channels[@]}"; do
jchannel='{}'
case "$channel" in
nightly)
jchannel="$(jq <<<"$jchannel" --arg U "$NIGHTLY_DATE_URL" '.version_url = $U')"
;;
esac
jexpanded_channel="$(jq <<<"$jchannel" --arg C "$channel" '.platforms = {}')"
for tool in "${all_tools[@]}"; do
suffix="${channel}_${tool}"
version='' zipfile='' checksumfile='' urldir='' executable='' jtool='' tool_object=''
zipfile="$(grab_channelfile_line "ZIPFILE_${suffix}")"
checksumfile="$(grab_channelfile_line "CHECKSUMS_${suffix}")"
urldir="$(grab_channelfile_line "URLDIR_${suffix}")"
jtool="$(jq -nr --arg Z "$zipfile" --arg C "$checksumfile" --arg U "$urldir" '.zipfile = $Z | .checksumfile = $C | .urldir = $U')"
# Directives used to invoke expand_all:
expansions=( "TOOLNAME:$tool" "ZIPFILE:$zipfile" "CHECKFILE:$checksumfile")
# See jexpanded_channel below in the platform loop (for synadia-nats-platforms.json):
tool_jq=( --arg T "$tool" )
tool_object='executable: $E, zip_url: $Z, checksum_url: $C'
case "$channel" in
nightly)
expansions+=( "VERSIONTAG:%NIGHTLY%" "VERSIONNOV:%NIGHTLY%" )
;;
*)
version="$(grab_channelfile_line "VERSION_${suffix}")"
jtool="$(jq <<<"$jtool" --arg V "$version" '.version = $V')"
expansions+=( "VERSIONTAG:$version" "VERSIONNOV:${version#v}" )
tool_jq+=( --arg VT "$version" --arg VB "${version#v}" )
tool_object="${tool_object}"', version_tag: $VT, version_bare: $VB'
;;
esac
jchannel="$(jq <<<"$jchannel" --arg T "$tool" --argjson P "$jtool" '.[$T] = $P')"
for platform in "${SUPPORTED_PLATFORMS[@]}"; do
executable="$tool${PLATFORM_EXE_EXTENSION[$platform]:+.}${PLATFORM_EXE_EXTENSION[$platform]:-}"
jexpanded_channel="$(jq <<<"$jexpanded_channel" --arg P "$platform" '.platforms[$P] //= {tools: {}}')"
platform_expands=( "${expansions[@]}" "OSNAME:${platform%%-*}" "GOARCH:${platform#*-}" )
zip_url="$(expand_all "${urldir}${zipfile}" "${platform_expands[@]}")"
chk_url="$(expand_all "${urldir}${checksumfile}" "${platform_expands[@]}")"
jexpanded_channel="$(jq <<<"$jexpanded_channel" \
"${tool_jq[@]}" --arg P "$platform" --arg Z "$zip_url" --arg C "$chk_url" --arg E "$executable" \
'.platforms[$P].tools[$T] = '"{ $tool_object }")"
done
done
jchdata="$(jq <<<"$jchdata" --arg C "$channel" --argjson P "$jchannel" '.[$C] = $P')"
jplatformdata="$(jq <<<"$jplatformdata" --arg C "$channel" --argjson P "$jexpanded_channel" '.[$C] = $P')"
done
[[ -d "$DEPLOY_DIR" ]] || mkdir -pv -- "$DEPLOY_DIR"
note "Writing: $OUT_CHANNELS"
printf '%s\n' > "$OUT_CHANNELS" "$jchdata"
note "Writing: $OUT_PLATFORMS"
printf '%s\n' > "$OUT_PLATFORMS" "$jplatformdata"