Files
Dot-Zsh/Scripts/bin/update.sh
2026-05-31 23:24:18 +01:00

136 lines
3.0 KiB
Bash

#!/bin/bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")"
MANIFEST="$REPO_ROOT/Bins/versions.json"
ensure_deps() {
local missing=()
for cmd in jq curl python3; do
if ! command -v "$cmd" >/dev/null 2>&1; then
missing+=("$cmd")
fi
done
if [ "${#missing[@]}" -gt 0 ]; then
printf 'Missing required commands: %s\n' "${missing[*]}" >&2
exit 1
fi
}
github_api() {
local path="$1"
local auth_args=()
if [ -n "${GITHUB_TOKEN:-}" ]; then
auth_args=(-H "Authorization: Bearer $GITHUB_TOKEN")
fi
curl -fsSL \
-H "Accept: application/vnd.github+json" \
"${auth_args[@]}" \
"https://api.github.com${path}"
}
list_versions() {
local tool="$1" owner repo
if ! jq -e --arg tool "$tool" '.[$tool]' "$MANIFEST" >/dev/null; then
printf 'Unsupported tool: %s\n' "$tool" >&2
exit 1
fi
owner="$(jq -r --arg tool "$tool" '.[$tool].owner' "$MANIFEST")"
repo="$(jq -r --arg tool "$tool" '.[$tool].repo' "$MANIFEST")"
github_api "/repos/$owner/$repo/releases?per_page=100" | jq -r '.[].tag_name'
}
select_version() {
local tool="$1"
local versions
versions="$(list_versions "$tool")"
if [ -z "$versions" ]; then
printf 'No releases found for %s\n' "$tool" >&2
exit 1
fi
if command -v fzf >/dev/null 2>&1; then
printf '%s\n' "$versions" | fzf --prompt="Select ${tool} version > " --height=20 --reverse
else
printf '%s\n' "$versions" | sed -n '1,20p' >&2
printf 'fzf is not installed, so pass a version explicitly.\n' >&2
exit 1
fi
}
update_version() {
local tool="$1" version="$2"
local tmp_file
if [ -z "$version" ]; then
printf 'No version selected for %s\n' "$tool" >&2
exit 1
fi
tmp_file="$(mktemp)"
python3 - "$MANIFEST" "$tool" "$version" "$tmp_file" <<'PY'
import json
import pathlib
import sys
manifest_path = pathlib.Path(sys.argv[1])
tool = sys.argv[2]
version = sys.argv[3]
tmp_path = pathlib.Path(sys.argv[4])
data = json.loads(manifest_path.read_text())
if tool not in data:
raise SystemExit(f"Unsupported tool: {tool}")
data[tool]["version"] = version
tmp_path.write_text(json.dumps(data, indent=2) + "\n")
PY
mv "$tmp_file" "$MANIFEST"
printf 'Pinned %s to %s\n' "$tool" "$version"
}
main() {
local mode="update" tool version
ensure_deps
if [ "${1:-}" = "--list" ]; then
mode="list"
shift
fi
tool="${1:-}"
version="${2:-}"
if [ -z "$tool" ]; then
printf 'Usage: %s [--list] tool [version]\n' "$0" >&2
exit 1
fi
case "$mode" in
list)
list_versions "$tool"
;;
update)
if [ -z "$version" ]; then
version="$(select_version "$tool")"
fi
update_version "$tool" "$version"
;;
esac
}
main "$@"