feat(devshell): stream quickshell warnings and errors in nix develop
qs-log follows the working-tree instance's log filtered to WARN|ERROR (-a for
everything), and the shellHook starts it in the background once qs-dev is up,
taking it down again in the exit trap alongside qs-prod. A binding loop or a
failed binding is a WARN, and easy to miss when it scrolls past unwatched.
It starts at the end of the log rather than replaying the backlog, and
re-attaches in a loop: `qs log -f` ends when the instance it attached to exits,
and the dev shell outlives individual instances.
Also corrects the hot-reload note added in 7268221, which was wrong on both
counts. Tested against the running shell: `touch` never reloads (mtime is not a
content change) and inode-replacing edits like `sed -i` are picked up fine. The
reliable check is whether `qs log` shows a "Reloading configuration..." line.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HEtXvseVb5gwAtKNhFx2PU
This commit is contained in:
@@ -583,6 +583,7 @@
|
||||
# instance is the identical build to the packaged one.
|
||||
qs = "${nixpkgs.legacyPackages.${system}.quickshell}/bin/qs";
|
||||
git = "${nixpkgs.legacyPackages.${system}.git}/bin/git";
|
||||
grep = "${nixpkgs.legacyPackages.${system}.gnugrep}/bin/grep";
|
||||
|
||||
# Resolved at RUN time, not build time: the entire point is to run the
|
||||
# working tree, and `self` here is only a store snapshot of it.
|
||||
@@ -631,6 +632,33 @@
|
||||
echo "qs-dev: live on $cfg — edits there now hot-reload"
|
||||
'';
|
||||
|
||||
# qs log -f prints everything the instance logs; WARN and ERROR are the
|
||||
# two that mean something is wrong with the QML in front of you. A
|
||||
# binding loop or a failed binding is a WARN and easy to miss when it
|
||||
# scrolls past inside a reload's worth of chatter.
|
||||
qs-log = pkgs.writeShellScriptBin "qs-log" ''
|
||||
set -uo pipefail
|
||||
${preamble}
|
||||
|
||||
filter='WARN|ERROR'
|
||||
case "''${1:-}" in
|
||||
-a|--all) filter='.' ;;
|
||||
esac
|
||||
|
||||
# -t 1: `qs log -f` replays the whole backlog first, which would dump
|
||||
# every historical warning into the terminal on shell entry.
|
||||
#
|
||||
# `qs log -f` ends when the instance it attached to exits, and the dev
|
||||
# shell outlives individual instances — a QML error kills one, `qs-dev`
|
||||
# starts another. Re-attach instead of going quiet for the session.
|
||||
while :; do
|
||||
if running "$cfg"; then
|
||||
${qs} log -p "$cfg" -t 1 -f 2>/dev/null | ${grep} --line-buffered -E "$filter" >&2
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
'';
|
||||
|
||||
qs-prod = pkgs.writeShellScriptBin "qs-prod" ''
|
||||
set -uo pipefail
|
||||
${preamble}
|
||||
@@ -641,7 +669,7 @@
|
||||
'';
|
||||
in
|
||||
pkgs.mkShell {
|
||||
packages = [ pkgs.quickshell qs-dev qs-prod ];
|
||||
packages = [ pkgs.quickshell qs-dev qs-prod qs-log ];
|
||||
|
||||
# Swap on entry, swap back on exit. Three guards:
|
||||
# - interactive only ($- has i). `nix develop --command X` EXECs X,
|
||||
@@ -655,9 +683,15 @@
|
||||
shellHook = ''
|
||||
if [[ $- == *i* ]] && [ -n "''${WAYLAND_DISPLAY:-}" ] && [ -z "''${HOMELAB_QS_DEV:-}" ]; then
|
||||
export HOMELAB_QS_DEV=1
|
||||
qs-dev && trap qs-prod EXIT
|
||||
if qs-dev; then
|
||||
# Stream the dev instance's warnings and errors into this
|
||||
# terminal, and take the follower down with the shell.
|
||||
qs-log & HOMELAB_QS_LOG=$!
|
||||
trap 'kill "$HOMELAB_QS_LOG" 2>/dev/null; qs-prod' EXIT
|
||||
fi
|
||||
fi
|
||||
echo "homelab devshell — qs-dev (working tree) / qs-prod (packaged); exit restores"
|
||||
echo "homelab devshell — quickshell WARN/ERROR stream here; qs-log -a for everything"
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user