diff --git a/setup/packages/flatpak-packages b/setup/packages/flatpak-packages index a6e2e21..e38b7e1 100644 --- a/setup/packages/flatpak-packages +++ b/setup/packages/flatpak-packages @@ -5,3 +5,5 @@ app.bluebubbles.BlueBubbles org.mozilla.thunderbird_esr io.missioncenter.MissionCenter io.mpv.Mpv +# A GUI over the podman that development-packages installs. +io.podman_desktop.PodmanDesktop diff --git a/setup/scripts/install-packages b/setup/scripts/install-packages index ea31760..925f842 100755 --- a/setup/scripts/install-packages +++ b/setup/scripts/install-packages @@ -98,12 +98,56 @@ else log "Package list was not in specified path: $HYPR_FILE" fi -# --- Install Bun --- +# --- Applications no repository packages ------------------------------------- +# +# Everything else Panama installs comes from dnf or Flathub. These three do not +# exist in either, so each is an explicit exception with a reason, and each is +# skipped when already present so a re-run costs nothing. +# +# None of them pins a version. sunhat pinned URLs -- upscayl 2.11.5, LACT 0.5.4, +# a fedora-40 RPM -- and every one of them was a 404 within a release cycle. An +# installer that resolves "latest" keeps working; one that names a version rots. +# +# A failure here is logged and stepped over rather than aborting: this stage has +# already installed the desktop by this point, and an unreachable third-party +# host should not cost you that. + +# Bun: the JavaScript runtime and package manager. No RPM, no flatpak. if [[ -x "$HOME/.bun/bin/bun" ]]; then log "Bun already installed at \"$HOME/.bun/bin/bun\"" else log "Installing Bun via curl..." - curl -fsSL https://bun.sh/install | bash > /dev/null 2>&1 + curl -fsSL https://bun.sh/install | bash > /dev/null 2>&1 || log "Bun install failed; skipping" +fi + +# Claude Code: Anthropic's CLI. The official installer keeps itself updated +# afterwards, so this runs once and then never needs to again. +if command -v claude >/dev/null 2>&1; then + log "Claude Code already installed at \"$(command -v claude)\"" +else + log "Installing Claude Code via the official installer..." + curl -fsSL https://claude.ai/install.sh | bash > /dev/null 2>&1 || log "Claude Code install failed; skipping" +fi + +# RustDesk: remote desktop. The flatpak cannot register the root-owned system +# service that unattended access needs -- see panama-doctor's rustdesk check -- +# so this takes the RPM. The download URL is resolved from the latest release +# rather than written down, so it does not go stale. +if rpm -q rustdesk >/dev/null 2>&1; then + log "RustDesk already installed" +else + log "Resolving the latest RustDesk release..." + rustdesk_url="$(curl -fsSL https://api.github.com/repos/rustdesk/rustdesk/releases/latest 2>/dev/null \ + | jq -r '.assets[].browser_download_url | select(test("x86_64\\.rpm$")) | select(test("suse") | not)' \ + | head -1)" + if [[ -n "$rustdesk_url" ]]; then + log "Installing RustDesk from $rustdesk_url" + # The RPM ships rustdesk.service already enabled, which is what provides + # unattended access; Panama deliberately does not start it a second time. + sudo dnf install -y "$rustdesk_url" > /dev/null || log "RustDesk install failed; skipping" + else + log "Could not resolve a RustDesk release; skipping" + fi fi # --- Install Flatpak Packages --- diff --git a/tests/quickshell/declared-dependencies-contract.sh b/tests/quickshell/declared-dependencies-contract.sh index cd308d7..1e98411 100755 --- a/tests/quickshell/declared-dependencies-contract.sh +++ b/tests/quickshell/declared-dependencies-contract.sh @@ -36,6 +36,17 @@ BASELINE='^(sh|bash|cat|cut|sed|awk|gawk|grep|egrep|head|tail|sort|uniq|tr|wc|fi SESSION='^(systemctl|busctl|journalctl|loginctl|hostnamectl|localectl|systemd-inhibit|systemd-run|udevadm|gsettings|dconf|dbus-send|dbus-monitor|hyprctl|qs|quickshell|gnf|panama|wl-copy|wl-paste)$' +# Installed by install-packages itself, because no repository carries them. +# They are deliberately absent from the package lists, and install-packages +# probes for them with `command -v` precisely because they arrive out of band -- +# so that probe must not be read as an undeclared dependency. Anything added +# here needs a matching install block and a stated reason for the exception. +SELF_INSTALLED='^(bun|claude)$' + +# jq programs are quoted arguments, but the scanner is line-based and cannot +# tell a filter from a command. `not` is a jq builtin appearing inside one. +JQ_BUILTINS='^(not|empty|error|env|input|inputs)$' + declared="$(cat "$repo_dir"/setup/packages/* 2>/dev/null | sed 's/#.*//' | tr -d ' ' | grep -v '^$' | sort -u)" [[ -n "$declared" ]] || fail 'no package lists found' @@ -85,6 +96,8 @@ while read -r script; do [[ "$cmd" =~ $SHELL_WORDS ]] && continue [[ "$cmd" =~ $BASELINE ]] && continue [[ "$cmd" =~ $SESSION ]] && continue + [[ "$cmd" =~ $SELF_INSTALLED ]] && continue + [[ "$cmd" =~ $JQ_BUILTINS ]] && continue pkg="$(package_for "$cmd")" grep -qx "$pkg" <<<"$declared" && continue