Migration This is my new public git source viewer. Source coming soon. Please contact with concerns/bugs. Contact me

users/ryan/modules/zen/lock.sh

42a3265eaa10cf190dfea678736835eaf66fbf97 · 2.5 KB · 61 lines raw

1 #!/usr/bin/env bash
2 # Resolve ryan.zen.extensions into extensions.lock.json via AMO's v5 API.
3 #
4 # lock.sh <attr> [--missing]
5 #
6 # <attr> is the evaluated home-manager config, e.g.
7 # ~/.config/home-manager#homeConfigurations.ryan.config
8 # ~/.config/nix#darwinConfigurations.<host>.config.home-manager.users.ryan
9 #
10 # Default: re-resolve everything (unpinned entries move to AMO's current version).
11 # --missing: keep existing entries that still satisfy the spec; resolve the rest.
12 #
13 # Only ryan.zen.extensions.*.{id,version} is evaluated, which never touches the
14 # lock, so this works when the lock is empty or stale.
15 # Needs: nix (>= 2.19 for `nix hash convert`), curl, jq.
16 set -euo pipefail
17
18 attr="${1:?usage: lock.sh <hm-config-attr> [--missing]}"
19 mode="${2:-all}"
20 here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
21 lockfile="$here/extensions.lock.json"
22 api="https://addons.mozilla.org/api/v5/addons/addon"
23
24 spec="$(nix eval --json "$attr.ryan.zen.extensions" \
25 --apply 'es: builtins.mapAttrs (_: e: { inherit (e) id version; }) (builtins.removeAttrs es (builtins.filter (n: !es.${n}.enable) (builtins.attrNames es)))')"
26 old="$(cat "$lockfile" 2>/dev/null || echo '{}')"
27 new='{}'
28
29 uri() { jq -rn --arg s "$1" '$s|@uri'; }
30
31 for name in $(jq -r 'keys[]' <<<"$spec"); do
32 id="$(jq -r --arg n "$name" '.[$n].id' <<<"$spec")"
33 want="$(jq -r --arg n "$name" '.[$n].version // empty' <<<"$spec")"
34
35 if [ "$mode" = "--missing" ]; then
36 keep="$(jq -c --arg n "$name" --arg id "$id" --arg v "$want" \
37 '.[$n] | select(. != null and .id == $id and ($v == "" or .version == $v))' <<<"$old")"
38 if [ -n "$keep" ]; then
39 new="$(jq --arg n "$name" --argjson e "$keep" '.[$n] = $e' <<<"$new")"
40 continue
41 fi
42 fi
43
44 if [ -n "$want" ]; then
45 v="$(curl -fsSL "$api/$(uri "$id")/versions/$(uri "$want")/")"
46 else
47 v="$(curl -fsSL "$api/$(uri "$id")/" | jq '.current_version')"
48 fi
49
50 version="$(jq -r '.version' <<<"$v")"
51 url="$(jq -r '.file.url' <<<"$v")"
52 algo_hex="$(jq -r '.file.hash' <<<"$v")" # "sha256:<hex>"
53 [ "${algo_hex%%:*}" = sha256 ] || { echo "$name: unexpected hash $algo_hex" >&2; exit 1; }
54 hash="$(nix hash convert --hash-algo sha256 --to sri "${algo_hex#sha256:}")"
55
56 echo "$name ($id) -> $version" >&2
57 new="$(jq --arg n "$name" --arg id "$id" --arg ver "$version" --arg url "$url" --arg h "$hash" \
58 '.[$n] = {id: $id, version: $ver, url: $url, hash: $h}' <<<"$new")"
59 done
60
61 jq -S . <<<"$new" > "$lockfile.tmp" && mv "$lockfile.tmp" "$lockfile"