# Nix supplies the whole toolchain (Zig, GTK, libadwaita), so there is # nothing for mise to install; these tasks just drive it. [tasks.build] description = "Build a release binary into zig-out/bin" run = "nix develop --command zig build -Doptimize=ReleaseFast" [tasks.build-debug] description = "Build a debug binary (leak checking, safety checks)" run = "nix develop --command zig build" [tasks.run] description = "Build and run vtabs" run = "nix develop --command zig build run" [tasks.fmt] description = "Format all Zig source" run = "nix develop --command zig fmt build.zig src" [tasks.screenshot] description = "Screenshot vtabs in a throwaway headless compositor" depends = ["build-debug"] run = "nix develop --command ./shot.sh" [tasks.install] description = "Install vtabs into ~/.local with a desktop entry and icon" depends = ["build"] run = ''' #!/usr/bin/env bash set -euo pipefail data="${XDG_DATA_HOME:-$HOME/.local/share}" bindir="$HOME/.local/bin" libexec="$HOME/.local/libexec/vtabs" apps="$data/applications" icons="$data/icons/hicolor/scalable/apps" gcroots="$data/vtabs/gcroots" # The binary carries an RPATH into the Nix store, so it runs anywhere, but it # still has to be told where GTK's GSettings schemas and icon themes live or # it aborts on a missing schema. Read those paths back out of the dev shell # that built it rather than hardcoding store hashes. schemas="$(nix develop --command printenv VTABS_GSETTINGS_SCHEMA_DIR)" datadirs="$(nix develop --command printenv VTABS_RUNTIME_DATA_DIRS)" mkdir -p "$bindir" "$libexec" "$apps" "$icons" "$gcroots" install -m755 zig-out/bin/vtabs "$libexec/vtabs" # A launcher script rather than a symlink: a desktop launcher starts the app # with a minimal environment, so the GTK runtime paths must be set here. # Existing values are preserved so this composes with the rest of the session. cat > "$bindir/vtabs" < "$apps/dev.greyson.vtabs.desktop" install -m644 dist/dev.greyson.vtabs.svg "$icons/dev.greyson.vtabs.svg" # Pin the store paths the installed binary links against. Without this a # later `nix-collect-garbage` deletes GTK and the installed app stops # starting, with no obvious connection to the command that broke it. # Nix roots are transitive, so rooting each RPATH entry covers its closure. rm -f "$gcroots"/* if command -v readelf >/dev/null; then readelf -d "$libexec/vtabs" \ | sed -n 's/.*R\(UN\)\?PATH.*\[\(.*\)\]/\2/p' \ | tr ':' '\n' \ | sed -n 's|^\(/nix/store/[^/]*\).*|\1|p' \ | sort -u \ | while read -r path; do nix-store --realise --add-root "$gcroots/$(basename "$path")" \ --indirect "$path" >/dev/null 2>&1 || true done echo "pinned $(find "$gcroots" -maxdepth 1 -type l | wc -l) store paths against garbage collection" else echo "warning: readelf not found; store paths left unpinned (nix-collect-garbage may break the install)" >&2 fi # Let the desktop notice the new entry and icon right away. command -v update-desktop-database >/dev/null && update-desktop-database -q "$apps" || true command -v gtk-update-icon-cache >/dev/null && gtk-update-icon-cache -qtf "$data/icons/hicolor" 2>/dev/null || true echo "installed $bindir/vtabs" case ":$PATH:" in *":$bindir:"*) ;; *) echo "note: $bindir is not on your PATH; the desktop entry still works" >&2 ;; esac ''' [tasks.uninstall] description = "Remove everything `install` put into ~/.local" run = ''' #!/usr/bin/env bash set -euo pipefail data="${XDG_DATA_HOME:-$HOME/.local/share}" apps="$data/applications" rm -f "$HOME/.local/bin/vtabs" rm -rf "$HOME/.local/libexec/vtabs" rm -f "$apps/dev.greyson.vtabs.desktop" rm -f "$data/icons/hicolor/scalable/apps/dev.greyson.vtabs.svg" # Dropping the roots lets Nix reclaim the runtime closure on its next GC. rm -rf "$data/vtabs" command -v update-desktop-database >/dev/null && update-desktop-database -q "$apps" || true command -v gtk-update-icon-cache >/dev/null && gtk-update-icon-cache -qtf "$data/icons/hicolor" 2>/dev/null || true echo "uninstalled vtabs" '''