Refactor setup workflow
This commit is contained in:
99
Scripts/bin/install.sh
Normal file
99
Scripts/bin/install.sh
Normal file
@@ -0,0 +1,99 @@
|
||||
#!/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"
|
||||
TARGET_DIR="$HOME/.local/bin"
|
||||
|
||||
ensure_deps() {
|
||||
local missing=()
|
||||
|
||||
for cmd in jq curl tar; 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
|
||||
}
|
||||
|
||||
detect_arch() {
|
||||
case "$(uname -m)" in
|
||||
x86_64) printf 'x86_64\n' ;;
|
||||
aarch64|arm64) printf 'aarch64\n' ;;
|
||||
*)
|
||||
printf 'Unsupported architecture: %s\n' "$(uname -m)" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
install_tool() {
|
||||
local tool="$1"
|
||||
local arch version owner repo asset binary_rel url tmp_dir archive_path extracted_path target_path
|
||||
|
||||
arch="$(detect_arch)"
|
||||
|
||||
if ! jq -e --arg tool "$tool" '.[$tool]' "$MANIFEST" >/dev/null; then
|
||||
printf 'Unsupported tool: %s\n' "$tool" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
version="$(jq -r --arg tool "$tool" '.[$tool].version' "$MANIFEST")"
|
||||
owner="$(jq -r --arg tool "$tool" '.[$tool].owner' "$MANIFEST")"
|
||||
repo="$(jq -r --arg tool "$tool" '.[$tool].repo' "$MANIFEST")"
|
||||
asset="$(jq -r --arg tool "$tool" --arg arch "$arch" '.[$tool].linux[$arch].asset' "$MANIFEST")"
|
||||
binary_rel="$(jq -r --arg tool "$tool" --arg arch "$arch" '.[$tool].linux[$arch].binary' "$MANIFEST")"
|
||||
|
||||
if [ -z "$asset" ] || [ "$asset" = "null" ] || [ -z "$binary_rel" ] || [ "$binary_rel" = "null" ]; then
|
||||
printf 'No Linux asset mapping for %s on %s\n' "$tool" "$arch" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$TARGET_DIR"
|
||||
tmp_dir="$(mktemp -d)"
|
||||
archive_path="$tmp_dir/$asset"
|
||||
url="https://github.com/$owner/$repo/releases/download/$version/$asset"
|
||||
|
||||
printf 'Installing %s %s\n' "$tool" "$version"
|
||||
curl -fL "$url" -o "$archive_path"
|
||||
tar -xzf "$archive_path" -C "$tmp_dir"
|
||||
|
||||
extracted_path="$tmp_dir/$binary_rel"
|
||||
if [ ! -f "$extracted_path" ]; then
|
||||
printf 'Expected binary not found after extraction: %s\n' "$binary_rel" >&2
|
||||
rm -rf "$tmp_dir"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
target_path="$TARGET_DIR/$tool"
|
||||
install -m 755 "$extracted_path" "$target_path"
|
||||
rm -rf "$tmp_dir"
|
||||
|
||||
printf 'Installed %s -> %s\n' "$tool" "$target_path"
|
||||
}
|
||||
|
||||
main() {
|
||||
ensure_deps
|
||||
|
||||
if [ "${1:-}" = "--all" ]; then
|
||||
while IFS= read -r tool; do
|
||||
install_tool "$tool"
|
||||
done < <(jq -r 'keys[]' "$MANIFEST")
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -z "${1:-}" ]; then
|
||||
printf 'Usage: %s [--all|tool]\n' "$0" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
install_tool "$1"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
135
Scripts/bin/update.sh
Normal file
135
Scripts/bin/update.sh
Normal file
@@ -0,0 +1,135 @@
|
||||
#!/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 "$@"
|
||||
Reference in New Issue
Block a user