feat: party log records a group-readable transcript
tmux pipe-pane on every pane of the party session, appending into <party dir>/log (0640, party group) so any attendee can grab a copy. Start and stop are announced to everyone attached; close rescues a non-empty transcript to the host's home before removing the dir. Panes opened later are picked up by re-running party log (a pane_pipe check keeps already-piped panes single-piped, since tmux's pipe-pane -o toggles an existing pipe closed rather than skipping it). Raw output, escapes included. Close polls the transcript for size stability before rescuing it, since a cross-filesystem mv is copy+unlink and could otherwise drop bytes still draining from the pipe-pane writers.
This commit is contained in:
parent
a011e4b03c
commit
aea7ef58b6
5 changed files with 229 additions and 7 deletions
87
tests/87-log.bats
Normal file
87
tests/87-log.bats
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
#!/usr/bin/env bats
|
||||
#
|
||||
# party log: pipe-pane transcript into the per-party dir. Needs a real
|
||||
# tmux server (pipe-pane semantics can't be stubbed honestly), so most
|
||||
# tests gate on require_party_group like the other e2e suites.
|
||||
|
||||
load 'helpers'
|
||||
|
||||
setup() {
|
||||
setup_party_sandbox
|
||||
export TMUX_PARTY_GROUP="$(id -gn)"
|
||||
}
|
||||
|
||||
teardown() { teardown_party_sandbox; }
|
||||
|
||||
logfile() { printf '%s/party-%s:%s.d/log\n' "$PARTY_SOCKET_DIR" "$USER" "$1"; }
|
||||
sock_of() { printf '%s/party-%s:%s.d/sock\n' "$PARTY_SOCKET_DIR" "$USER" "$1"; }
|
||||
|
||||
# Wait up to ~10s for $2 to appear in file $1. Integer sleeps only:
|
||||
# fractional sleep is not portable across the matrix.
|
||||
poll_for() {
|
||||
for _ in 1 2 3 4 5 6 7 8 9 10; do
|
||||
grep -q "$2" "$1" 2>/dev/null && return 0
|
||||
sleep 1
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
@test "log without a hosted party fails" {
|
||||
run "$PARTY_BIN" log
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" == *"do not host"* ]]
|
||||
}
|
||||
|
||||
@test "log captures pane output; --stop ends capture" {
|
||||
"$PARTY_BIN" host scribe
|
||||
run "$PARTY_BIN" log
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Logging to"* ]]
|
||||
|
||||
tmux -S "$(sock_of scribe)" send-keys -t scribe 'echo marker-ONE' Enter
|
||||
poll_for "$(logfile scribe)" marker-ONE
|
||||
|
||||
run "$PARTY_BIN" log --stop
|
||||
[ "$status" -eq 0 ]
|
||||
tmux -S "$(sock_of scribe)" send-keys -t scribe 'echo marker-TWO' Enter
|
||||
sleep 2
|
||||
! grep -q marker-TWO "$(logfile scribe)"
|
||||
}
|
||||
|
||||
@test "log file is 0640 so group members can copy it" {
|
||||
"$PARTY_BIN" host perms
|
||||
"$PARTY_BIN" log
|
||||
[ -n "$(find "$(logfile perms)" -prune -perm 0640 2>/dev/null)" ]
|
||||
}
|
||||
|
||||
@test "re-running log attaches panes created after the first run" {
|
||||
"$PARTY_BIN" host panes
|
||||
"$PARTY_BIN" log
|
||||
tmux -S "$(sock_of panes)" split-window -t panes
|
||||
"$PARTY_BIN" log
|
||||
tmux -S "$(sock_of panes)" send-keys -t panes.1 'echo marker-PANE2' Enter
|
||||
poll_for "$(logfile panes)" marker-PANE2
|
||||
}
|
||||
|
||||
@test "close rescues a non-empty transcript to HOME" {
|
||||
export HOME="$PARTY_TMP/home"
|
||||
mkdir -p "$HOME"
|
||||
"$PARTY_BIN" host rescue
|
||||
"$PARTY_BIN" log
|
||||
tmux -S "$(sock_of rescue)" send-keys -t rescue 'echo marker-KEEP' Enter
|
||||
poll_for "$(logfile rescue)" marker-KEEP
|
||||
run "$PARTY_BIN" close rescue
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"transcript saved to"* ]]
|
||||
saved=$(ls "$HOME"/party-rescue-*.log)
|
||||
grep -q marker-KEEP "$saved"
|
||||
}
|
||||
|
||||
@test "close without a transcript stays silent about rescue" {
|
||||
export HOME="$PARTY_TMP/home"
|
||||
mkdir -p "$HOME"
|
||||
"$PARTY_BIN" host quiet
|
||||
run "$PARTY_BIN" close quiet
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" != *"transcript"* ]]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue