Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions ralph-loop.sh
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,20 @@ normalize_memory_max() {
rotate_logs() {
local log_dir=$1
local max_logs=$2

ls -t "$log_dir"/*.log 2>/dev/null | tail -n +"$((max_logs + 1))" | xargs -r rm -f --
local -a logs=()
local line

# Newest first. NUL-delimited so workspace paths with spaces (or other
# whitespace) stay one entry; xargs would split them into separate paths.
while IFS= read -r -d '' line; do
logs+=("${line#*$'\t'}")
done < <(find "$log_dir" -maxdepth 1 -type f -name '*.log' -printf '%T@\t%p\0' 2>/dev/null | sort -z -t $'\t' -k1,1nr)

# Only ever remove entries inside $log_dir, and only the ones past max_logs.
local f
for f in "${logs[@]:max_logs}"; do
rm -f -- "$f"
done
}

find_stop_file() {
Expand Down
46 changes: 46 additions & 0 deletions tests/ralph-loop.bats
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,49 @@ teardown() {
# The stop file must NOT be deleted.
[ -f stop.md ]
}

# Log rotation runs once per iteration. These tests use a fake CLI so the loop
# can run to completion without any real tool installed.
write_env() {
local ws=$1 max_logs=$2
mkdir -p "$ws/.ralph"
cat > "$ws/.ralph/.env" <<CFG
RALPH_TOOL=codex
RALPH_MODEL_CAPABILITY=med
RALPH_THINKING=false
RALPH_SWITCH_ON_EXHAUSTION=false
RALPH_MEMORY_MAX=
RALPH_CODEX_COMMAND=$WORK/faketool
RALPH_CODEX_FLAGS="--noop"
RALPH_LOOP_MAX_LOGS=$max_logs
CFG
printf 'do a thing\n' > "$ws/p.md"
}

setup_fake_tool() {
cat > "$WORK/faketool" <<'SH'
#!/usr/bin/env bash
cat >/dev/null
echo "faketool $*"
SH
chmod +x "$WORK/faketool"
}

@test "log rotation still trims when the workspace path contains a space" {
setup_fake_tool
ws="$WORK/my ws"
write_env "$ws" 1
cd "$ws"
run bash "$SCRIPT" 3 p.md
[ "$(find "$ws/.ralph/logs" -name '*.log' | wc -l)" -eq 1 ]
}

@test "log rotation never removes a file outside the log directory" {
setup_fake_tool
ws="$WORK/my ws"
write_env "$ws" 1
: > "$WORK/my"
cd "$ws"
run bash "$SCRIPT" 3 p.md
[ -e "$WORK/my" ]
}
Loading