| Inline the babashka scripts into the justfile 76dcc6c nandi 10d ago | 1 | # 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 | # |
| 6 | # Every recipe that runs frq has the same shape: outside the dev shell, re-enter |
| 7 | # it and come back to this same recipe; inside, hand jolt the deps overrides and |
| 8 | # the library path the shell exported. The re-entry test is JOLT_NATIVE_LIB, |
| 9 | # which only the shell sets — no flag to forget, and no second code path for |
| Name the libcosmic recipe for its backend: `just cosmic run` 5ba9382 nandi 6d ago | 10 | # someone who runs `nix develop --command just cosmic run` by hand. |
| Take glimmer-vidya from gitlab, so a stranger can build this 5c40e75 nandi 18d ago | 11 | |
| Write the build in babashka, and pin the babashka 34832a8 nandi 18d ago | 12 | set shell := ["bash", "-euo", "pipefail", "-c"] |
| A freeq client in jolt, as glimmer components on Vidya 4719d6f nandi 19d ago | 13 | |
| Give the terminal's classpath an nREPL, and hand recipes their arguments 664397d nandi 10d ago | 14 | # 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 |
| 16 | # rather than handing it argv — and `just tui --headless` silently ran the |
| 17 | # terminal instead. |
| 18 | set positional-arguments |
| 19 | |
| Inline the babashka scripts into the justfile 76dcc6c nandi 10d ago | 20 | # nix is not on every host this runs on: on the machine these recipes were |
| 21 | # written for it lives in an Arch distrobox, at the same path — which is why |
| 22 | # the container is entered rather than the tree copied into it. See CLAUDE.md. |
| 23 | nix := `command -v nix >/dev/null 2>&1 && echo nix || echo "distrobox enter arch -- nix"` |
| 24 | |
| 25 | # --max-jobs 0 is what sends the work to the `builders` entry rather than |
| 26 | # compiling it here. Left to the default, nix prefers the local machine, and a |
| 27 | # cold jolt-native is egui, openh264 and quinn on a laptop — for a derivation a |
| 28 | # remote builder has likely built already. FRQ_MAX_JOBS=auto is the way out on |
| 29 | # a machine with no builder configured. |
| 30 | jobs := env("FRQ_MAX_JOBS", "0") |
| 31 | |
| A freeq client in jolt, as glimmer components on Vidya 4719d6f nandi 19d ago | 32 | default: |
| 33 | @just --list |
| 34 | |
| Paint the phone in COSMIC's own theme, read from cosmic-config ba4e71b nandi 7d ago | 35 | # Re-read the COSMIC theme into the APK. |
| 36 | # |
| 37 | # libcosmic asks cosmic-config for the accent and the surfaces at run time, so |
| Name the libcosmic recipe for its backend: `just cosmic run` 5ba9382 nandi 6d ago | 38 | # `just cosmic run` already follows COSMIC Settings as it changes. A phone has |
| 39 | # no cosmic-config, so the APK carries them instead — read here, on the machine |
| Paint the phone in COSMIC's own theme, read from cosmic-config ba4e71b nandi 7d ago | 40 | # that has them, and compiled in. That is the one real difference between the |
| 41 | # two, and it is why the generated file is in git rather than gitignored: a |
| 42 | # checkout on a machine with no COSMIC still builds. |
| 43 | # |
| 44 | # Run it after changing the theme in COSMIC Settings, then `just apk`. |
| 45 | theme: |
| 46 | #!/usr/bin/env bash |
| 47 | set -euo pipefail |
| 48 | cd "{{justfile_directory()}}" |
| 49 | python3 tools/cosmic2cljd.py flutter/src/frq/theme/cosmic.cljd |
| 50 | |
| Build the APK, out of ClojureDart and Flutter e2b0e6b nandi 7d ago | 51 | # The APK: ClojureDart compiled to Dart, then Flutter's Gradle build. |
| 52 | # |
| 53 | # Impure on purpose, and worth saying why rather than leaving it to be |
| 54 | # discovered. Gradle resolves its own dependencies over the network and |
| 55 | # installs build-tools and a platform into ANDROID_HOME as it goes, so it |
| 56 | # cannot run in a sandbox and cannot write to the store. What nix gives here |
| 57 | # is the toolchain — clojure, a JDK, Flutter, and an SDK composed by |
| 58 | # androidenv — and the recipe copies that SDK somewhere writable |
| 59 | # (flutter/.home) for Gradle to finish off. That copy and everything Gradle |
| 60 | # leaves behind are gitignored. |
| 61 | # |
| 62 | # No ndkVersion in android/app/build.gradle.kts, for the same reason: the |
| 63 | # Flutter template sets it, setting it makes Gradle fetch that exact NDK, and |
| 64 | # there is no native code here to need one. |
| 65 | # |
| 66 | # just apk build the debug APK |
| 67 | # just apk install build it and put it on a connected device |
| 68 | # just apk run install and launch |
| 69 | # just apk log logcat, filtered to this app |
| 70 | apk action="build": |
| 71 | #!/usr/bin/env bash |
| 72 | set -euo pipefail |
| 73 | cd "{{justfile_directory()}}/flutter" |
| 74 | |
| Build the APK from the flake, at the rev flake.lock pins 77d4bec nandi 6d ago | 75 | # The flake's, not an --impure --expr against whatever nixos-unstable is |
| 76 | # today: the licence config the SDK needs lives in `androidPkgsFor` now, |
| 77 | # so this is an ordinary output at the rev flake.lock pins. |
| 78 | sdk="$(nix build --no-link --print-out-paths \ |
| 79 | "{{justfile_directory()}}#android-sdk")/libexec/android-sdk" |
| Build the APK, out of ClojureDart and Flutter e2b0e6b nandi 7d ago | 80 | |
| Let adb keep its identity when the APK recipe moves HOME bc0e14f nandi 6d ago | 81 | # adb keeps the key the phone has already trusted under the real HOME, and |
| 82 | # HOME moves below so Gradle can write into the SDK copy. Told where to |
| 83 | # look, adb keeps its identity; left to find $HOME/.android it generates a |
| 84 | # new one, the device stops recognising this machine, and the deploy ends |
| 85 | # in "no devices/emulators found" while `adb devices` in any other shell |
| 86 | # lists it perfectly well. |
| 87 | export ANDROID_USER_HOME="${ANDROID_USER_HOME:-$HOME/.android}" |
| 88 | |
| Build the APK, out of ClojureDart and Flutter e2b0e6b nandi 7d ago | 89 | export HOME="$PWD/.home" |
| 90 | export ANDROID_HOME="$HOME/android-sdk" |
| 91 | export ANDROID_SDK_ROOT="$ANDROID_HOME" |
| 92 | mkdir -p "$HOME" |
| 93 | |
| 94 | # Gradle writes into ANDROID_HOME, so it is a copy rather than the store |
| 95 | # path. Made once and kept: re-copying would throw away the build-tools |
| 96 | # and platform Gradle installed into it on the last run. |
| 97 | if [ ! -d "$ANDROID_HOME" ]; then |
| 98 | cp -r "$sdk" "$ANDROID_HOME" |
| 99 | chmod -R u+w "$ANDROID_HOME" |
| 100 | fi |
| 101 | |
| Seed the ClojureDart caches out of the flake f2e12af nandi 6d ago | 102 | # The compile's three caches, same flake-output-and-copy shape as the SDK |
| 103 | # and for the same reason: tools.deps and pub both write into theirs, and |
| 104 | # the store is read-only. What this buys is the "Resolving dependencies… |
| 105 | # Downloading packages…" that used to open every run. |
| 106 | deps="$(nix build --no-link --print-out-paths \ |
| 107 | "{{justfile_directory()}}#cljd-deps")" |
| 108 | |
| 109 | # Neither of these follows HOME. Both are read off the JVM's user.home, |
| 110 | # which comes from /etc/passwd rather than the environment — so moving |
| 111 | # HOME below is not enough to move them, and left alone they would be the |
| 112 | # real ~/.m2 and ~/.gitlibs, shared with every other project on the box. |
| 113 | export GITLIBS="$HOME/gitlibs" |
| 114 | m2="$HOME/m2" |
| 115 | export PUB_CACHE="$HOME/.pub-cache" |
| 116 | |
| 117 | # Seeded once each and then left alone, exactly as ANDROID_HOME is: after |
| 118 | # the first compile these hold whatever the working tree has asked for |
| 119 | # since, and re-copying would throw that away. |
| 120 | seed() { |
| 121 | [ -e "$2" ] && return 0 |
| 122 | mkdir -p "$(dirname "$2")" |
| 123 | cp -r "$deps/$1" "$2" |
| 124 | chmod -R u+w "$2" |
| 125 | } |
| 126 | seed m2 "$m2" |
| 127 | seed gitlibs "$GITLIBS" |
| 128 | seed pub-cache "$PUB_CACHE" |
| 129 | seed clojuredart/cache "$PWD/.clojuredart/cache" |
| 130 | |
| Build the APK from the flake, at the rev flake.lock pins 77d4bec nandi 6d ago | 131 | # Also the flake's. `nix shell nixpkgs#...` read the registry, which is a |
| 132 | # different and unlocked nixpkgs — the Flutter that built the APK could |
| 133 | # move under it without flake.lock changing a line. |
| 134 | flutter="nix develop {{justfile_directory()}}#flutter --command" |
| Build the APK, out of ClojureDart and Flutter e2b0e6b nandi 7d ago | 135 | |
| Seed the ClojureDart caches out of the flake f2e12af nandi 6d ago | 136 | # cljd-deps ships the analyzer project unresolved — a fixed-output |
| 137 | # derivation may not name the store, and a resolved pub project is |
| 138 | # nothing but store paths. So it is resolved here instead, offline, |
| 139 | # against the cache that derivation did fetch. ClojureDart reaches for the |
| 140 | # network only when bin/analyzer.dart is missing, and after this it is not. |
| 141 | for helper in .clojuredart/cache/*/cljd_helper; do |
| 142 | [ -d "$helper" ] || continue |
| 143 | [ -e "$helper/.dart_tool/package_config.json" ] && continue |
| 144 | ( cd "$helper" && $flutter flutter pub get --offline ) |
| 145 | done |
| 146 | |
| 147 | $flutter clojure -Sdeps "{:mvn/local-repo \"$m2\"}" -M:cljd compile |
| Build the APK, out of ClojureDart and Flutter e2b0e6b nandi 7d ago | 148 | |
| 149 | # Rewritten every run: it carries absolute store paths, and the flutter |
| 150 | # one moves whenever nixpkgs does. |
| 151 | $flutter flutter config --android-sdk "$ANDROID_HOME" >/dev/null |
| 152 | |
| 153 | apk=build/app/outputs/flutter-apk/app-debug.apk |
| 154 | adb="${ADB:-$ANDROID_HOME/platform-tools/adb}" |
| 155 | |
| 156 | case "{{action}}" in |
| 157 | build) $flutter flutter build apk --debug ;; |
| 158 | install) $flutter flutter build apk --debug && "$adb" install -r "$apk" ;; |
| 159 | run) $flutter flutter build apk --debug && "$adb" install -r "$apk" \ |
| 160 | && "$adb" shell monkey -p uk.nandi.frq -c android.intent.category.LAUNCHER 1 ;; |
| 161 | log) "$adb" logcat -s flutter ;; |
| 162 | *) echo "usage: just apk [build|install|run|log]" >&2; exit 1 ;; |
| 163 | esac |
| 164 | |
| Inline the babashka scripts into the justfile 76dcc6c nandi 10d ago | 165 | # Two halves, and the split is the point. The frq source is the files on disk, |
| Split the tree three ways, and let the phone be Flutter's 7070931 nandi 7d ago | 166 | # uncommitted edits and all. Everything under it — jolt, glimmer, glimmer-cosmic |
| 167 | # and the native objects — is the flake's, built rather than fetched. |
| Inline the babashka scripts into the justfile 76dcc6c nandi 10d ago | 168 | # |
| 169 | # Deliberately not `nix run .#frq`. That builds the flake's own copy of the |
| 170 | # source, which is the tree as git has it — so an edit that has not been |
| 171 | # committed, or committed on a branch the command was not pointed at, runs as |
| 172 | # whatever was there before, silently. A run meant to answer "does my change |
| 173 | # work" has to be the files on disk. |
| 174 | # |
| Split the tree three ways, and let the phone be Flutter's 7070931 nandi 7d ago | 175 | # libcosmic paints through wgpu, so this needs nixGL off NixOS for the same |
| 176 | # reason the window always did: the real driver is the host's. |
| 177 | # |
| 178 | # There is no jvui and no vidya here any more — both were experiments. The |
| 179 | # window is libcosmic and the terminal is libjolttui, and those are the two. |
| 180 | # |
| Run this tree on a native half the builders made a32699e nandi 16d ago | 181 | # The app: this tree's source on the flake's everything-else, in the dev shell. |
| Name the libcosmic recipe for its backend: `just cosmic run` 5ba9382 nandi 6d ago | 182 | # |
| 183 | # Named for the backend rather than for the verb, the way `flutter-desktop` |
| 184 | # is: two desktop GUIs, neither of them the default one. |
| 185 | # |
| 186 | # just cosmic run [args...] open the window |
| 187 | cosmic action="run" *args: |
| Inline the babashka scripts into the justfile 76dcc6c nandi 10d ago | 188 | #!/usr/bin/env bash |
| 189 | set -euo pipefail |
| 190 | cd "{{justfile_directory()}}" |
| Name the libcosmic recipe for its backend: `just cosmic run` 5ba9382 nandi 6d ago | 191 | if [ "{{action}}" != "run" ]; then |
| 192 | echo "usage: just cosmic run [args...]" >&2 |
| 193 | exit 1 |
| 194 | fi |
| 195 | shift |
| Inline the babashka scripts into the justfile 76dcc6c nandi 10d ago | 196 | if [ -z "${JOLT_NATIVE_LIB:-}" ]; then |
| Name the libcosmic recipe for its backend: `just cosmic run` 5ba9382 nandi 6d ago | 197 | exec {{nix}} develop . --max-jobs {{jobs}} --command just cosmic run "$@" |
| Inline the babashka scripts into the justfile 76dcc6c nandi 10d ago | 198 | fi |
| 199 | |
| 200 | deps="{:deps {jolt-lang/glimmer {:local/root \"$GLIMMER_SRC\"}" |
| Split the tree three ways, and let the phone be Flutter's 7070931 nandi 7d ago | 201 | deps="$deps nandi/glimmer-cosmic {:local/root \"$GLIMMER_COSMIC_SRC\"}}}" |
| Inline the babashka scripts into the justfile 76dcc6c nandi 10d ago | 202 | |
| 203 | export LD_LIBRARY_PATH="$JOLT_NATIVE_LIB:$FRQ_LIB_PATH${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" |
| Paint the same screens into a terminal ab83b42 nandi 16d ago | 204 | |
| Inline the babashka scripts into the justfile 76dcc6c nandi 10d ago | 205 | runner=() |
| 206 | [ -e /run/current-system ] || runner=("$NIXGL") |
| 207 | |
| Split the tree three ways, and let the phone be Flutter's 7070931 nandi 7d ago | 208 | exec "${runner[@]}" jolt -Sdeps "$deps" -m frq.cosmic "$@" |
| Inline the babashka scripts into the justfile 76dcc6c nandi 10d ago | 209 | |
| Name the libcosmic recipe for its backend: `just cosmic run` 5ba9382 nandi 6d ago | 210 | # `cosmic` with the other backend under it. Only libjolttui: `frq.app` names no |
| Split the tree three ways, and let the phone be Flutter's 7070931 nandi 7d ago | 211 | # backend at all any more, and `frq.tui` requires glimmer-tui so the one |
| 212 | # installed is the terminal. |
| Inline the babashka scripts into the justfile 76dcc6c nandi 10d ago | 213 | # |
| Name the libcosmic recipe for its backend: `just cosmic run` 5ba9382 nandi 6d ago | 214 | # No nixGL here, unlike `cosmic`: a terminal wants nothing from the host's GL |
| Inline the babashka scripts into the justfile 76dcc6c nandi 10d ago | 215 | # driver, which is the reason this output exists on machines that have none. |
| 216 | # |
| Check what common/ may contain, on every push 86c2e1b nandi 6d ago | 217 | # What may appear in common/, checked — the half of the tree both backends |
| 218 | # compile. Needs nothing built: it reads the source, so it is the one check |
| 219 | # that runs anywhere, and CI runs exactly this. |
| 220 | check-common: |
| 221 | #!/usr/bin/env bash |
| 222 | python3 tools/check-common.py common |
| 223 | |
| Paint the same screens into a terminal ab83b42 nandi 16d ago | 224 | # The same screens in a terminal. `just tui --headless` prints one screenshot. |
| 225 | tui *args: |
| Inline the babashka scripts into the justfile 76dcc6c nandi 10d ago | 226 | #!/usr/bin/env bash |
| 227 | set -euo pipefail |
| 228 | cd "{{justfile_directory()}}" |
| 229 | if [ -z "${JOLT_NATIVE_LIB:-}" ]; then |
| 230 | exec {{nix}} develop . --max-jobs {{jobs}} --command just tui "$@" |
| 231 | fi |
| 232 | |
| 233 | deps="{:deps {jolt-lang/glimmer {:local/root \"$GLIMMER_SRC\"}" |
| 234 | deps="$deps nandi/glimmer-tui {:local/root \"$GLIMMER_TUI_SRC\"}}}" |
| 235 | |
| 236 | export LD_LIBRARY_PATH="$JOLT_NATIVE_LIB${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" |
| Build the desktop libraries rather than fetching a release of them 0b81161 nandi 14d ago | 237 | |
| Inline the babashka scripts into the justfile 76dcc6c nandi 10d ago | 238 | exec jolt -Sdeps "$deps" -m frq.tui "$@" |
| 239 | |
| Give the terminal's classpath an nREPL, and hand recipes their arguments 664397d nandi 10d ago | 240 | # The same classpath as `tui`, with an nREPL on it instead of a `-main`: a |
| 241 | # session that can require `frq.tui` and then redefine a component while it is |
| 242 | # on screen, which is a second and not the minute a rebuild costs. |
| 243 | # |
| 244 | # just nrepl then, from an editor or a client on 7888: |
| 245 | # (require (quote frq.tui)) both backends, terminal installed last |
| 246 | # (frq.tui/-main "--headless" "--demo") |
| 247 | # (glimmer.core/reload!) re-mount after redefining a component |
| 248 | # |
| 249 | # `just repl nrepl-server` is the window's half of this — the same thing minus |
| 250 | # glimmer-tui. Port is nrepl-server's own positional: `just nrepl 7889`. |
| 251 | nrepl *args: |
| 252 | #!/usr/bin/env bash |
| 253 | set -euo pipefail |
| 254 | cd "{{justfile_directory()}}" |
| 255 | if [ -z "${JOLT_NATIVE_LIB:-}" ]; then |
| 256 | exec {{nix}} develop . --max-jobs {{jobs}} --command just nrepl "$@" |
| 257 | fi |
| 258 | |
| 259 | deps="{:deps {jolt-lang/glimmer {:local/root \"$GLIMMER_SRC\"}" |
| 260 | deps="$deps nandi/glimmer-tui {:local/root \"$GLIMMER_TUI_SRC\"}}}" |
| 261 | |
| 262 | export LD_LIBRARY_PATH="$JOLT_NATIVE_LIB:$FRQ_LIB_PATH${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" |
| 263 | |
| 264 | exec jolt -Sdeps "$deps" nrepl-server "$@" |
| 265 | |
| Inline the babashka scripts into the justfile 76dcc6c nandi 10d ago | 266 | # `jolt` in the repo root does not work on its own: deps.edn carries |
| 267 | # :jolt/native, so every invocation here loads libvidya and libjoltmoq before it |
| 268 | # reads a line, and dies naming the library if the loader cannot find them. So |
| Name the libcosmic recipe for its backend: `just cosmic run` 5ba9382 nandi 6d ago | 269 | # this is `cosmic` without the app — and `cosmic` is this with a window's |
| 270 | # worth of |
| Inline the babashka scripts into the justfile 76dcc6c nandi 10d ago | 271 | # extra care about the GL driver. |
| 272 | # |
| Build the desktop libraries rather than fetching a release of them 0b81161 nandi 14d ago | 273 | # A jolt with the native libraries under it: a REPL, or `just repl nrepl-server`. |
| 274 | repl *args: |
| Inline the babashka scripts into the justfile 76dcc6c nandi 10d ago | 275 | #!/usr/bin/env bash |
| 276 | set -euo pipefail |
| 277 | cd "{{justfile_directory()}}" |
| 278 | if [ -z "${JOLT_NATIVE_LIB:-}" ]; then |
| 279 | exec {{nix}} develop . --max-jobs {{jobs}} --command just repl "$@" |
| 280 | fi |
| 281 | |
| 282 | deps="{:deps {jolt-lang/glimmer {:local/root \"$GLIMMER_SRC\"}" |
| Split the tree three ways, and let the phone be Flutter's 7070931 nandi 7d ago | 283 | deps="$deps nandi/glimmer-cosmic {:local/root \"$GLIMMER_COSMIC_SRC\"}}}" |
| Inline the babashka scripts into the justfile 76dcc6c nandi 10d ago | 284 | |
| 285 | export LD_LIBRARY_PATH="$JOLT_NATIVE_LIB:$FRQ_LIB_PATH${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" |
| 286 | |
| 287 | exec jolt -Sdeps "$deps" "$@" |
| Bind libmoq_ffi from the object's own metadata, not from its header 9f081a1 nandi 8d ago | 288 | |
| 289 | # Regenerate src/frq/moq/raw.clj from the libmoq_ffi we actually load. |
| 290 | # |
| 291 | # UniFFI embeds its interface metadata in the object, so `uniffi-bindgen |
| 292 | # --library` reads the truth out of the .so rather than a header shipped |
| Fetch libmoq_ffi again, and keep the codecs out of Rust f518938 nandi 8d ago | 293 | # beside it. Those differ at one version number: the published Linux and |
| 294 | # Android objects are built without moq-ffi's `audio` and `video` features |
| 295 | # (206 functions, no codecs), while the shipped C header describes the Apple |
| 296 | # build (230). The object is the only source this recipe will accept. |
| Bind libmoq_ffi from the object's own metadata, not from its header 9f081a1 nandi 8d ago | 297 | # |
| 298 | # The bindgen must match the uniffi that built the object — 0.32 for moq-ffi |
| 299 | # 0.3.17 — and it is built once into the scratch dir rather than pinned into |
| 300 | # the flake: nothing in a normal build needs it, and a regeneration is a thing |
| 301 | # done when the moq-ffi pin moves, by hand, on purpose. |
| 302 | # |
| 303 | # just gen-moq # the loaded library |
| 304 | # just gen-moq path/to/libmoq_ffi.so |
| 305 | # |
| 306 | # Regenerate the libmoq_ffi bindings from the object's own embedded metadata. |
| 307 | gen-moq lib="": |
| 308 | #!/usr/bin/env bash |
| 309 | set -euo pipefail |
| 310 | lib="${1:-${JOLT_NATIVE_LIB:-}/libmoq_ffi.so}" |
| 311 | [ -f "$lib" ] || { echo "no libmoq_ffi.so at $lib — pass one: just gen-moq <path>" >&2; exit 1; } |
| 312 | work="${TMPDIR:-/tmp}/frq-gen-moq" |
| 313 | mkdir -p "$work/ubg/src" |
| 314 | cat > "$work/ubg/Cargo.toml" <<'TOML' |
| 315 | [package] |
| 316 | name = "ubg" |
| 317 | version = "0.1.0" |
| 318 | edition = "2021" |
| 319 | [[bin]] |
| 320 | name = "uniffi-bindgen" |
| 321 | path = "src/main.rs" |
| 322 | [dependencies] |
| 323 | uniffi = { version = "0.32", features = ["cli"] } |
| 324 | TOML |
| 325 | echo 'fn main() { uniffi::uniffi_bindgen_main() }' > "$work/ubg/src/main.rs" |
| 326 | ( cd "$work/ubg" && cargo build --release -q ) |
| 327 | ( cd "$work/ubg" && ./target/release/uniffi-bindgen generate \ |
| 328 | --library "$lib" --language python --out-dir "$work/py" --no-format ) |
| 329 | python3 tools/py2jolt.py "$work"/py/*.py > "$work/body.clj" |
| 330 | { sed -n '1,/^ (:require \[jolt.ffi :as ffi\]))$/p' src/frq/moq/raw.clj; echo; cat "$work/body.clj"; } > "$work/raw.clj" |
| 331 | mv "$work/raw.clj" src/frq/moq/raw.clj |
| 332 | echo "wrote src/frq/moq/raw.clj ($(grep -c '^(ffi/defcfn' src/frq/moq/raw.clj) entry points)" |
| Paint the desktop with Flutter too, beside libcosmic fc5f63c nandi 6d ago | 333 | |
| 334 | # The other desktop GUI: the same screens, painted by Flutter instead of |
| 335 | # libcosmic. |
| 336 | # |
| Name the libcosmic recipe for its backend: `just cosmic run` 5ba9382 nandi 6d ago | 337 | # `just cosmic run` and this one are two frontends over one tree, and the |
| 338 | # split is the same one the APK already draws. Everything under `common/` — the |
| Paint the desktop with Flutter too, beside libcosmic fc5f63c nandi 6d ago | 339 | # screens, the cells, `frq.io` — is shared; what differs is who paints it and |
| 340 | # who answers the host. So this recipe is `just apk` with the Android half |
| 341 | # taken out: the same `clojure -M:cljd compile` over the same flutter/src, |
| 342 | # then Flutter's Linux target rather than its Android one. CMake and Ninja |
| 343 | # instead of Gradle, `flutter/linux/` as the runner, no SDK and no JDK. |
| 344 | # |
| 345 | # Still impure, for one of the two reasons `apk` is: pub.dev resolution and |
| 346 | # Flutter's own engine artifacts are network. What it does NOT need is the |
| 347 | # writable-ANDROID_HOME dance — nothing here writes into the store — so there |
| 348 | # is no `flutter/.home` on this path. |
| 349 | # |
| Name the libcosmic recipe for its backend: `just cosmic run` 5ba9382 nandi 6d ago | 350 | # nixGL for the reason `cosmic` needs it and `tui` does not: Flutter paints |
| Paint the desktop with Flutter too, beside libcosmic fc5f63c nandi 6d ago | 351 | # through GL, and off NixOS the driver is the host's. |
| 352 | # |
| 353 | # just flutter-desktop build the debug bundle |
| 354 | # just flutter-desktop run build it and open the window |
| 355 | flutter-desktop action="build": |
| 356 | #!/usr/bin/env bash |
| 357 | set -euo pipefail |
| 358 | cd "{{justfile_directory()}}" |
| 359 | if [ -z "${FRQ_FLUTTER_DESKTOP:-}" ]; then |
| 360 | exec {{nix}} develop .#flutter-desktop --max-jobs {{jobs}} \ |
| 361 | --command just flutter-desktop "$@" |
| 362 | fi |
| 363 | cd flutter |
| 364 | |
| Seed the ClojureDart caches out of the flake f2e12af nandi 6d ago | 365 | # The same three caches `just apk` seeds, in the same place and out of the |
| 366 | # same flake output — one compiler, one set of dependencies, and no reason |
| 367 | # for the two frontends to keep a copy each. `.home/` is `apk`'s directory |
| 368 | # by name and this is the only thing put there from here, which is the |
| 369 | # point: whichever recipe runs first pays for the copy and the other finds |
| 370 | # it warm. |
| 371 | # |
| 372 | # No `nix build` here, unlike `apk`: this recipe is already inside the |
| 373 | # shell that names FRQ_CLJD_DEPS by the time it gets this far, and `apk` |
| 374 | # needs the path before it enters anything. |
| 375 | # |
| 376 | # m2 and gitlibs are set here for the reason they are set there — the JVM |
| 377 | # reads user.home out of /etc/passwd, so neither follows HOME and left |
| 378 | # alone they are the real ~/.m2 and ~/.gitlibs. |
| 379 | export PUB_CACHE="$PWD/.home/.pub-cache" |
| 380 | export GITLIBS="$PWD/.home/gitlibs" |
| 381 | m2="$PWD/.home/m2" |
| 382 | |
| 383 | seed() { |
| 384 | [ -e "$2" ] && return 0 |
| 385 | mkdir -p "$(dirname "$2")" |
| 386 | cp -r "$FRQ_CLJD_DEPS/$1" "$2" |
| 387 | chmod -R u+w "$2" |
| 388 | } |
| 389 | seed m2 "$m2" |
| 390 | seed gitlibs "$GITLIBS" |
| 391 | seed pub-cache "$PUB_CACHE" |
| 392 | seed clojuredart/cache "$PWD/.clojuredart/cache" |
| 393 | |
| 394 | # Resolved here rather than in cljd-deps, which was not allowed to name |
| 395 | # the store — see the same loop in `apk`. |
| 396 | for helper in .clojuredart/cache/*/cljd_helper; do |
| 397 | [ -d "$helper" ] || continue |
| 398 | [ -e "$helper/.dart_tool/package_config.json" ] && continue |
| 399 | ( cd "$helper" && flutter pub get --offline ) |
| 400 | done |
| 401 | |
| 402 | clojure -Sdeps "{:mvn/local-repo \"$m2\"}" -M:cljd compile |
| Paint the desktop with Flutter too, beside libcosmic fc5f63c nandi 6d ago | 403 | flutter build linux --debug |
| 404 | |
| 405 | # x64/arm64 is Flutter's own name for the host arch, not uname's. |
| 406 | case "$(uname -m)" in |
| 407 | x86_64) arch=x64 ;; |
| 408 | aarch64) arch=arm64 ;; |
| 409 | *) echo "unknown arch $(uname -m)" >&2; exit 1 ;; |
| 410 | esac |
| 411 | bundle="build/linux/$arch/debug/bundle" |
| 412 | |
| 413 | case "{{action}}" in |
| 414 | build) echo "built $PWD/$bundle/frq" ;; |
| 415 | run) |
| 416 | runner=() |
| 417 | [ -e /run/current-system ] || runner=("$NIXGL") |
| 418 | exec "${runner[@]}" "$bundle/frq" |
| 419 | ;; |
| 420 | *) echo "usage: just flutter-desktop [build|run]" >&2; exit 1 ;; |
| 421 | esac |