nandi/frqpublic Fork 0
bd10e816d10d09c3dbe1256c1b7c661d8e190ee6
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 · 257 lines · 9.9 KBMakefile Blame HistoryRaw
Six verbs, and the last of the nix 2e24e64 nandi yesterday1# Six verbs over one tree.
Inline the babashka scripts into the justfile 76dcc6c nandi 12d ago2#
Six verbs, and the last of the nix 2e24e64 nandi yesterday3# There is no nix here any more. `tools/toolchain.sh` fetches Flutter (which
4# carries Dart), a JDK, the Clojure CLI and Nim as sha256-pinned tarballs into
5# `.toolchain/`, and every recipe below runs inside the environment that
6# script prints. One mechanism, and the same one the containers in `.modal/`
7# use — which is what lets a plain Debian image build this.
8#
9# What the host still brings: a C compiler (Nim shells out to one), OpenSSL
10# (nim.cfg is `-d:ssl`), git, curl, unzip, python3. For `run desktop` and the
11# other Linux builds, GTK and the usual CMake/Ninja/pkg-config.
12#
13# just build TARGET apk desktop web lib ui app
14# just run TARGET apk desktop web ui app
15# just test SUITE all nim dart common live
The last of the Clojure 284b59c nandi yesterday16# just modal CONTAINER dev
CI builds the image, Modal serves it 5693bd5 nandi 9h ago17# just deploy web the CI-built image, to a Modal URL
Six verbs, and the last of the nix 2e24e64 nandi yesterday18# just serve [PORT] the Modal-built web bundle, on localhost
19# just tools ... the toolchain itself
Take glimmer-vidya from gitlab, so a stranger can build this 5c40e75 nandi 20d ago20
Write the build in babashka, and pin the babashka 34832a8 nandi 19d ago21set shell := ["bash", "-euo", "pipefail", "-c"]
A freeq client in jolt, as glimmer components on Vidya 4719d6f nandi 21d ago22
Six verbs, and the last of the nix 2e24e64 nandi yesterday23# Every recipe is a `#!` script. Without this, "$@" is empty in one of them —
24# just interpolates into a shebang recipe rather than handing it argv.
Give the terminal's classpath an nREPL, and hand recipes their arguments 664397d nandi 11d ago25set positional-arguments
26
Six verbs, and the last of the nix 2e24e64 nandi yesterday27root := justfile_directory()
28tc := justfile_directory() / "tools/toolchain.sh"
Inline the babashka scripts into the justfile 76dcc6c nandi 12d ago29
A freeq client in jolt, as glimmer components on Vidya 4719d6f nandi 21d ago30default:
31 @just --list
32
The last of the Clojure 284b59c nandi yesterday33# The toolchain, directly: `just tools versions`,
Six verbs, and the last of the nix 2e24e64 nandi yesterday34# `just tools exec -- flutter doctor`.
The last of the Clojure 284b59c nandi yesterday35[doc('the toolchain itself: versions, exec -- CMD')]
Six verbs, and the last of the nix 2e24e64 nandi yesterday36tools *args:
37 #!/usr/bin/env bash
38 cd "{{root}}"
39 exec "{{tc}}" "$@"
40
41# Build a target.
42#
The last of the Clojure 284b59c nandi yesterday43# desktop the app: Nim owns the state and the screens, Flutter paints
A web version, from the same core 23846db nandi 10h ago44# web the same, in a browser: the core compiled by `nim js`, the
45# socket a WebSocket to freeq's own bridge, Flutter painting
The last of the Clojure 284b59c nandi yesterday46# lib the Nim core alone, as build/nim/libfrqcore.so
A web version, from the same core 23846db nandi 10h ago47# core-js the core alone, as build/web/frq_core.js
The last of the Clojure 284b59c nandi yesterday48#
49# There were four more. `apk` and `web` compiled ClojureDart and went with it:
50# the web target cannot come back without a wasm build of the core, since a
51# browser has no dart:ffi, and the APK wants libfrqcore.so cross-compiled for
52# Android's ABIs. `ui` and `app` were the two halves of the migration, and
53# there is one app now.
A web version, from the same core 23846db nandi 10h ago54[doc('build a target: desktop web lib core-js')]
Six verbs, and the last of the nix 2e24e64 nandi yesterday55build target="desktop":
Build the APK, out of ClojureDart and Flutter e2b0e6b nandi 8d ago56 #!/usr/bin/env bash
57 set -euo pipefail
Six verbs, and the last of the nix 2e24e64 nandi yesterday58 cd "{{root}}"
59 case "{{target}}" in
60 desktop) just _flutter desktop build ;;
A web version, from the same core 23846db nandi 10h ago61 web) just _web-bundle ;;
Six verbs, and the last of the nix 2e24e64 nandi yesterday62 lib) just _nim-lib ;;
The core, compiled to JavaScript 5ac0521 nandi 10h ago63 core-js) just _nim-js ;;
A web version, from the same core 23846db nandi 10h ago64 *) echo "usage: just build [desktop|web|lib|core-js]" >&2; exit 1 ;;
Build the APK, out of ClojureDart and Flutter e2b0e6b nandi 8d ago65 esac
66
Six verbs, and the last of the nix 2e24e64 nandi yesterday67# Build a target and start it.
Paint the desktop with Flutter too, beside libcosmic fc5f63c nandi 8d ago68#
The last of the Clojure 284b59c nandi yesterday69# FRQ_TRACE=1 every line in and out, both languages in one log
70# FRQ_AUTOCONNECT=1 press Connect at startup, for a window a script cannot
71# click; FRQ_NICK overrides the nickname
A web version, from the same core 23846db nandi 10h ago72[doc('build the app and start it: desktop web')]
The last of the Clojure 284b59c nandi yesterday73run target="desktop":
Paint the desktop with Flutter too, beside libcosmic fc5f63c nandi 8d ago74 #!/usr/bin/env bash
75 set -euo pipefail
Six verbs, and the last of the nix 2e24e64 nandi yesterday76 cd "{{root}}"
77 case "{{target}}" in
78 desktop) just _flutter desktop run ;;
A web version, from the same core 23846db nandi 10h ago79 web) just _web-bundle
80 echo "serving build/web on http://localhost:8000"
81 exec python3 -m http.server 8000 --directory build/web ;;
82 *) echo "usage: just run [desktop|web]" >&2; exit 1 ;;
Paint the desktop with Flutter too, beside libcosmic fc5f63c nandi 8d ago83 esac
A shell that is already the devShell, and two recipes to reach it e853593 nandi 6d ago84
Six verbs, and the last of the nix 2e24e64 nandi yesterday85# Test a suite.
86#
87# nim the Nim core. No Flutter, no Dart, no SDK — a rule about the IRC
88# wire format is checkable in a second.
89# dart the Dart side of the FFI boundary, on the plain Dart VM. Passing
90# `nim` and failing this one is a marshalling bug, which is why the
91# two are separate suites.
The core, compiled to JavaScript 5ac0521 nandi 10h ago92# web the JavaScript build of the same core, driven as a browser
93# drives it. Needs node and nothing else.
Six verbs, and the last of the nix 2e24e64 nandi yesterday94# live the whole stack against a real freeq. Not in `all`: it wants a
95# network and a running server.
96#
97# just test all of them
98# just test nim tircparse one Nim file
The core, compiled to JavaScript 5ac0521 nandi 10h ago99[doc('run a suite: all nim dart layout web live')]
Six verbs, and the last of the nix 2e24e64 nandi yesterday100test suite="all" *args:
A third target, and the seam that was already waiting for it f54ca45 nandi 3d ago101 #!/usr/bin/env bash
102 set -euo pipefail
Six verbs, and the last of the nix 2e24e64 nandi yesterday103 cd "{{root}}"
104 shift
105 case "{{suite}}" in
The core, compiled to JavaScript 5ac0521 nandi 10h ago106 all) just test nim && just test dart && just test layout \
107 && just test web ;;
Lay every screen out in a test, and fix what that found 36bdfc5 nandi yesterday108 layout) just _nim-lib
109 just _flutter layout test ;;
Six verbs, and the last of the nix 2e24e64 nandi yesterday110 nim) just _nim-test "$@" ;;
The core, compiled to JavaScript 5ac0521 nandi 10h ago111 web) just _nim-js
112 exec node nim/web/test/smoke.js build/web/frq_core.js ;;
Six verbs, and the last of the nix 2e24e64 nandi yesterday113 dart) just _nim-lib
114 exec "{{tc}}" exec -- bash -c \
115 'cd dart/frq_core && dart pub get && dart test -r expanded' ;;
116 live) just _nim-lib
117 exec "{{tc}}" exec -- bash -c \
118 'cd dart/frq_core && dart pub get >/dev/null && dart run tool/live_ui.dart "$@"' _ "$@" ;;
The core, compiled to JavaScript 5ac0521 nandi 10h ago119 *) echo "usage: just test [all|nim|dart|layout|web|live]" >&2; exit 1 ;;
Six verbs, and the last of the nix 2e24e64 nandi yesterday120 esac
A third target, and the seam that was already waiting for it f54ca45 nandi 3d ago121
Six verbs, and the last of the nix 2e24e64 nandi yesterday122# The containers in `.modal/`, run on Modal rather than here: this machine
123# evaluates and Modal builds. See CLAUDE.md, which says so rather more firmly.
A shell that is already the devShell, and two recipes to reach it e853593 nandi 6d ago124#
Six verbs, and the last of the nix 2e24e64 nandi yesterday125# `--shell` leaves a sandbox running with the container's own image, volumes
126# and environment, and prints the command to attach to it. It blocks — an
127# ephemeral app takes its sandbox down when the entrypoint returns — so attach
128# from a second terminal and Ctrl-C here when done. The sandbox bills until
129# you do.
A shell that is already the devShell, and two recipes to reach it e853593 nandi 6d ago130#
Six verbs, and the last of the nix 2e24e64 nandi yesterday131# just modal dev
The last of the Clojure 284b59c nandi yesterday132# just modal dev --shell
Six verbs, and the last of the nix 2e24e64 nandi yesterday133[doc('run a .modal/ container on Modal')]
134modal container="dev" *args:
A shell that is already the devShell, and two recipes to reach it e853593 nandi 6d ago135 #!/usr/bin/env bash
136 set -euo pipefail
Six verbs, and the last of the nix 2e24e64 nandi yesterday137 cd "{{root}}"
138 shift || true
A shell that is already the devShell, and two recipes to reach it e853593 nandi 6d ago139 exec modal run ".modal/{{container}}/container.py" "$@"
140
CI builds the image, Modal serves it 5693bd5 nandi 9h ago141# Deploy, rather than run: a URL that stays up between pushes.
142#
The registry it pushes to is the one it has 627b785 nandi 9h ago143# Nothing is built here. `.modal/web/` points at an image rickub already made
144# and pushed, and FRQ_WEB_IMAGE is which tag of it — so this is the same
145# command the `web` workflow's deploy job runs, with the tag named by hand
146# instead of by the commit. Normally you want the job; this is for deploying an older tag, or a
CI builds the image, Modal serves it 5693bd5 nandi 9h ago147# first deploy before CI has one.
148#
The registry it pushes to is the one it has 627b785 nandi 9h ago149# FRQ_WEB_IMAGE=registry.rickub.com/nandi/frq-web:<sha> just deploy web
CI builds the image, Modal serves it 5693bd5 nandi 9h ago150[doc('deploy a .modal/ container as a URL (needs FRQ_WEB_IMAGE)')]
151deploy container="web":
152 #!/usr/bin/env bash
153 set -euo pipefail
154 cd "{{root}}"
155 if [ -z "${FRQ_WEB_IMAGE:-}" ]; then
156 echo "deploy: set FRQ_WEB_IMAGE to the image tag CI pushed" >&2
157 echo " e.g. registry.gitlab.com/<ns>/frq/web:\$(git rev-parse HEAD)" >&2
158 exit 1
159 fi
The web container is plain Modal bd10e81 nandi 8h ago160 # `app.py` for `web`, which is plain Modal; a `container.py` for anything
161 # described by a `container.toml`.
162 spec=".modal/{{container}}/app.py"
163 [ -f "$spec" ] || spec=".modal/{{container}}/container.py"
164 exec modal deploy "$spec"
CI builds the image, Modal serves it 5693bd5 nandi 9h ago165
The core, compiled to JavaScript 5ac0521 nandi 10h ago166# The same core, compiled to JavaScript.
167#
168# `--path:src --path:web`, in that order, because the later path wins: every
169# module under `nim/web/frq` shadows the one beside it in `nim/src/frq`, so
170# `frq/conn` is a queue the host fills rather than two socket threads, and the
171# shared code above them never learns which host it is on.
A web version, from the same core 23846db nandi 10h ago172# The web bundle: the core as JavaScript, and Flutter around it.
173#
174# The core goes into `flutter/web/` rather than being copied afterwards,
175# because `flutter build web` copies that directory into the bundle — so the
176# page's `<script src="frq_core.js">` resolves the same in a dev server as it
177# does in the built output.
178[private]
179_web-bundle:
180 #!/usr/bin/env bash
181 set -euo pipefail
182 cd "{{root}}"
183 just _nim-js
184 cp build/web/frq_core.js flutter/web/frq_core.js
185 exec "{{tc}}" exec -- bash -euo pipefail -c '
186 cd flutter
187 flutter pub get
188 flutter build web
189 rm -rf ../build/web
190 cp -r build/web ../build/web
191 echo "built build/web"'
192
The core, compiled to JavaScript 5ac0521 nandi 10h ago193[private]
194_nim-js:
195 #!/usr/bin/env bash
196 set -euo pipefail
197 cd "{{root}}"
198 out="{{root}}/build/web"
199 mkdir -p "$out"
200 exec "{{tc}}" exec -- bash -euo pipefail -c '
201 cd nim
202 nim js -d:release --hints:off \
203 --path:src --path:web --out:"'"$out"'/frq_core.js" web/frq_web.nim
204 printf "built %s (%s)\n" "'"$out"'/frq_core.js" \
205 "$(gzip -9c "'"$out"'/frq_core.js" | wc -c | awk "{printf \"%d KB gzipped\", \$1/1024}")"'
206
Six verbs, and the last of the nix 2e24e64 nandi yesterday207[private]
208_nim-lib:
One frontend where there were three, and a core that is not Clojure 438b247 nandi yesterday209 #!/usr/bin/env bash
210 set -euo pipefail
Six verbs, and the last of the nix 2e24e64 nandi yesterday211 cd "{{root}}"
212 out="{{root}}/build/nim"
One frontend where there were three, and a core that is not Clojure 438b247 nandi yesterday213 mkdir -p "$out"
Six verbs, and the last of the nix 2e24e64 nandi yesterday214 exec "{{tc}}" exec -- bash -euo pipefail -c '
215 cd nim
216 nim c --app:lib --mm:orc -d:release --hints:off \
217 --path:src --out:"'"$out"'/libfrqcore.so" src/frq_core.nim
218 echo "built '"$out"'/libfrqcore.so"
219 nm -D --defined-only "'"$out"'/libfrqcore.so" | grep " T frq_" || true'
220
221[private]
222_nim-test *args:
The binding is Dart, and it works f7aea3b nandi yesterday223 #!/usr/bin/env bash
224 set -euo pipefail
Six verbs, and the last of the nix 2e24e64 nandi yesterday225 cd "{{root}}"
226 exec "{{tc}}" exec -- bash -euo pipefail -c '
227 cd nim
228 if [ -n "${1:-}" ]; then
229 exec nim c -r --hints:off --path:src "tests/$1.nim"
230 fi
231 for t in tests/t*.nim; do
232 echo "== $t"
233 nim c -r --hints:off --path:src "$t"
234 done' _ "$@"
235
236[private]
237_flutter target action:
Nim under the existing UI, not instead of it 56551a8 nandi yesterday238 #!/usr/bin/env bash
239 set -euo pipefail
Six verbs, and the last of the nix 2e24e64 nandi yesterday240 cd "{{root}}"
The last of the Clojure 284b59c nandi yesterday241 just _nim-lib
Six verbs, and the last of the nix 2e24e64 nandi yesterday242 exec "{{tc}}" exec -- bash -euo pipefail -c '
243 cd flutter
244 # Nim resolves OpenSSL through dynlib at run time; without the host
245 # library on the loader path `newContext` dies in a SIGSEGV that says
246 # nothing about SSL.
247 export LD_LIBRARY_PATH="${FRQ_OPENSSL_LIB:-}${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
The last of the Clojure 284b59c nandi yesterday248 flutter pub get
Six verbs, and the last of the nix 2e24e64 nandi yesterday249 case "$1:$2" in
The last of the Clojure 284b59c nandi yesterday250 desktop:build) exec flutter build linux --debug ;;
251 desktop:run) exec flutter run -d linux ;;
Lay every screen out in a test, and fix what that found 36bdfc5 nandi yesterday252 # Widget tests, which lay every screen out for real. Headless: no
The last of the Clojure 284b59c nandi yesterday253 # GL and no window, which is what makes them the check a Wayland
Lay every screen out in a test, and fix what that found 36bdfc5 nandi yesterday254 # window cannot be.
The last of the Clojure 284b59c nandi yesterday255 layout:test) exec flutter test test/nim_layout_test.dart ;;
256 *) echo "unknown target/action: $1 $2" >&2; exit 1 ;;
Six verbs, and the last of the nix 2e24e64 nandi yesterday257 esac' _ "{{target}}" "{{action}}"