nandi/frqpublic Fork 0
87a28ccbc1ad41565d24fa8c4f68e1f9426fd61e
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.

justfile · 459 lines · 20.4 KBMakefile Blame HistoryRaw
Inline the babashka scripts into the justfile 76dcc6c nandi 11d ago1# The work is here now, in recipe bodies, where it used to be in scripts/ —
2# babashka scripts run through a scripts/bb that went looking for a babashka.
3# That indirection bought one thing worth having, a shared way to reach nix on
4# a host that keeps it in a container, and `nix` below is the whole of it.
5#
One frontend where there were three, and a core that is not Clojure 438b247 nandi 21h ago6# Every recipe that builds has the same shape: outside the dev shell, re-enter
7# it and come back to this same recipe; inside, do the work. The re-entry test
8# is an environment variable only the shell sets — no flag to forget, and no
9# second code path for someone who runs `nix develop --command just ...` by
10# hand.
Take glimmer-vidya from gitlab, so a stranger can build this 5c40e75 nandi 19d ago11
Write the build in babashka, and pin the babashka 34832a8 nandi 18d ago12set shell := ["bash", "-euo", "pipefail", "-c"]
A freeq client in jolt, as glimmer components on Vidya 4719d6f nandi 20d ago13
Give the terminal's classpath an nREPL, and hand recipes their arguments 664397d nandi 10d ago14# Every recipe below is a `#!` script and passes its arguments on with "$@".
15# Without this that is empty in one — just interpolates into a shebang recipe
One frontend where there were three, and a core that is not Clojure 438b247 nandi 21h ago16# rather than handing it argv — and a recipe silently ignored its flags.
Give the terminal's classpath an nREPL, and hand recipes their arguments 664397d nandi 10d ago17set positional-arguments
18
Inline the babashka scripts into the justfile 76dcc6c nandi 11d ago19# nix is not on every host this runs on: on the machine these recipes were
20# written for it lives in an Arch distrobox, at the same path — which is why
21# the container is entered rather than the tree copied into it. See CLAUDE.md.
22nix := `command -v nix >/dev/null 2>&1 && echo nix || echo "distrobox enter arch -- nix"`
23
24# --max-jobs 0 is what sends the work to the `builders` entry rather than
25# compiling it here. Left to the default, nix prefers the local machine, and a
One frontend where there were three, and a core that is not Clojure 438b247 nandi 21h ago26# cold Flutter toolchain is a lot of compiling on a laptop — for a derivation a
Inline the babashka scripts into the justfile 76dcc6c nandi 11d ago27# remote builder has likely built already. FRQ_MAX_JOBS=auto is the way out on
28# a machine with no builder configured.
29jobs := env("FRQ_MAX_JOBS", "0")
30
A freeq client in jolt, as glimmer components on Vidya 4719d6f nandi 20d ago31default:
32 @just --list
33
Build the APK, out of ClojureDart and Flutter e2b0e6b nandi 7d ago34# The APK: ClojureDart compiled to Dart, then Flutter's Gradle build.
35#
36# Impure on purpose, and worth saying why rather than leaving it to be
37# discovered. Gradle resolves its own dependencies over the network and
38# installs build-tools and a platform into ANDROID_HOME as it goes, so it
39# cannot run in a sandbox and cannot write to the store. What nix gives here
40# is the toolchain — clojure, a JDK, Flutter, and an SDK composed by
41# androidenv — and the recipe copies that SDK somewhere writable
42# (flutter/.home) for Gradle to finish off. That copy and everything Gradle
43# leaves behind are gitignored.
44#
45# No ndkVersion in android/app/build.gradle.kts, for the same reason: the
46# Flutter template sets it, setting it makes Gradle fetch that exact NDK, and
47# there is no native code here to need one.
48#
49# just apk build the debug APK
50# just apk install build it and put it on a connected device
51# just apk run install and launch
52# just apk log logcat, filtered to this app
53apk action="build":
54 #!/usr/bin/env bash
55 set -euo pipefail
56 cd "{{justfile_directory()}}/flutter"
57
Build the APK from the flake, at the rev flake.lock pins 77d4bec nandi 7d ago58 # The flake's, not an --impure --expr against whatever nixos-unstable is
59 # today: the licence config the SDK needs lives in `androidPkgsFor` now,
60 # so this is an ordinary output at the rev flake.lock pins.
61 sdk="$(nix build --no-link --print-out-paths \
62 "{{justfile_directory()}}#android-sdk")/libexec/android-sdk"
Build the APK, out of ClojureDart and Flutter e2b0e6b nandi 7d ago63
Let adb keep its identity when the APK recipe moves HOME bc0e14f nandi 7d ago64 # adb keeps the key the phone has already trusted under the real HOME, and
65 # HOME moves below so Gradle can write into the SDK copy. Told where to
66 # look, adb keeps its identity; left to find $HOME/.android it generates a
67 # new one, the device stops recognising this machine, and the deploy ends
68 # in "no devices/emulators found" while `adb devices` in any other shell
69 # lists it perfectly well.
70 export ANDROID_USER_HOME="${ANDROID_USER_HOME:-$HOME/.android}"
71
Build the APK, out of ClojureDart and Flutter e2b0e6b nandi 7d ago72 export HOME="$PWD/.home"
73 export ANDROID_HOME="$HOME/android-sdk"
74 export ANDROID_SDK_ROOT="$ANDROID_HOME"
75 mkdir -p "$HOME"
76
77 # Gradle writes into ANDROID_HOME, so it is a copy rather than the store
78 # path. Made once and kept: re-copying would throw away the build-tools
79 # and platform Gradle installed into it on the last run.
80 if [ ! -d "$ANDROID_HOME" ]; then
81 cp -r "$sdk" "$ANDROID_HOME"
82 chmod -R u+w "$ANDROID_HOME"
83 fi
84
Seed the ClojureDart caches out of the flake f2e12af nandi 7d ago85 # The compile's three caches, same flake-output-and-copy shape as the SDK
86 # and for the same reason: tools.deps and pub both write into theirs, and
87 # the store is read-only. What this buys is the "Resolving dependencies…
88 # Downloading packages…" that used to open every run.
89 deps="$(nix build --no-link --print-out-paths \
90 "{{justfile_directory()}}#cljd-deps")"
91
92 # Neither of these follows HOME. Both are read off the JVM's user.home,
93 # which comes from /etc/passwd rather than the environment — so moving
94 # HOME below is not enough to move them, and left alone they would be the
95 # real ~/.m2 and ~/.gitlibs, shared with every other project on the box.
96 export GITLIBS="$HOME/gitlibs"
97 m2="$HOME/m2"
98 export PUB_CACHE="$HOME/.pub-cache"
99
100 # Seeded once each and then left alone, exactly as ANDROID_HOME is: after
101 # the first compile these hold whatever the working tree has asked for
102 # since, and re-copying would throw that away.
103 seed() {
104 [ -e "$2" ] && return 0
105 mkdir -p "$(dirname "$2")"
106 cp -r "$deps/$1" "$2"
107 chmod -R u+w "$2"
108 }
109 seed m2 "$m2"
110 seed gitlibs "$GITLIBS"
111 seed pub-cache "$PUB_CACHE"
112 seed clojuredart/cache "$PWD/.clojuredart/cache"
113
Build the APK from the flake, at the rev flake.lock pins 77d4bec nandi 7d ago114 # Also the flake's. `nix shell nixpkgs#...` read the registry, which is a
115 # different and unlocked nixpkgs — the Flutter that built the APK could
116 # move under it without flake.lock changing a line.
117 flutter="nix develop {{justfile_directory()}}#flutter --command"
Build the APK, out of ClojureDart and Flutter e2b0e6b nandi 7d ago118
Seed the ClojureDart caches out of the flake f2e12af nandi 7d ago119 # cljd-deps ships the analyzer project unresolved — a fixed-output
120 # derivation may not name the store, and a resolved pub project is
121 # nothing but store paths. So it is resolved here instead, offline,
122 # against the cache that derivation did fetch. ClojureDart reaches for the
123 # network only when bin/analyzer.dart is missing, and after this it is not.
124 for helper in .clojuredart/cache/*/cljd_helper; do
125 [ -d "$helper" ] || continue
126 [ -e "$helper/.dart_tool/package_config.json" ] && continue
127 ( cd "$helper" && $flutter flutter pub get --offline )
128 done
129
130 $flutter clojure -Sdeps "{:mvn/local-repo \"$m2\"}" -M:cljd compile
Build the APK, out of ClojureDart and Flutter e2b0e6b nandi 7d ago131
132 # Rewritten every run: it carries absolute store paths, and the flutter
133 # one moves whenever nixpkgs does.
134 $flutter flutter config --android-sdk "$ANDROID_HOME" >/dev/null
135
136 apk=build/app/outputs/flutter-apk/app-debug.apk
137 adb="${ADB:-$ANDROID_HOME/platform-tools/adb}"
138
139 case "{{action}}" in
140 build) $flutter flutter build apk --debug ;;
141 install) $flutter flutter build apk --debug && "$adb" install -r "$apk" ;;
142 run) $flutter flutter build apk --debug && "$adb" install -r "$apk" \
143 && "$adb" shell monkey -p uk.nandi.frq -c android.intent.category.LAUNCHER 1 ;;
144 log) "$adb" logcat -s flutter ;;
145 *) echo "usage: just apk [build|install|run|log]" >&2; exit 1 ;;
146 esac
147
One frontend where there were three, and a core that is not Clojure 438b247 nandi 21h ago148# What may appear in common/, checked. Needs nothing built: it reads the
149# source, so it is the one check that runs anywhere, and CI runs exactly this.
Check what common/ may contain, on every push 86c2e1b nandi 7d ago150check-common:
151 #!/usr/bin/env bash
152 python3 tools/check-common.py common
153
One frontend where there were three, and a core that is not Clojure 438b247 nandi 21h ago154# The desktop GUI: the same screens the APK paints, on Flutter's Linux target.
Give the terminal's classpath an nREPL, and hand recipes their arguments 664397d nandi 10d ago155#
One frontend where there were three, and a core that is not Clojure 438b247 nandi 21h ago156# This recipe and `just apk` are two targets over one tree, and the split is
157# the one the APK already draws. Everything under `common/` — the screens, the
158# cells, `frq.io` — is shared; what differs is who answers the host. So this
159# is `just apk` with the Android half taken out: the same `clojure -M:cljd compile` over the same flutter/src,
Paint the desktop with Flutter too, beside libcosmic fc5f63c nandi 7d ago160# then Flutter's Linux target rather than its Android one. CMake and Ninja
161# instead of Gradle, `flutter/linux/` as the runner, no SDK and no JDK.
162#
163# Still impure, for one of the two reasons `apk` is: pub.dev resolution and
164# Flutter's own engine artifacts are network. What it does NOT need is the
165# writable-ANDROID_HOME dance — nothing here writes into the store — so there
166# is no `flutter/.home` on this path.
167#
One frontend where there were three, and a core that is not Clojure 438b247 nandi 21h ago168# nixGL because Flutter paints through GL, and off NixOS the driver is the
169# host's.
Paint the desktop with Flutter too, beside libcosmic fc5f63c nandi 7d ago170#
171# just flutter-desktop build the debug bundle
172# just flutter-desktop run build it and open the window
173flutter-desktop action="build":
174 #!/usr/bin/env bash
175 set -euo pipefail
176 cd "{{justfile_directory()}}"
177 if [ -z "${FRQ_FLUTTER_DESKTOP:-}" ]; then
178 exec {{nix}} develop .#flutter-desktop --max-jobs {{jobs}} \
179 --command just flutter-desktop "$@"
180 fi
181 cd flutter
182
Seed the ClojureDart caches out of the flake f2e12af nandi 7d ago183 # The same three caches `just apk` seeds, in the same place and out of the
184 # same flake output — one compiler, one set of dependencies, and no reason
185 # for the two frontends to keep a copy each. `.home/` is `apk`'s directory
186 # by name and this is the only thing put there from here, which is the
187 # point: whichever recipe runs first pays for the copy and the other finds
188 # it warm.
189 #
190 # No `nix build` here, unlike `apk`: this recipe is already inside the
191 # shell that names FRQ_CLJD_DEPS by the time it gets this far, and `apk`
192 # needs the path before it enters anything.
193 #
194 # m2 and gitlibs are set here for the reason they are set there — the JVM
195 # reads user.home out of /etc/passwd, so neither follows HOME and left
196 # alone they are the real ~/.m2 and ~/.gitlibs.
197 export PUB_CACHE="$PWD/.home/.pub-cache"
198 export GITLIBS="$PWD/.home/gitlibs"
199 m2="$PWD/.home/m2"
200
201 seed() {
202 [ -e "$2" ] && return 0
203 mkdir -p "$(dirname "$2")"
204 cp -r "$FRQ_CLJD_DEPS/$1" "$2"
205 chmod -R u+w "$2"
206 }
207 seed m2 "$m2"
208 seed gitlibs "$GITLIBS"
209 seed pub-cache "$PUB_CACHE"
210 seed clojuredart/cache "$PWD/.clojuredart/cache"
211
212 # Resolved here rather than in cljd-deps, which was not allowed to name
213 # the store — see the same loop in `apk`.
214 for helper in .clojuredart/cache/*/cljd_helper; do
215 [ -d "$helper" ] || continue
216 [ -e "$helper/.dart_tool/package_config.json" ] && continue
217 ( cd "$helper" && flutter pub get --offline )
218 done
219
220 clojure -Sdeps "{:mvn/local-repo \"$m2\"}" -M:cljd compile
Paint the desktop with Flutter too, beside libcosmic fc5f63c nandi 7d ago221 flutter build linux --debug
222
223 # x64/arm64 is Flutter's own name for the host arch, not uname's.
224 case "$(uname -m)" in
225 x86_64) arch=x64 ;;
226 aarch64) arch=arm64 ;;
227 *) echo "unknown arch $(uname -m)" >&2; exit 1 ;;
228 esac
229 bundle="build/linux/$arch/debug/bundle"
230
231 case "{{action}}" in
232 build) echo "built $PWD/$bundle/frq" ;;
233 run)
234 runner=()
235 [ -e /run/current-system ] || runner=("$NIXGL")
236 exec "${runner[@]}" "$bundle/frq"
237 ;;
238 *) echo "usage: just flutter-desktop [build|run]" >&2; exit 1 ;;
239 esac
A shell that is already the devShell, and two recipes to reach it e853593 nandi 5d ago240
A third target, and the seam that was already waiting for it f54ca45 nandi 2d ago241# The third frontend: the same screens again, compiled to JavaScript.
242#
243# `flutter-desktop` with the Linux half taken out. One `clojure -M:cljd
244# compile` over the same flutter/src and common/, then Flutter's web target
245# instead of its Linux one — dart2js instead of CMake and Ninja, and a
246# directory of static files instead of a bundle with an executable in it.
247#
Three tarballs where a devShell was 5ce66d5 nandi yesterday248# And the one target with no nix in it. The other two need the host: a JDK
249# and the Android SDK for `apk`, GTK and a C++ toolchain and nixGL for
250# `flutter-desktop`. This one needs a Dart, a JVM and a browser, and the
251# browser is not ours — so `tools/toolchain.sh` fetches the first two as
252# pinned tarballs into `.toolchain/` and there is nothing left for a devShell
253# to supply. That is what lets the container in `.modal/flutter-web/` drop
254# its image build too: same script, same three pins, no store to populate.
255#
256# Impure for the reason the other two are: pub.dev resolution and Flutter's
257# engine artifacts are network, and now the toolchain is as well — pinned by
258# sha256, which is the reproducibility that was worth having out of the store.
A third target, and the seam that was already waiting for it f54ca45 nandi 2d ago259#
260# The entry point is `frq.main-web`, not `frq.main`: path_provider has no web
261# implementation, so the `getApplicationSupportDirectory` that `frq.main`
262# awaits throws MissingPluginException before any widget is built. The web
263# entry installs `frq.io.web` — localStorage behind the same seam — and awaits
264# nothing. `frq.net.dart` is still the socket half, so connecting will want a
265# WebSocket before this does more than paint.
266#
Three tarballs where a devShell was 5ce66d5 nandi yesterday267# One build and no `--debug` variant, because there is nothing to gain from
268# one: dart2js at -O1 measured 52.5s against the release build's 49.8s on the
269# same source change here, so a second, larger bundle would buy noise. See
270# `tools/build-web.sh`, which writes the numbers down.
271#
A third target, and the seam that was already waiting for it f54ca45 nandi 2d ago272# just flutter-web build build/web
273# just flutter-web serve build it and serve it on $PORT (8080)
Three tarballs where a devShell was 5ce66d5 nandi yesterday274# just flutter-web serve 3000 ...on another port
A third target, and the seam that was already waiting for it f54ca45 nandi 2d ago275flutter-web action="build" port="8080":
276 #!/usr/bin/env bash
277 set -euo pipefail
Three tarballs where a devShell was 5ce66d5 nandi yesterday278 # A wrapper and nothing else. The build is a shell script because the
279 # container runs it too, and a container that had to install `just` to
280 # start would be one dependency away from the point.
281 exec "{{justfile_directory()}}/tools/build-web.sh" {{action}} {{port}}
A third target, and the seam that was already waiting for it f54ca45 nandi 2d ago282
A shell that is already the devShell, and two recipes to reach it e853593 nandi 5d ago283# The containers in `.modal/`, run on Modal rather than here. This machine
284# evaluates and Modal builds — see CLAUDE.md, which says so rather more
285# firmly — and these two recipes are the whole interface to that.
286#
One frontend where there were three, and a core that is not Clojure 438b247 nandi 21h ago287# Named for where the work happens, the way `flutter-desktop` is named for
288# what paints: there is no re-entry test here because nothing
A Mesa nobody needed, and the AppImage that carried it 9db383c nandi 23h ago289# re-enters. There is no `nix` variable either, and that used to be because
One frontend where there were three, and a core that is not Clojure 438b247 nandi 21h ago290# nix ran out there — now it is because neither of these containers has any
291# nix in it at all.
A shell that is already the devShell, and two recipes to reach it e853593 nandi 5d ago292#
293# just modal flutter-dev the incremental Flutter loop
One frontend where there were three, and a core that is not Clojure 438b247 nandi 21h ago294# just modal flutter-web the web bundle
295modal container="flutter-dev" *args:
A shell that is already the devShell, and two recipes to reach it e853593 nandi 5d ago296 #!/usr/bin/env bash
297 set -euo pipefail
298 cd "{{justfile_directory()}}"
299 shift
300 exec modal run ".modal/{{container}}/container.py" "$@"
301
A third target, and the seam that was already waiting for it f54ca45 nandi 2d ago302# The Modal-built web bundle, served from this machine on localhost.
303#
304# Not a local build: `modal volume get` pulls what `just modal flutter-web`
305# already compiled out of the devshell volume, so this needs no Flutter, no
306# Dart and no nix — only python, which the flake shell has and so does the
307# machine.
308#
309# It exists for one reason, and the reason is the auth broker rather than
310# convenience. freeq's broker finishes an OAuth login by redirecting the
311# browser to `return_to`, and it will only redirect to an origin on its
312# allowlist: its own https hosts, and `http://localhost` or `http://127.0.0.1`
313# on ANY port. A build served from anywhere else — the Modal URL included —
314# gets `400 Invalid return_to URL` and can never complete a Bluesky sign-in,
315# no matter what the client does. localhost is the one allowlisted origin we
316# can serve from, so this is how Bluesky sign-in is tested.
317#
318# Guest and app-password sign-in need none of this; they work on the deployed
319# URL, because neither goes near the broker.
320#
321# just web-local fetch and serve on :8080
322# just web-local 3000 another port; any port is allowlisted
323web-local port="8080":
324 #!/usr/bin/env bash
325 set -euo pipefail
326 cd "{{justfile_directory()}}"
327 out="{{justfile_directory()}}/.web-local"
328 mkdir -p "$out"
329 echo "fetching the Modal-built bundle…"
330 # --force: this is a mirror of the volume, and a stale file left behind
331 # would be served in preference to the one just built.
332 modal volume get --force devshell frq-flutter-web/flutter/build/web "$out"
333 echo
334 echo " http://localhost:{{port}}"
335 echo
336 echo "Bluesky sign-in works here and not on the Modal URL: the broker"
337 echo "allowlists localhost on any port. Put wss://irc.freeq.at/irc in the"
338 echo "Server field — a browser has no TCP."
339 exec python3 -m http.server {{port}} --bind 127.0.0.1 --directory "$out/web"
340
A shell that is already the devShell, and two recipes to reach it e853593 nandi 5d ago341# A sandbox left running with the container's own image, volumes and
342# environment, and the command to get into it. `modal shell --image` cannot
343# be pointed at a published Modal image like arch-nix, so attaching to a
344# running sandbox is the only way to get a shell that is the container.
345#
346# It blocks: an ephemeral app stops when its entrypoint returns and takes the
347# sandbox with it. Attach from a second terminal, and Ctrl-C here when done —
348# the sandbox bills until you do.
349#
350# just modal-shell flutter-dev, the usual one
One frontend where there were three, and a core that is not Clojure 438b247 nandi 21h ago351# just modal-shell flutter-web the web bundle container
A shell that is already the devShell, and two recipes to reach it e853593 nandi 5d ago352modal-shell container="flutter-dev":
353 #!/usr/bin/env bash
354 set -euo pipefail
355 cd "{{justfile_directory()}}"
356 exec modal run ".modal/{{container}}/container.py" --shell
One frontend where there were three, and a core that is not Clojure 438b247 nandi 21h ago357
358# The Nim core's test suite.
359#
360# It needs no Flutter, no Dart and no Android SDK — which is the point of
361# having the logic here rather than under `common/`: a rule about the IRC wire
362# format can be checked in a second, on any machine, without a toolchain that
363# takes minutes to enter.
364#
365# just nim-test the whole suite
366# just nim-test tircparse one file
367nim-test file="":
368 #!/usr/bin/env bash
369 set -euo pipefail
370 cd "{{justfile_directory()}}"
371 if [ -z "${FRQ_NIM:-}" ]; then
372 exec {{nix}} develop .#nim --max-jobs {{jobs}} --command just nim-test "$@"
373 fi
374 cd nim
375 if [ -n "{{file}}" ]; then
376 exec nim c -r --hints:off --path:src "tests/{{file}}.nim"
377 fi
378 for t in tests/t*.nim; do
379 echo "== $t"
380 nim c -r --hints:off --path:src "$t"
381 done
382
383# The Nim core as a shared library, into build/nim.
384#
385# `--mm:orc` rather than the default: this is a library loaded by a Dart
386# process that owns its own lifetime, so reference counting with a cycle
387# collector is the memory model that does not need a GC thread of its own or a
388# stack it can scan.
389#
390# `-d:release` and not `-d:danger`: the bounds checks are what turn a
391# malformed line off a socket into an exception instead of a read past the end
392# of a buffer, and this parses exactly that.
393nim-lib:
394 #!/usr/bin/env bash
395 set -euo pipefail
396 cd "{{justfile_directory()}}"
397 if [ -z "${FRQ_NIM:-}" ]; then
398 exec {{nix}} develop .#nim --max-jobs {{jobs}} --command just nim-lib
399 fi
400 out="{{justfile_directory()}}/build/nim"
401 mkdir -p "$out"
402 cd nim
403 nim c --app:lib --mm:orc -d:release --hints:off \
404 --path:src --out:"$out/libfrqcore.so" src/frq_core.nim
405 echo "built $out/libfrqcore.so"
406 nm -D --defined-only "$out/libfrqcore.so" | grep ' T frq_' || true
The binding is Dart, and it works f7aea3b nandi 20h ago407
408# The Dart side of the Nim boundary, on the plain Dart VM.
409#
410# No Flutter, no emulator, no ClojureDart — `dart/frq_core` is ordinary Dart
411# over `dart:ffi` and is not a Flutter package, so the test that proves the
412# marshalling runs in a second. Passing `just nim-test` and failing this one is a
413# marshalling bug, which is the whole reason the two suites are separate.
414#
415# Builds the library first: the test dlopens a real .so and there is no point
416# reporting that it could not find one.
417dart-test:
418 #!/usr/bin/env bash
419 set -euo pipefail
420 cd "{{justfile_directory()}}"
421 if [ -z "${FRQ_DART:-}" ]; then
422 # nim-lib before the re-entry, not after: it enters a shell of its own
423 # and doing it on the far side would build the library twice.
424 just nim-lib
425 exec {{nix}} develop .#dart --max-jobs {{jobs}} --command just dart-test
426 fi
427 cd dart/frq_core
428 dart pub get
429 dart test -r expanded
Nim owns the screen, Dart owns the pixels 43a02c2 nandi 20h ago430
Nim under the existing UI, not instead of it 56551a8 nandi 20h ago431# The real app, with the Nim core as its transport.
432#
433# This is the wiring that matters: `frq.main-nim` is `frq.main` with one line
434# changed — `frq.net.nim/install!` where it says `frq.net.dart/install!`. Every
435# screen, every cell and every action is the one that was already there. Nim
436# owns the socket, the TLS and the line framing, and nothing else.
437#
438# just nim-app build it
439# just nim-app run open the window
440nim-app action="build":
441 #!/usr/bin/env bash
442 set -euo pipefail
443 cd "{{justfile_directory()}}"
444 if [ -z "${FRQ_FLUTTER_DESKTOP:-}" ]; then
445 just nim-lib
446 exec {{nix}} develop .#flutter-desktop --max-jobs {{jobs}} \
447 --command just nim-app "$@"
448 fi
449 cd flutter
450 flutter pub get
451 export LD_LIBRARY_PATH="${FRQ_OPENSSL_LIB:-}${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
452 clojure -M:cljd compile frq.main-nim
453 runner=()
454 [ -e /run/current-system ] || runner=("$NIXGL")
455 case "{{action}}" in
456 build) exec "${runner[@]}" flutter build linux --debug -t lib/main_nim_app.dart ;;
457 run) exec "${runner[@]}" flutter run -d linux -t lib/main_nim_app.dart ;;
458 *) echo "usage: just nim-app [build|run]" >&2; exit 1 ;;
459 esac