nandi/frqpublic Fork 0
c20643ad1218d42ae3b0e23939d1860aa6b1d193
Commits
Clone
git clone https://git.rickub.com/nandi/frq.git
git clone ssh://git@rickub.com/nandi/frq.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

container.toml · 125 lines · 5.4 KBTOML Blame HistoryRaw
The window opens, and a devShell that remembers what it built c20643a nandi 5d ago1[container]
2name = "frq-flutter-dev"
3description = "the Flutter desktop build, incremental, in a nix devShell"
4base = "arch-nix"
5# A Sandbox, not a Function: runs on a real VM, and the command is
6# the sandbox's own process so it dies when the command does.
7runtime = "sandbox"
8
9[build]
10# The container lives inside the repo it builds, so the copy is rooted two
11# levels up and `.` is the whole tree.
12context = "../.."
13include = ["."]
14
15# Two volumes doing two different jobs. `nix-cache` is the binary cache every
16# container here reads from and writes back to. `devshell` is the working
17# state of a `nix develop` loop, and it is shared by every container that has
18# one -- each gets its own directory under it, named for the devShell it
19# belongs to, so two projects (or two shells of one project) never write the
20# same tree. Modal Volumes have no locking, so the directories are the only
21# thing keeping them apart, and two runs of the *same* devshell must not
22# overlap.
23[volumes]
24nix-cache = "/nix-cache"
25devshell = "/devshell"
26
27[resources]
28cpu = 8
29memory = 16384
30timeout = 3600
31
32[run]
33workdir = "/app"
34# Nix for the dependencies, the ordinary toolchain for the build. `nix build`
35# cannot do this: a derivation is all-or-nothing, so any edit is a fresh
36# sandbox and a fresh compile of everything. Here the devShell supplies the
37# compiler and the libraries, and `flutter build` decides what is stale --
38# which is the whole reason `just flutter-desktop` exists as the working-tree
39# loop rather than as another `nix build`.
40#
41# rsync and not cp, with --checksum and not mtimes: Modal copies the source in
42# with fresh timestamps on every run, so a plain copy would look entirely new
43# to Flutter and rebuild the lot. --checksum compares content, leaves the
44# unchanged files' timestamps alone, and lets the incremental build work.
45#
46# The excludes are the state that must NOT be overwritten from /app -- it is
47# what we are here to keep. `just flutter-desktop` seeds those caches only
48# when they are missing, so finding them warm is all it takes.
49command = """
50set -e
51# This container's own directory on the shared devshell volume, named for the
52# devShell it keeps the state of. Anything else using this volume picks its
53# own name and the two never meet.
54SHELL_DIR=/devshell/frq-flutter-desktop
55mkdir -p "$SHELL_DIR"
56
57# A worktree's `.git` is a *file* naming a gitdir back on the machine that
58# copied it in, and nix believes it and goes looking for a path that is not
59# here. It has to go before any flake reference to /app.
60rm -rf /app/.git
61
62echo "sync: /app -> $SHELL_DIR"
63# `nix shell --command` and not `nix profile install`: a profile install puts
64# rsync in ~/.nix-profile/bin, which is not on the PATH of the shell already
65# running, so the very next line said `rsync: command not found`.
66#
67# rsync and not cp, with --checksum and not mtimes: Modal copies the source in
68# with fresh timestamps every run, so a plain copy looks entirely new to
69# Flutter and rebuilds the lot. --checksum compares content and leaves the
70# unchanged files' timestamps alone, which is the whole basis of the
71# incremental build.
72#
73# The excludes are the state we are here to keep -- overwriting them from /app
74# would defeat the volume. `just flutter-desktop` seeds those caches only when
75# they are missing, so finding them warm is all it takes.
76nix shell nixpkgs#rsync --accept-flake-config \
77 --extra-substituters file:///nix-cache --command \
78 rsync -a --checksum --delete \
79 --exclude 'flutter/.home/' \
80 --exclude 'flutter/.clojuredart/' \
81 --exclude 'flutter/build/' \
82 --exclude 'flutter/.dart_tool/' \
83 --exclude '.git' \
84 /app/ "$SHELL_DIR/"
85
86cd "$SHELL_DIR"
87echo "state carried over:"
88du -sh flutter/.home flutter/.clojuredart flutter/build 2>/dev/null \
89 || echo " (none yet -- first run)"
90
91# Nix for the dependencies, the ordinary toolchain for the build. `nix build`
92# cannot do this: a derivation is all-or-nothing, so any edit is a fresh
93# sandbox and a fresh compile of everything. Here the devShell supplies the
94# compiler and the libraries and `flutter build` decides what is stale.
95# Evaluated from /app and built in the volume. Both halves matter: /app is the
96# pristine copy, so nix stores a source tree of the repo rather than one
97# carrying gigabytes of flutter/build, while the recipe still runs where the
98# state it reuses lives -- `just -f` is what puts it there, since the recipe
99# cds to its own justfile's directory.
100nix develop /app#flutter-desktop --accept-flake-config \
101 --extra-substituters file:///nix-cache \
102 --max-jobs auto --command just -f "$SHELL_DIR/justfile" flutter-desktop
103
104echo "built:"
105du -sh flutter/build
106
107# The devShell's closure is gigabytes of Flutter, Dart, clang and GTK, and the
108# store it landed in belongs to the image rather than to a volume -- so
109# without this every run re-fetches it from upstream. Written back, the next
110# run substitutes it from file:///nix-cache instead.
111if [ -f /nix-cache/nix-cache-info ]; then
112 echo "cache: writing the devShell closure back"
113 nix copy --no-check-sigs --all --to file:///nix-cache
114fi
115"""
116env = { }
117
118[nix]
119# No devShell warming at image build time: this enters `nix develop` at run
120# time, on the VM, where the cache answers for its closure. The ptyshim that
121# warming would need under gVisor is deprecated and does not come back.
122flake = false
123shim = false
124
125# [experimental] overrides the sandbox default of vm_runtime = true.