diff --git a/.gitea/workflows/flatpak.yml b/.gitea/workflows/flatpak.yml index d30a644..6e9e894 100644 --- a/.gitea/workflows/flatpak.yml +++ b/.gitea/workflows/flatpak.yml @@ -85,10 +85,17 @@ jobs: # flatpak builds with no network; vendor every crate from Cargo.lock into # cargo-sources.json next to the manifest (referenced by the manifest's # punktfunk-client module). + # + # Prune the microsoft/windows-rs git crates first: they belong to + # punktfunk-client-windows, which the flatpak never builds, and leaving them in makes + # flatpak-builder full-clone that multi-GB repo at build time → "No space left on + # device" (see packaging/flatpak/prune-windows-lock.py). The committed Cargo.lock is + # untouched; cargo --offline only needs sources for the crates it compiles. run: | curl -fsSL -o /tmp/flatpak-cargo-generator.py \ https://raw.githubusercontent.com/flatpak/flatpak-builder-tools/master/cargo/flatpak-cargo-generator.py - python3 /tmp/flatpak-cargo-generator.py Cargo.lock \ + python3 packaging/flatpak/prune-windows-lock.py Cargo.lock /tmp/Cargo.flatpak.lock + python3 /tmp/flatpak-cargo-generator.py /tmp/Cargo.flatpak.lock \ -o packaging/flatpak/cargo-sources.json - name: Build the flatpak (install deps from Flathub, offline build) diff --git a/packaging/flatpak/build-flatpak.sh b/packaging/flatpak/build-flatpak.sh index 5fd7515..550c45b 100755 --- a/packaging/flatpak/build-flatpak.sh +++ b/packaging/flatpak/build-flatpak.sh @@ -65,7 +65,10 @@ else fi # Needs python3 + aiohttp + tomlkit. On a host that lacks them (e.g. the Deck), generate on the # Mac / a dev box instead and rsync the result next to the manifest (reused by the branch above). - python3 "$GEN" Cargo.lock -o packaging/flatpak/cargo-sources.json + # Prune the microsoft/windows-rs git crates first (punktfunk-client-windows only) — otherwise + # flatpak-builder full-clones that multi-GB repo and fills the disk. See prune-windows-lock.py. + python3 packaging/flatpak/prune-windows-lock.py Cargo.lock /tmp/Cargo.flatpak.lock + python3 "$GEN" /tmp/Cargo.flatpak.lock -o packaging/flatpak/cargo-sources.json fi # --- build into a local ostree repo, then export a single-file bundle -------------------- diff --git a/packaging/flatpak/prune-windows-lock.py b/packaging/flatpak/prune-windows-lock.py new file mode 100755 index 0000000..8978f35 --- /dev/null +++ b/packaging/flatpak/prune-windows-lock.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +"""Write a copy of a Cargo.lock with the microsoft/windows-rs git packages removed. + +The punktfunk workspace lockfile includes `punktfunk-client-windows`' git dependencies — the +whole microsoft/windows-rs tree (windows-reactor + ~13 `windows-*` crates, all pinned to one +git rev). The flatpak builds ONLY the Linux client (`-p punktfunk-client-linux`), which never +references them, but `flatpak-cargo-generator.py` walks the whole lock and emits a `type: git` +source for windows-rs; `flatpak-builder` then FULL-clones that multi-GB repo at "Downloading +sources" → "No space left on device", failing the build. + +Stripping those packages from the lock the generator sees is safe: the committed Cargo.lock is +left untouched for the `--locked` build, and `cargo --offline` only needs vendored sources for +the crates it actually compiles (none of the windows-rs crates are in the Linux client's +dependency closure). + +Dependency-free (no tomlkit) so it also runs on the Steam Deck's stock python. Matches on the +`source =` line specifically, so a crate that merely *lists* a windows-rs dependency is kept. + +Usage: prune-windows-lock.py +""" +import sys + +WINDOWS_RS = "github.com/microsoft/windows-rs" + + +def is_windows_rs(block: str) -> bool: + for line in block.splitlines(): + s = line.strip() + if s.startswith("source = ") and WINDOWS_RS in s: + return True + return False + + +def main() -> None: + src, dst = sys.argv[1], sys.argv[2] + text = open(src).read() + # Cargo.lock (v3+) is a header followed by `[[package]]` blocks, no trailing [metadata]. + parts = text.split("\n[[package]]\n") + header = parts[0] + kept, removed = [], 0 + for block in parts[1:]: + if is_windows_rs(block): + removed += 1 + else: + kept.append(block) + out = header + "".join("\n[[package]]\n" + b for b in kept) + open(dst, "w").write(out) + print(f"prune-windows-lock: removed {removed} windows-rs git crates ({src} -> {dst})") + + +if __name__ == "__main__": + main()