| Inline the babashka scripts into the justfile 76dcc6c nandi 11d 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 |
| 10 | # someone who runs `nix develop --command just run` by hand. |
| Take glimmer-vidya from gitlab, so a stranger can build this 5c40e75 nandi 19d 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 20d 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 11d 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 20d ago | 32 | default: |
| 33 | @just --list |
| 34 | |
| Inline the babashka scripts into the justfile 76dcc6c nandi 11d ago | 35 | # 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 | 36 | # uncommitted edits and all. Everything under it — jolt, glimmer, glimmer-cosmic |
| 37 | # and the native objects — is the flake's, built rather than fetched. |
| Inline the babashka scripts into the justfile 76dcc6c nandi 11d ago | 38 | # |
| 39 | # Deliberately not `nix run .#frq`. That builds the flake's own copy of the |
| 40 | # source, which is the tree as git has it — so an edit that has not been |
| 41 | # committed, or committed on a branch the command was not pointed at, runs as |
| 42 | # whatever was there before, silently. A run meant to answer "does my change |
| 43 | # work" has to be the files on disk. |
| 44 | # |
| Split the tree three ways, and let the phone be Flutter's 7070931 nandi 7d ago | 45 | # libcosmic paints through wgpu, so this needs nixGL off NixOS for the same |
| 46 | # reason the window always did: the real driver is the host's. |
| 47 | # |
| 48 | # There is no jvui and no vidya here any more — both were experiments. The |
| 49 | # window is libcosmic and the terminal is libjolttui, and those are the two. |
| 50 | # |
| Run this tree on a native half the builders made a32699e nandi 17d ago | 51 | # The app: this tree's source on the flake's everything-else, in the dev shell. |
| A freeq client in jolt, as glimmer components on Vidya 4719d6f nandi 20d ago | 52 | run *args: |
| Inline the babashka scripts into the justfile 76dcc6c nandi 11d ago | 53 | #!/usr/bin/env bash |
| 54 | set -euo pipefail |
| 55 | cd "{{justfile_directory()}}" |
| 56 | if [ -z "${JOLT_NATIVE_LIB:-}" ]; then |
| 57 | exec {{nix}} develop . --max-jobs {{jobs}} --command just run "$@" |
| 58 | fi |
| 59 | |
| 60 | 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 | 61 | deps="$deps nandi/glimmer-cosmic {:local/root \"$GLIMMER_COSMIC_SRC\"}}}" |
| Inline the babashka scripts into the justfile 76dcc6c nandi 11d ago | 62 | |
| 63 | 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 17d ago | 64 | |
| Inline the babashka scripts into the justfile 76dcc6c nandi 11d ago | 65 | runner=() |
| 66 | [ -e /run/current-system ] || runner=("$NIXGL") |
| 67 | |
| Split the tree three ways, and let the phone be Flutter's 7070931 nandi 7d ago | 68 | exec "${runner[@]}" jolt -Sdeps "$deps" -m frq.cosmic "$@" |
| Inline the babashka scripts into the justfile 76dcc6c nandi 11d ago | 69 | |
| Split the tree three ways, and let the phone be Flutter's 7070931 nandi 7d ago | 70 | # `run` with the other backend under it. Only libjolttui: `frq.app` names no |
| 71 | # backend at all any more, and `frq.tui` requires glimmer-tui so the one |
| 72 | # installed is the terminal. |
| Inline the babashka scripts into the justfile 76dcc6c nandi 11d ago | 73 | # |
| 74 | # No nixGL here, unlike `run`: a terminal wants nothing from the host's GL |
| 75 | # driver, which is the reason this output exists on machines that have none. |
| 76 | # |
| Paint the same screens into a terminal ab83b42 nandi 17d ago | 77 | # The same screens in a terminal. `just tui --headless` prints one screenshot. |
| 78 | tui *args: |
| Inline the babashka scripts into the justfile 76dcc6c nandi 11d ago | 79 | #!/usr/bin/env bash |
| 80 | set -euo pipefail |
| 81 | cd "{{justfile_directory()}}" |
| 82 | if [ -z "${JOLT_NATIVE_LIB:-}" ]; then |
| 83 | exec {{nix}} develop . --max-jobs {{jobs}} --command just tui "$@" |
| 84 | fi |
| 85 | |
| 86 | deps="{:deps {jolt-lang/glimmer {:local/root \"$GLIMMER_SRC\"}" |
| 87 | deps="$deps nandi/glimmer-tui {:local/root \"$GLIMMER_TUI_SRC\"}}}" |
| 88 | |
| 89 | 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 15d ago | 90 | |
| Inline the babashka scripts into the justfile 76dcc6c nandi 11d ago | 91 | exec jolt -Sdeps "$deps" -m frq.tui "$@" |
| 92 | |
| Give the terminal's classpath an nREPL, and hand recipes their arguments 664397d nandi 10d ago | 93 | # The same classpath as `tui`, with an nREPL on it instead of a `-main`: a |
| 94 | # session that can require `frq.tui` and then redefine a component while it is |
| 95 | # on screen, which is a second and not the minute a rebuild costs. |
| 96 | # |
| 97 | # just nrepl then, from an editor or a client on 7888: |
| 98 | # (require (quote frq.tui)) both backends, terminal installed last |
| 99 | # (frq.tui/-main "--headless" "--demo") |
| 100 | # (glimmer.core/reload!) re-mount after redefining a component |
| 101 | # |
| 102 | # `just repl nrepl-server` is the window's half of this — the same thing minus |
| 103 | # glimmer-tui. Port is nrepl-server's own positional: `just nrepl 7889`. |
| 104 | nrepl *args: |
| 105 | #!/usr/bin/env bash |
| 106 | set -euo pipefail |
| 107 | cd "{{justfile_directory()}}" |
| 108 | if [ -z "${JOLT_NATIVE_LIB:-}" ]; then |
| 109 | exec {{nix}} develop . --max-jobs {{jobs}} --command just nrepl "$@" |
| 110 | fi |
| 111 | |
| 112 | deps="{:deps {jolt-lang/glimmer {:local/root \"$GLIMMER_SRC\"}" |
| 113 | deps="$deps nandi/glimmer-tui {:local/root \"$GLIMMER_TUI_SRC\"}}}" |
| 114 | |
| 115 | export LD_LIBRARY_PATH="$JOLT_NATIVE_LIB:$FRQ_LIB_PATH${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" |
| 116 | |
| 117 | exec jolt -Sdeps "$deps" nrepl-server "$@" |
| 118 | |
| Inline the babashka scripts into the justfile 76dcc6c nandi 11d ago | 119 | # `jolt` in the repo root does not work on its own: deps.edn carries |
| 120 | # :jolt/native, so every invocation here loads libvidya and libjoltmoq before it |
| 121 | # reads a line, and dies naming the library if the loader cannot find them. So |
| 122 | # this is `run` without the app — and `run` is this with a window's worth of |
| 123 | # extra care about the GL driver. |
| 124 | # |
| Build the desktop libraries rather than fetching a release of them 0b81161 nandi 15d ago | 125 | # A jolt with the native libraries under it: a REPL, or `just repl nrepl-server`. |
| 126 | repl *args: |
| Inline the babashka scripts into the justfile 76dcc6c nandi 11d ago | 127 | #!/usr/bin/env bash |
| 128 | set -euo pipefail |
| 129 | cd "{{justfile_directory()}}" |
| 130 | if [ -z "${JOLT_NATIVE_LIB:-}" ]; then |
| 131 | exec {{nix}} develop . --max-jobs {{jobs}} --command just repl "$@" |
| 132 | fi |
| 133 | |
| 134 | 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 | 135 | deps="$deps nandi/glimmer-cosmic {:local/root \"$GLIMMER_COSMIC_SRC\"}}}" |
| Inline the babashka scripts into the justfile 76dcc6c nandi 11d ago | 136 | |
| 137 | export LD_LIBRARY_PATH="$JOLT_NATIVE_LIB:$FRQ_LIB_PATH${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" |
| 138 | |
| 139 | exec jolt -Sdeps "$deps" "$@" |
| Bind libmoq_ffi from the object's own metadata, not from its header 9f081a1 nandi 9d ago | 140 | |
| 141 | # Regenerate src/frq/moq/raw.clj from the libmoq_ffi we actually load. |
| 142 | # |
| 143 | # UniFFI embeds its interface metadata in the object, so `uniffi-bindgen |
| 144 | # --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 9d ago | 145 | # beside it. Those differ at one version number: the published Linux and |
| 146 | # Android objects are built without moq-ffi's `audio` and `video` features |
| 147 | # (206 functions, no codecs), while the shipped C header describes the Apple |
| 148 | # 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 9d ago | 149 | # |
| 150 | # The bindgen must match the uniffi that built the object — 0.32 for moq-ffi |
| 151 | # 0.3.17 — and it is built once into the scratch dir rather than pinned into |
| 152 | # the flake: nothing in a normal build needs it, and a regeneration is a thing |
| 153 | # done when the moq-ffi pin moves, by hand, on purpose. |
| 154 | # |
| 155 | # just gen-moq # the loaded library |
| 156 | # just gen-moq path/to/libmoq_ffi.so |
| 157 | # |
| 158 | # Regenerate the libmoq_ffi bindings from the object's own embedded metadata. |
| 159 | gen-moq lib="": |
| 160 | #!/usr/bin/env bash |
| 161 | set -euo pipefail |
| 162 | lib="${1:-${JOLT_NATIVE_LIB:-}/libmoq_ffi.so}" |
| 163 | [ -f "$lib" ] || { echo "no libmoq_ffi.so at $lib — pass one: just gen-moq <path>" >&2; exit 1; } |
| 164 | work="${TMPDIR:-/tmp}/frq-gen-moq" |
| 165 | mkdir -p "$work/ubg/src" |
| 166 | cat > "$work/ubg/Cargo.toml" <<'TOML' |
| 167 | [package] |
| 168 | name = "ubg" |
| 169 | version = "0.1.0" |
| 170 | edition = "2021" |
| 171 | [[bin]] |
| 172 | name = "uniffi-bindgen" |
| 173 | path = "src/main.rs" |
| 174 | [dependencies] |
| 175 | uniffi = { version = "0.32", features = ["cli"] } |
| 176 | TOML |
| 177 | echo 'fn main() { uniffi::uniffi_bindgen_main() }' > "$work/ubg/src/main.rs" |
| 178 | ( cd "$work/ubg" && cargo build --release -q ) |
| 179 | ( cd "$work/ubg" && ./target/release/uniffi-bindgen generate \ |
| 180 | --library "$lib" --language python --out-dir "$work/py" --no-format ) |
| 181 | python3 tools/py2jolt.py "$work"/py/*.py > "$work/body.clj" |
| 182 | { sed -n '1,/^ (:require \[jolt.ffi :as ffi\]))$/p' src/frq/moq/raw.clj; echo; cat "$work/body.clj"; } > "$work/raw.clj" |
| 183 | mv "$work/raw.clj" src/frq/moq/raw.clj |
| 184 | echo "wrote src/frq/moq/raw.clj ($(grep -c '^(ffi/defcfn' src/frq/moq/raw.clj) entry points)" |