From 0593df837e498b25b4c807c02a26b9972bfcdd2f Mon Sep 17 00:00:00 2001 From: Don Williams Date: Wed, 8 Oct 2025 01:24:01 -0400 Subject: [PATCH] Added upgrade script, tag env variables On branch hl-051 Your branch is up to date with 'origin/hl-051'. Changes to be committed: new file: hypr-tags.env modified: install-scripts/aquamarine.sh modified: install-scripts/hyprgraphics.sh modified: install-scripts/hyprland-protocols.sh modified: install-scripts/hyprland-qt-support.sh modified: install-scripts/hyprland-qtutils.sh modified: install-scripts/hyprland.sh modified: install-scripts/hyprlang.sh modified: install-scripts/hyprutils.sh modified: install-scripts/hyprwayland-scanner.sh new file: update-hyprland.sh --- hypr-tags.env | 13 + install-scripts/aquamarine.sh | 2 + install-scripts/hyprgraphics.sh | 2 + install-scripts/hyprland-protocols.sh | 2 + install-scripts/hyprland-qt-support.sh | 2 + install-scripts/hyprland-qtutils.sh | 2 + install-scripts/hyprland.sh | 2 + install-scripts/hyprlang.sh | 2 + install-scripts/hyprutils.sh | 2 + install-scripts/hyprwayland-scanner.sh | 2 + update-hyprland.sh | 330 +++++++++++++++++++++++++ 11 files changed, 361 insertions(+) create mode 100644 hypr-tags.env create mode 100644 update-hyprland.sh diff --git a/hypr-tags.env b/hypr-tags.env new file mode 100644 index 0000000..f9b2ac7 --- /dev/null +++ b/hypr-tags.env @@ -0,0 +1,13 @@ +# Central tag overrides for the Hyprland stack +# You can edit these values or let update-hyprland.sh manage them. +# Each module script reads its TAG from these environment variables if set. + +HYPRLAND_TAG=v0.51.1 +AQUAMARINE_TAG=v0.9.2 +HYPRUTILS_TAG=v0.8.2 +HYPRLANG_TAG=v0.6.4 +HYPRGRAPHICS_TAG=v0.1.5 +HYPRWAYLAND_SCANNER_TAG=v0.4.5 +HYPRLAND_PROTOCOLS_TAG=v0.6.4 +HYPRLAND_QT_SUPPORT_TAG=v0.1.0 +HYPRLAND_QTUTILS_TAG=v0.1.4 diff --git a/install-scripts/aquamarine.sh b/install-scripts/aquamarine.sh index 5f5855a..b5ce758 100755 --- a/install-scripts/aquamarine.sh +++ b/install-scripts/aquamarine.sh @@ -6,6 +6,8 @@ #specific branch or release tag="v0.9.2" +# Allow environment override +if [ -n "${AQUAMARINE_TAG:-}" ]; then tag="$AQUAMARINE_TAG"; fi # Dry-run support DO_INSTALL=1 diff --git a/install-scripts/hyprgraphics.sh b/install-scripts/hyprgraphics.sh index a5ae9e9..8a7cf9b 100755 --- a/install-scripts/hyprgraphics.sh +++ b/install-scripts/hyprgraphics.sh @@ -9,6 +9,8 @@ hyprgraphics=( #specific branch or release tag="v0.1.5" +# Allow environment override +if [ -n "${HYPRGRAPHICS_TAG:-}" ]; then tag="$HYPRGRAPHICS_TAG"; fi # Dry-run support DO_INSTALL=1 diff --git a/install-scripts/hyprland-protocols.sh b/install-scripts/hyprland-protocols.sh index cbc6dbc..55740f6 100755 --- a/install-scripts/hyprland-protocols.sh +++ b/install-scripts/hyprland-protocols.sh @@ -6,6 +6,8 @@ #specific branch or release tag="v0.6.4" +# Allow environment override +if [ -n "${HYPRLAND_PROTOCOLS_TAG:-}" ]; then tag="$HYPRLAND_PROTOCOLS_TAG"; fi # Dry-run support DO_INSTALL=1 diff --git a/install-scripts/hyprland-qt-support.sh b/install-scripts/hyprland-qt-support.sh index 8fac32a..be1b491 100755 --- a/install-scripts/hyprland-qt-support.sh +++ b/install-scripts/hyprland-qt-support.sh @@ -16,6 +16,8 @@ qt_support=( #specific branch or release tag="v0.1.0" +# Allow environment override +if [ -n "${HYPRLAND_QT_SUPPORT_TAG:-}" ]; then tag="$HYPRLAND_QT_SUPPORT_TAG"; fi # Dry-run support DO_INSTALL=1 diff --git a/install-scripts/hyprland-qtutils.sh b/install-scripts/hyprland-qtutils.sh index 53f2c61..b21ec57 100755 --- a/install-scripts/hyprland-qtutils.sh +++ b/install-scripts/hyprland-qtutils.sh @@ -18,6 +18,8 @@ qtutils=( #specific branch or release tag="v0.1.4" +# Allow environment override +if [ -n "${HYPRLAND_QTUTILS_TAG:-}" ]; then tag="$HYPRLAND_QTUTILS_TAG"; fi # Dry-run support DO_INSTALL=1 diff --git a/install-scripts/hyprland.sh b/install-scripts/hyprland.sh index 5789f8d..aba1768 100755 --- a/install-scripts/hyprland.sh +++ b/install-scripts/hyprland.sh @@ -4,6 +4,8 @@ #specific branch or release tag="v0.50.1" +# Allow environment override +if [ -n "${HYPRLAND_TAG:-}" ]; then tag="$HYPRLAND_TAG"; fi # Dry-run support DO_INSTALL=1 diff --git a/install-scripts/hyprlang.sh b/install-scripts/hyprlang.sh index 7a10961..9ffc16c 100755 --- a/install-scripts/hyprlang.sh +++ b/install-scripts/hyprlang.sh @@ -6,6 +6,8 @@ #specific branch or release tag="v0.6.4" +# Allow environment override +if [ -n "${HYPRLANG_TAG:-}" ]; then tag="$HYPRLANG_TAG"; fi # Dry-run support DO_INSTALL=1 diff --git a/install-scripts/hyprutils.sh b/install-scripts/hyprutils.sh index f99fb3f..4ba5e2e 100755 --- a/install-scripts/hyprutils.sh +++ b/install-scripts/hyprutils.sh @@ -5,6 +5,8 @@ #specific branch or release tag="v0.8.2" +# Allow environment override +if [ -n "${HYPRUTILS_TAG:-}" ]; then tag="$HYPRUTILS_TAG"; fi # Dry-run support DO_INSTALL=1 diff --git a/install-scripts/hyprwayland-scanner.sh b/install-scripts/hyprwayland-scanner.sh index ebe9255..31b0b4e 100755 --- a/install-scripts/hyprwayland-scanner.sh +++ b/install-scripts/hyprwayland-scanner.sh @@ -9,6 +9,8 @@ scan_depend=( #specific branch or release tag="v0.4.5" +# Allow environment override +if [ -n "${HYPRWAYLAND_SCANNER_TAG:-}" ]; then tag="$HYPRWAYLAND_SCANNER_TAG"; fi # Dry-run support DO_INSTALL=1 diff --git a/update-hyprland.sh b/update-hyprland.sh new file mode 100644 index 0000000..5c502dc --- /dev/null +++ b/update-hyprland.sh @@ -0,0 +1,330 @@ +#!/usr/bin/env bash +# update-hyprland.sh +# Manage and build just the Hyprland stack (Hyprland + companion apps/libs) +# - Maintains a central tag file (hypr-tags.env) with versions +# - Can fetch latest release tags from GitHub and update hypr-tags.env +# - Can restore tags from a backup +# - Can run a dry-run build (compile only) or install build of the stack +# +# Usage examples: +# chmod +x ./update-hyprland.sh +# ./update-hyprland.sh --dry-run # compile-only using current tags +# ./update-hyprland.sh --install # compile + install using current tags +# ./update-hyprland.sh --fetch-latest --dry-run # refresh tags to latest, then dry-run +# ./update-hyprland.sh --set HYPRLAND=v0.51.1 --dry-run # set one or more tags +# ./update-hyprland.sh --restore --dry-run # restore most recent backup of tags and dry-run +# ./update-hyprland.sh --only hyprland,hyprutils --dry-run +# ./update-hyprland.sh --skip aquamarine --install +# ./update-hyprland.sh --with-deps --dry-run +# ./update-hyprland.sh --fetch-latest --via-helper # use dry-run-build.sh for a summary-only run +# +# Notes: +# - Requires curl; for --fetch-latest, jq is recommended (installed by 00-dependencies.sh) +# - Works from repo root; do not cd into install-scripts/ + +set -euo pipefail + +REPO_ROOT=$(pwd) +TAGS_FILE="$REPO_ROOT/hypr-tags.env" +LOG_DIR="$REPO_ROOT/Install-Logs" +mkdir -p "$LOG_DIR" +TS=$(date +%F-%H%M%S) +SUMMARY_LOG="$LOG_DIR/update-hypr-$TS.log" + +# Default module order (core first, then Hyprland) +DEFAULT_MODULES=( + hyprutils + hyprlang + hyprgraphics + hyprwayland-scanner + hyprland-protocols + hyprland-qt-support + hyprland-qtutils + aquamarine + hyprland +) + +WITH_DEPS=0 +DO_INSTALL=0 +DO_DRY_RUN=0 +FETCH_LATEST=0 +RESTORE=0 +VIA_HELPER=0 +ONLY_LIST="" +SKIP_LIST="" +SET_ARGS=() + +usage() { + sed -n '2,120p' "$0" | sed -n '/^# /p' | sed 's/^# \{0,1\}//' +} + +ensure_tags_file() { + if [[ ! -f "$TAGS_FILE" ]]; then + echo "[INFO] Creating default tags file: $TAGS_FILE" | tee -a "$SUMMARY_LOG" + cat > "$TAGS_FILE" <<'EOF' +HYPRLAND_TAG=v0.50.1 +AQUAMARINE_TAG=v0.9.2 +HYPRUTILS_TAG=v0.8.2 +HYPRLANG_TAG=v0.6.4 +HYPRGRAPHICS_TAG=v0.1.5 +HYPRWAYLAND_SCANNER_TAG=v0.4.5 +HYPRLAND_PROTOCOLS_TAG=v0.6.4 +HYPRLAND_QT_SUPPORT_TAG=v0.1.0 +HYPRLAND_QTUTILS_TAG=v0.1.4 +EOF + fi +} + +backup_tags() { + ensure_tags_file + cp "$TAGS_FILE" "$TAGS_FILE.bak-$TS" + echo "[INFO] Backed up $TAGS_FILE to $TAGS_FILE.bak-$TS" | tee -a "$SUMMARY_LOG" +} + +restore_tags() { + latest_bak=$(ls -1t "$TAGS_FILE".bak-* 2>/dev/null | head -n1 || true) + if [[ -z "$latest_bak" ]]; then + echo "[ERROR] No backup tags file found." | tee -a "$SUMMARY_LOG" + exit 1 + fi + cp "$latest_bak" "$TAGS_FILE" + echo "[INFO] Restored tags from $latest_bak" | tee -a "$SUMMARY_LOG" +} + +set_tags_from_args() { + ensure_tags_file + backup_tags + # load existing into assoc map + declare -A map + while IFS='=' read -r k v; do + [[ -z "$k" || "$k" =~ ^# ]] && continue + map[$k]="$v" + done < "$TAGS_FILE" + for kv in "${SET_ARGS[@]}"; do + key="${kv%%=*}" + val="${kv#*=}" + case "$key" in + HYPRLAND|hyprland) key=HYPRLAND_TAG ;; + AQUAMARINE|aquamarine) key=AQUAMARINE_TAG ;; + HYPRUTILS|hyprutils) key=HYPRUTILS_TAG ;; + HYPRLANG|hyprlang) key=HYPRLANG_TAG ;; + HYPRGRAPHICS|hyprgraphics) key=HYPRGRAPHICS_TAG ;; + HYPRWAYLAND_SCANNER|hyprwayland-scanner|hyprwayland_scanner) key=HYPRWAYLAND_SCANNER_TAG ;; + HYPRLAND_PROTOCOLS|hyprland-protocols|hyprland_protocols) key=HYPRLAND_PROTOCOLS_TAG ;; + HYPRLAND_QT_SUPPORT|hyprland-qt-support|hyprland_qt_support) key=HYPRLAND_QT_SUPPORT_TAG ;; + HYPRLAND_QTUTILS|hyprland-qtutils|hyprland_qtutils) key=HYPRLAND_QTUTILS_TAG ;; + esac + map[$key]="$val" + done + { + for k in "${!map[@]}"; do + echo "$k=${map[$k]}" + done | sort + } > "$TAGS_FILE" + echo "[INFO] Updated $TAGS_FILE with provided tags" | tee -a "$SUMMARY_LOG" +} + +# Fetch latest release tags from GitHub for the stack +fetch_latest_tags() { + ensure_tags_file + backup_tags + + # Require curl; jq is preferred. Fallback to grep/sed if jq is missing. + if ! command -v curl >/dev/null 2>&1; then + echo "[ERROR] curl is required." | tee -a "$SUMMARY_LOG" + exit 1 + fi + + declare -A repos=( + [HYPRLAND_TAG]="hyprwm/Hyprland" + [AQUAMARINE_TAG]="hyprwm/aquamarine" + [HYPRUTILS_TAG]="hyprwm/hyprutils" + [HYPRLANG_TAG]="hyprwm/hyprlang" + [HYPRGRAPHICS_TAG]="hyprwm/hyprgraphics" + [HYPRWAYLAND_SCANNER_TAG]="hyprwm/hyprwayland-scanner" + [HYPRLAND_PROTOCOLS_TAG]="hyprwm/hyprland-protocols" + [HYPRLAND_QT_SUPPORT_TAG]="hyprwm/hyprland-qt-support" + [HYPRLAND_QTUTILS_TAG]="hyprwm/hyprland-qtutils" + ) + + declare -A tags + + for key in "${!repos[@]}"; do + repo="${repos[$key]}" + url="https://api.github.com/repos/$repo/releases/latest" + echo "[INFO] Fetching latest tag for $repo" | tee -a "$SUMMARY_LOG" + body=$(curl -fsSL "$url" || true) + if [[ -z "$body" ]]; then + echo "[WARN] Empty response for $repo; leaving $key unchanged" | tee -a "$SUMMARY_LOG" + continue + fi + if command -v jq >/dev/null 2>&1; then + tag=$(printf '%s' "$body" | jq -r '.tag_name // empty') + else + tag=$(printf '%s' "$body" | grep -m1 '"tag_name"' | sed -E 's/.*"tag_name"\s*:\s*"([^"]+)".*/\1/') + fi + if [[ -n "$tag" ]]; then + tags[$key]="$tag" + else + echo "[WARN] Could not parse tag for $repo; leaving $key unchanged" | tee -a "$SUMMARY_LOG" + fi + done + + # Merge into existing file + declare -A map + while IFS='=' read -r k v; do + [[ -z "$k" || "$k" =~ ^# ]] && continue + map[$k]="$v" + done < "$TAGS_FILE" + + for k in "${!tags[@]}"; do + map[$k]="${tags[$k]}" + done + + { + for k in "${!map[@]}"; do + echo "$k=${map[$k]}" + done | sort + } > "$TAGS_FILE" + + echo "[INFO] Refreshed tags written to $TAGS_FILE" | tee -a "$SUMMARY_LOG" +} + +# Build runner using module scripts. Uses env vars from TAGS_FILE. +run_stack() { + # shellcheck disable=SC1090 + source "$TAGS_FILE" + # Export tags so child scripts inherit them + export HYPRLAND_TAG AQUAMARINE_TAG HYPRUTILS_TAG HYPRLANG_TAG HYPRGRAPHICS_TAG HYPRWAYLAND_SCANNER_TAG HYPRLAND_PROTOCOLS_TAG HYPRLAND_QT_SUPPORT_TAG HYPRLAND_QTUTILS_TAG + + # Optionally install dependencies (not dry-run) + if [[ $WITH_DEPS -eq 1 ]]; then + echo "[INFO] Installing dependencies via 00-dependencies.sh" | tee -a "$SUMMARY_LOG" + if ! "$REPO_ROOT/install-scripts/00-dependencies.sh"; then + echo "[ERROR] Dependencies installation failed." | tee -a "$SUMMARY_LOG" + exit 1 + fi + fi + + # Build module list based on --only/--skip + local modules + if [[ -n "$ONLY_LIST" ]]; then + IFS=',' read -r -a modules <<< "$ONLY_LIST" + else + modules=("${DEFAULT_MODULES[@]}") + fi + if [[ -n "$SKIP_LIST" ]]; then + IFS=',' read -r -a _skips <<< "$SKIP_LIST" + local filtered=() + for m in "${modules[@]}"; do + local skip_it=0 + for s in "${_skips[@]}"; do + [[ "$m" == "$s" ]] && { skip_it=1; break; } + done + [[ $skip_it -eq 0 ]] && filtered+=("$m") + done + modules=("${filtered[@]}") + fi + + declare -A results + + for mod in "${modules[@]}"; do + local script="$REPO_ROOT/install-scripts/$mod.sh" + echo "\n=== $mod ===" | tee -a "$SUMMARY_LOG" + [[ -f "$script" ]] || { echo "[WARN] Missing $script" | tee -a "$SUMMARY_LOG"; results[$mod]="MISSING"; continue; } + chmod +x "$script" || true + if [[ $DO_DRY_RUN -eq 1 ]]; then + if DRY_RUN=1 "$script"; then results[$mod]="PASS"; else results[$mod]="FAIL"; fi + else + if "$script"; then results[$mod]="INSTALLED"; else results[$mod]="FAIL"; fi + fi + done + + { + echo "\nSummary:" + for mod in "${modules[@]}"; do + printf "%-24s %s\n" "$mod" "${results[$mod]:-SKIPPED}" + done + echo "\nLogs under: $LOG_DIR. This run: $SUMMARY_LOG" + } | tee -a "$SUMMARY_LOG" + + # Non-zero on any FAILs + local failed=0 + for mod in "${modules[@]}"; do + [[ "${results[$mod]:-}" == FAIL ]] && failed=1 + done + return $failed +} + +# Parse args +while [[ $# -gt 0 ]]; do + case "$1" in + -h|--help) usage; exit 0 ;; + --with-deps) WITH_DEPS=1; shift ;; + --dry-run) DO_DRY_RUN=1; shift ;; + --install) DO_INSTALL=1; shift ;; + --fetch-latest) FETCH_LATEST=1; shift ;; + --restore) RESTORE=1; shift ;; + --via-helper) VIA_HELPER=1; shift ;; + --only) ONLY_LIST=${2:-}; shift 2 ;; + --skip) SKIP_LIST=${2:-}; shift 2 ;; + --set) + shift + while [[ $# -gt 0 && "$1" != --* ]]; do + SET_ARGS+=("$1") + shift + done + ;; + *) echo "Unknown argument: $1"; exit 2 ;; + esac +done + +# Validate options +if [[ $DO_INSTALL -eq 1 && $DO_DRY_RUN -eq 1 ]]; then + echo "[ERROR] Use either --dry-run or --install, not both." | tee -a "$SUMMARY_LOG" + exit 2 +fi + +ensure_tags_file + +# Apply tag operations +if [[ $RESTORE -eq 1 ]]; then + restore_tags +fi +if [[ ${#SET_ARGS[@]} -gt 0 ]]; then + set_tags_from_args +fi +if [[ $FETCH_LATEST -eq 1 ]]; then + fetch_latest_tags +fi + +# Run the stack +if [[ $DO_DRY_RUN -eq 0 && $DO_INSTALL -eq 0 ]]; then + echo "[INFO] No build option specified. Defaulting to --dry-run." | tee -a "$SUMMARY_LOG" + DO_DRY_RUN=1 +fi + +# If using helper, delegate to dry-run-build.sh for summary-only output +if [[ $VIA_HELPER -eq 1 ]]; then + if [[ $DO_INSTALL -eq 1 ]]; then + echo "[ERROR] --via-helper cannot be combined with --install (helper is dry-run only)." | tee -a "$SUMMARY_LOG" + exit 2 + fi + # shellcheck disable=SC1090 + source "$TAGS_FILE" + export HYPRLAND_TAG AQUAMARINE_TAG HYPRUTILS_TAG HYPRLANG_TAG HYPRGRAPHICS_TAG HYPRWAYLAND_SCANNER_TAG HYPRLAND_PROTOCOLS_TAG HYPRLAND_QT_SUPPORT_TAG HYPRLAND_QTUTILS_TAG + helper="$REPO_ROOT/dry-run-build.sh" + if [[ ! -x "$helper" ]]; then + echo "[ERROR] dry-run-build.sh not found or not executable at $helper" | tee -a "$SUMMARY_LOG" + exit 1 + fi + args=() + [[ $WITH_DEPS -eq 1 ]] && args+=("--with-deps") + [[ -n "$ONLY_LIST" ]] && args+=("--only" "$ONLY_LIST") + [[ -n "$SKIP_LIST" ]] && args+=("--skip" "$SKIP_LIST") + echo "[INFO] Delegating to dry-run-build.sh ${args[*]}" | tee -a "$SUMMARY_LOG" + "$helper" "${args[@]}" + exit $? +fi + +run_stack