refactor: Valve mirror module, golden menu test, local and CI checks

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
theupriserandClaude Sonnet 5.5 committed 2026-10-03 11:18:30 +02:00
1 parent 96336fa80f
commit 0cd92555d2
11 files changed
+113 -47

No files matched your search

+15
View File
@@ -0,0 +1,15 @@
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 4
[*.{yml,yaml,qml}]
indent_size = 2
[Makefile]
indent_style = tab
+1 -1
View File
@@ -40,7 +40,7 @@ jobs:
- name: Check - name: Check
run: | run: |
bash -n dist/steamify.sh bash -n dist/steamify.sh
python3 -m py_compile ui/steamify-ui python3 -m py_compile ui/steamify-ui patches/*.py
# shellcheck through an action that brings its own binary: GitHub's runner has it installed, # shellcheck through an action that brings its own binary: GitHub's runner has it installed,
# Gitea's act_runner image doesn't. One file per run, as before (the exceptions are the bundle's). # Gitea's act_runner image doesn't. One file per run, as before (the exceptions are the bundle's).
+2
View File
@@ -0,0 +1,2 @@
# The modules share variables across files once bundled (see AGENTS.md).
disable=SC2034,SC2154
+6
View File
@@ -5,6 +5,12 @@ All notable changes, per version and per commit. Versions follow
`steamify.sh`. Versions before 0.7.0 were numbered afterwards, `steamify.sh`. Versions before 0.7.0 were numbered afterwards,
one per merged pull request. one per merged pull request.
## Unreleased
- **refactor: Valve's package mirror in one module (`lib/valve-mirror.sh`: newest repo, package database fields, checksummed download); the SteamOS extras, CEC driver, BIOS lookup and os-release version used four copies**
- **test: the menu rules, the plan and the app's and installer's JSON are checked against a golden file (`tests/menu-test.sh` in steamify-cachyos-dev); `make check`, `.editorconfig`, `.shellcheckrc`**
- **docs: README lists the sources and projects Steamify builds on, with licences and thanks**
## 2.11.1 - 2026-10-02 ## 2.11.1 - 2026-10-02
- `d70aeb8` **docs: new README screenshots of the app (2.11 menu) on a Steam Machine and on an NVIDIA PC, and the README names the opt-in "Start Steam silently in desktop mode" and the icons as an option of the conversion** - `d70aeb8` **docs: new README screenshots of the app (2.11 menu) on a Steam Machine and on an NVIDIA PC, and the README names the opt-in "Start Steam silently in desktop mode" and the icons as an option of the conversion**
+24
View File
@@ -0,0 +1,24 @@
# Local checks, the same as CI's: make check
SH := steamify.sh $(wildcard lib/*.sh) ui/steamify-app.sh .github/tools/bundle.sh
# The unit tests live in ../steamify-cachyos-dev/tests (REPO points at this checkout).
DEV ?= ../steamify-cachyos-dev
TESTS := $(wildcard $(DEV)/tests/*-test.sh)
.PHONY: check syntax lint test bundle fmt-check
check: syntax lint test bundle
syntax:
@for f in $(SH); do bash -n "$$f" || exit 1; done
python3 -m py_compile ui/steamify-ui patches/*.py
lint:
@command -v shellcheck >/dev/null && shellcheck -S warning $(SH) || echo "shellcheck not installed: skipped"
test:
@for t in $(TESTS); do echo "== $$t"; REPO="$(CURDIR)" bash "$$t" || exit 1; done
bundle:
.github/tools/bundle.sh dist/steamify.sh
fmt-check:
@command -v shfmt >/dev/null && shfmt -d -i 4 -ci $(SH) || echo "shfmt not installed: skipped"
+6 -6
View File
@@ -30,16 +30,16 @@ bios_lookup_newest() {
[[ -n "${BIOS_LOOKED_UP:-}" ]] && return 0 [[ -n "${BIOS_LOOKED_UP:-}" ]] && return 0
BIOS_LOOKED_UP=1; BIOS_NEWEST="" BIOS_LOOKED_UP=1; BIOS_NEWEST=""
local tmp desc local tmp desc
BIOS_REPO="$(curl -fsL --max-time 10 "$VALVE_MIRROR/" | grep -oE "$BIOS_REPO_PREFIX-[0-9]+\.[0-9]+/" | tr -d / | sort -uV | tail -n 1)" BIOS_REPO="$(valve_newest_repo "$BIOS_REPO_PREFIX" 10)"
[[ -n "$BIOS_REPO" ]] || return 1 [[ -n "$BIOS_REPO" ]] || return 1
tmp="$(mktemp -d)" tmp="$(mktemp -d)"
if curl -fsL --max-time 30 "$VALVE_MIRROR/$BIOS_REPO/os/x86_64/$BIOS_REPO.files" -o "$tmp/files" && if curl -fsL --max-time 30 "$(valve_repo_url "$BIOS_REPO")/$BIOS_REPO.files" -o "$tmp/files" &&
curl -fsL --max-time 30 "$VALVE_MIRROR/$BIOS_REPO/os/x86_64/$BIOS_REPO.db" -o "$tmp/db"; then curl -fsL --max-time 30 "$(valve_repo_url "$BIOS_REPO")/$BIOS_REPO.db" -o "$tmp/db"; then
desc="$(tar -tf "$tmp/files" 2>/dev/null | grep -E '^fremont-hw-support-[0-9][^/]*/files$' | head -n 1)" desc="$(tar -tf "$tmp/files" 2>/dev/null | grep -E '^fremont-hw-support-[0-9][^/]*/files$' | head -n 1)"
[[ -n "$desc" ]] && BIOS_CAB="$(tar -xOf "$tmp/files" "$desc" | grep -E '^usr/share/fwupd/.*\.cab$' | head -n 1)" [[ -n "$desc" ]] && BIOS_CAB="$(tar -xOf "$tmp/files" "$desc" | grep -E '^usr/share/fwupd/.*\.cab$' | head -n 1)"
desc="${desc%/files}/desc" desc="${desc%/files}/desc"
BIOS_PKG="$(tar -xOf "$tmp/db" "$desc" 2>/dev/null | awk '/^%FILENAME%$/ { getline; print }')" BIOS_PKG="$(valve_desc_field "$tmp/db" "$desc" FILENAME)"
BIOS_SHA256="$(tar -xOf "$tmp/db" "$desc" 2>/dev/null | awk '/^%SHA256SUM%$/ { getline; print }')" BIOS_SHA256="$(valve_desc_field "$tmp/db" "$desc" SHA256SUM)"
[[ -n "${BIOS_CAB:-}" && -n "$BIOS_PKG" && -n "$BIOS_SHA256" ]] && BIOS_NEWEST="$(basename "$BIOS_CAB" .cab)" [[ -n "${BIOS_CAB:-}" && -n "$BIOS_PKG" && -n "$BIOS_SHA256" ]] && BIOS_NEWEST="$(basename "$BIOS_CAB" .cab)"
fi fi
rm -rf "$tmp" rm -rf "$tmp"
@@ -143,7 +143,7 @@ bios_prepare() {
{ err "Installing fwupd failed."; return 1; } { err "Installing fwupd failed."; return 1; }
rm -rf "$BIOS_STAGE_DIR"; mkdir -p "$BIOS_STAGE_DIR"; chmod 700 "$BIOS_STAGE_DIR" rm -rf "$BIOS_STAGE_DIR"; mkdir -p "$BIOS_STAGE_DIR"; chmod 700 "$BIOS_STAGE_DIR"
info "Downloading $BIOS_PKG ($BIOS_REPO)..." info "Downloading $BIOS_PKG ($BIOS_REPO)..."
if ! curl -fsSL "$VALVE_MIRROR/$BIOS_REPO/os/x86_64/$BIOS_PKG" -o "$BIOS_STAGE_DIR/pkg.tar.zst" || if ! curl -fsSL "$(valve_repo_url "$BIOS_REPO")/$BIOS_PKG" -o "$BIOS_STAGE_DIR/pkg.tar.zst" ||
! echo "$BIOS_SHA256 $BIOS_STAGE_DIR/pkg.tar.zst" | sha256sum -c --quiet - || ! echo "$BIOS_SHA256 $BIOS_STAGE_DIR/pkg.tar.zst" | sha256sum -c --quiet - ||
! tar -I unzstd -xf "$BIOS_STAGE_DIR/pkg.tar.zst" -C "$BIOS_STAGE_DIR" "$BIOS_CAB"; then ! tar -I unzstd -xf "$BIOS_STAGE_DIR/pkg.tar.zst" -C "$BIOS_STAGE_DIR" "$BIOS_CAB"; then
err "Downloading or verifying $BIOS_PKG failed; the BIOS was not touched." err "Downloading or verifying $BIOS_PKG failed; the BIOS was not touched."
+2 -18
View File
@@ -113,24 +113,8 @@ cec_repair() { cec_installed && ! cec_status; }
fetch_holo_pkg() { fetch_holo_pkg() {
# fetch_holo_pkg <dir> <package>: download the newest <package> from # fetch_holo_pkg <dir> <package>: download the newest <package> from
# Valve's newest holo repository into <dir> and print its path. The # Valve's newest holo repository into <dir> and print its path.
# SHA-256 comes from Valve's package index and is verified. valve_fetch_pkg holo "$2" "$1"
local dir="$1" name="$2" repo desc file_name sha256
repo="$(curl -fsL "$VALVE_MIRROR/" | grep -oE 'holo-[0-9]+\.[0-9]+/' | tr -d / | sort -V | tail -n 1)"
if [[ ! -f "$dir/holo.db" ]]; then
[[ -n "$repo" ]] && curl -fsL "$VALVE_MIRROR/$repo/os/x86_64/$repo.db" -o "$dir/holo.db" ||
{ err "Couldn't read Valve's SteamOS package index ($VALVE_MIRROR)."; return 1; }
fi
desc="$(tar -tf "$dir/holo.db" 2>/dev/null | grep -E "^$name-[0-9][^/]*/desc$" | head -n 1)"
[[ -n "$desc" ]] || { err "No $name in Valve's $repo repository."; return 1; }
file_name="$(tar -xOf "$dir/holo.db" "$desc" | awk '/^%FILENAME%$/ { getline; print }')"
sha256="$(tar -xOf "$dir/holo.db" "$desc" | awk '/^%SHA256SUM%$/ { getline; print }')"
info "Downloading $file_name ($repo)..." >&2
curl -fsL "$VALVE_MIRROR/$repo/os/x86_64/$file_name" -o "$dir/$file_name" ||
{ err "Downloading $file_name failed."; return 1; }
echo "$sha256 $dir/$file_name" | sha256sum -c --quiet - >&2 ||
{ err "Checksum mismatch for $file_name; not using it."; return 1; }
echo "$dir/$file_name"
} }
cec_enable() { cec_enable() {
+1 -1
View File
@@ -35,7 +35,7 @@ steamos_release() {
# capitals: steamos-3.9). Offline (e.g. in the installer): the one set # capitals: steamos-3.9). Offline (e.g. in the installer): the one set
# before, if any. # before, if any.
local v local v
v="$(curl -fsL --max-time 15 "$VALVE_MIRROR/" 2>/dev/null | grep -oE 'jupiter-[0-9]+\.[0-9]+/' | tr -d / | sort -V | tail -n 1)" v="$(valve_newest_repo jupiter 15)"
if [[ -n "$v" ]]; then echo "steamos-${v#jupiter-}" if [[ -n "$v" ]]; then echo "steamos-${v#jupiter-}"
else sed -n 's/^VERSION_ID=\(steamos-.*\)$/\1/p' /etc/os-release 2>/dev/null; fi else sed -n 's/^VERSION_ID=\(steamos-.*\)$/\1/p' /etc/os-release 2>/dev/null; fi
} }
+6 -20
View File
@@ -8,7 +8,6 @@
# package-owned); per-user settings go through the undo journal. # package-owned); per-user settings go through the undo journal.
# Sourced by steamify.sh; not meant to be run on its own. # Sourced by steamify.sh; not meant to be run on its own.
VALVE_MIRROR="https://steamdeck-packages.steamos.cloud/archlinux-mirror"
NESTED_DIR=/usr/local/share/applications/steam/holo-nested-desktop NESTED_DIR=/usr/local/share/applications/steam/holo-nested-desktop
EXTRAS_FILES=( EXTRAS_FILES=(
/usr/local/bin/holo-add-to-steam /usr/local/bin/holo-add-to-steam
@@ -23,25 +22,12 @@ STEAM_KEYBOARD_RULE=cachyos-gamescope-boot-steam-keyboard
fetch_valve_presets() { fetch_valve_presets() {
# fetch_valve_presets <dir>: download and extract the newest # fetch_valve_presets <dir>: download and extract the newest
# steamdeck-kde-presets into <dir>. The newest SteamOS release repo # steamdeck-kde-presets (from the newest SteamOS release repo, jupiter-3.9,
# (jupiter-3.9, jupiter-3.10, ...) is found on the mirror; its pacman # jupiter-3.10, ...) into <dir>.
# database gives the exact file name and SHA-256, which is verified. local dir="$1" pkg
local dir="$1" repo desc file_name sha256 pkg="$(valve_fetch_pkg jupiter steamdeck-kde-presets "$dir")" || return 1
repo="$(curl -fsL "$VALVE_MIRROR/" | grep -oE 'jupiter-[0-9]+\.[0-9]+/' | tr -d / | sort -V | tail -n 1)" tar -I unzstd -xf "$pkg" -C "$dir" usr/bin usr/share ||
[[ -n "$repo" ]] && curl -fsL "$VALVE_MIRROR/$repo/os/x86_64/$repo.db" -o "$dir/repo.db" || { err "Extracting $(basename "$pkg") failed."; return 1; }
{ err "Couldn't read Valve's SteamOS package index ($VALVE_MIRROR)."; return 1; }
desc="$(tar -tf "$dir/repo.db" 2>/dev/null | grep -E '^steamdeck-kde-presets-[0-9][^/]*/desc$' | head -n 1)"
[[ -n "$desc" ]] || { err "No steamdeck-kde-presets in Valve's $repo repository."; return 1; }
file_name="$(tar -xOf "$dir/repo.db" "$desc" | awk '/^%FILENAME%$/ { getline; print }')"
sha256="$(tar -xOf "$dir/repo.db" "$desc" | awk '/^%SHA256SUM%$/ { getline; print }')"
info "Downloading $file_name ($repo)..."
curl -fsL "$VALVE_MIRROR/$repo/os/x86_64/$file_name" -o "$dir/presets.pkg.tar.zst" ||
{ err "Downloading $file_name failed."; return 1; }
echo "$sha256 $dir/presets.pkg.tar.zst" | sha256sum -c --quiet - ||
{ err "Checksum mismatch for $file_name; not using it."; return 1; }
tar -I unzstd -xf "$dir/presets.pkg.tar.zst" -C "$dir" usr/bin usr/share ||
{ err "Extracting $file_name failed."; return 1; }
} }
extras_enable() { extras_enable() {
+49
View File
@@ -0,0 +1,49 @@
#!/bin/bash
# Valve's SteamOS package mirror: finding its newest repository and fetching a
# verified package from it. Used by the SteamOS extras, the Steam Machine CEC
# driver, the BIOS update and the os-release version.
# Sourced by steamify.sh; not meant to be run on its own.
VALVE_MIRROR="https://steamdeck-packages.steamos.cloud/archlinux-mirror"
valve_newest_repo() {
# valve_newest_repo <prefix> [max-seconds]: the newest <prefix>-X.Y repo
# (jupiter, holo), compared as versions: 3.10 is newer than 3.9. Prints
# nothing when the mirror can't be reached.
local -a limit=()
[[ -n "${2:-}" ]] && limit=(--max-time "$2")
curl -fsL "${limit[@]}" "$VALVE_MIRROR/" 2>/dev/null | grep -oE "$1-[0-9]+\.[0-9]+/" | tr -d / | sort -uV | tail -n 1
}
valve_repo_url() { echo "$VALVE_MIRROR/$1/os/x86_64"; }
valve_desc_field() {
# valve_desc_field <db> <desc path> <FIELD>: one value from a package's
# entry in a pacman database (FILENAME, SHA256SUM).
tar -xOf "$1" "$2" 2>/dev/null | awk -v f="%$3%" '$0 == f { getline; print }'
}
valve_fetch_pkg() {
# valve_fetch_pkg <repo prefix> <package> <dir>: download the newest
# <package> from the newest <prefix> repository into <dir> and print its
# path. The file name and SHA-256 come from the repository's database and
# the checksum is verified; the database is kept in <dir> for more calls.
local prefix="$1" name="$2" dir="$3" repo db desc file_name sha256
repo="$(valve_newest_repo "$prefix")"
db="$dir/$prefix.db"
if [[ ! -f "$db" ]]; then
[[ -n "$repo" ]] && curl -fsL "$(valve_repo_url "$repo")/$repo.db" -o "$db" ||
{ err "Couldn't read Valve's SteamOS package index ($VALVE_MIRROR)."; return 1; }
fi
desc="$(tar -tf "$db" 2>/dev/null | grep -E "^$name-[0-9][^/]*/desc$" | head -n 1)"
[[ -n "$desc" ]] || { err "No $name in Valve's $repo repository."; return 1; }
file_name="$(valve_desc_field "$db" "$desc" FILENAME)"
sha256="$(valve_desc_field "$db" "$desc" SHA256SUM)"
info "Downloading $file_name ($repo)..." >&2
curl -fsL "$(valve_repo_url "$repo")/$file_name" -o "$dir/$file_name" ||
{ err "Downloading $file_name failed."; return 1; }
echo "$sha256 $dir/$file_name" | sha256sum -c --quiet - >&2 ||
{ err "Checksum mismatch for $file_name; not using it."; return 1; }
echo "$dir/$file_name"
}
+1 -1
View File
@@ -19,7 +19,7 @@ VERSION=2.11.1
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
for lib in common state packages login-manager single-user steam-desktop steam-machine fremont-poweroff vram-booster hdmi-refresh nvidia controllers cec boot-session vapor-theme steamos-extras bios desktop-shortcut wizard-shortcut steam-game update-notifier first-login menu backend; do for lib in common valve-mirror state packages login-manager single-user steam-desktop steam-machine fremont-poweroff vram-booster hdmi-refresh nvidia controllers cec boot-session vapor-theme steamos-extras bios desktop-shortcut wizard-shortcut steam-game update-notifier first-login menu backend; do
# shellcheck source=/dev/null # shellcheck source=/dev/null
source "$SCRIPT_DIR/lib/$lib.sh" source "$SCRIPT_DIR/lib/$lib.sh"
done done