···116116 # we do this instead of using a `.nix` file because it lets us skip eval time.
117117 environment.etc = lib.mkIf (dependencies != []) {
118118 "spindle/devshell.drv".source = spindleDevShell.drvPath;
119119- "spindle/devshell-inputs".source = spindleDevShell.inputDerivation;
119119+ "spindle/devshell-closure".source = pkgs.closureInfo {rootPaths = [spindleDevShell];};
120120 };
121121 services = builtins.mapAttrs (normalize (options.services or {})) (userConfig.services or {});
122122 virtualisation = builtins.mapAttrs (normalize (options.virtualisation or {})) (userConfig.virtualisation or {});
+44-8
spindle/engines/microvm/test-spindle-microvm.sh
···11#!/usr/bin/env bash
22set -euo pipefail
33+# dont export big captures like `out=$(run_vm ...)` into the environment.
44+set +a
55+# extglob enables the *(...) pattern strip_ansi uses for pure-bash CSI stripping
66+shopt -s extglob
37# note: needs `sudo modprobe vhost_vsock`!
4859log() {
610 printf "\n\033[1;36m>>> %s\033[0m\n" "$*"
1111+}
1212+1313+_strip_ansi_stream() {
1414+ local line
1515+ while IFS= read -r line || [ -n "$line" ]; do
1616+ line=${line//$'\e'\[*([0-9;])[a-zA-Z]/}
1717+ line=${line//$'\e'\([a-zA-Z]/}
1818+ printf '%s\n' "$line"
1919+ done
720}
821922strip_ansi() {
1010- local esc
1111- esc=$(printf '\033')
1212- sed -E "s/${esc}\[[0-9;]*[a-zA-Z]//g; s/${esc}\([a-zA-Z]//g" "$@"
2323+ if [ "$#" -gt 0 ]; then
2424+ local f
2525+ for f in "$@"; do
2626+ [ -r "$f" ] && _strip_ansi_stream < "$f"
2727+ done
2828+ else
2929+ _strip_ansi_stream
3030+ fi
1331}
14321533# check_needles OUT NEEDLES...
3434+# each needle is an extended regex matched per line (mirrors `grep -qE`).
1635check_needles() {
1736 local out="$1"
1837 shift
1919- local clean
2020- clean=$(echo "$out" | strip_ansi)
3838+3939+ local -a lines
4040+ mapfile -t lines <<< "$out"
21412222- local needle missing=0
4242+ # strip ANSI per line (each line is short, so this stays cheap)
4343+ local i l
4444+ for i in "${!lines[@]}"; do
4545+ l=${lines[i]}
4646+ l=${l//$'\e'\[*([0-9;])[a-zA-Z]/}
4747+ l=${l//$'\e'\([a-zA-Z]/}
4848+ lines[i]=$l
4949+ done
5050+5151+ local needle missing=0 line hit
2352 for needle in "$@"; do
2424- if ! echo "$clean" | grep -qE "$needle"; then
5353+ hit=0
5454+ for line in "${lines[@]}"; do
5555+ if [[ $line =~ $needle ]]; then
5656+ hit=1
5757+ break
5858+ fi
5959+ done
6060+ if [ "$hit" -eq 0 ]; then
2561 echo "error: output missing '$needle'" >&2
2662 missing=1
2763 fi
2864 done
29653066 if [ "$missing" -ne 0 ]; then
3131- echo "$clean" >&2
6767+ printf '%s\n' "${lines[@]}" >&2
3268 return 1
3369 fi
3470}