Skip to content

Commit 719fb9a

Browse files
fix(cli): skip stderr summary on incremental no-op exports
Only print the Exported N of M summary when exported_session_count or failure_count is non-zero, so clean --since incremental cron runs with unchanged mtimes stay silent on stderr. Add subprocess test for the no-op path; tighten since-last early-return test to realistic 0/0 counts.
1 parent e947ced commit 719fb9a

2 files changed

Lines changed: 36 additions & 12 deletions

File tree

scripts/export.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ def _exit_bulk_export(result: BulkExportResult) -> None:
404404
n = result.exported_session_count
405405
m = result.total_candidates
406406
k = result.failure_count
407-
if m > 0 or n > 0 or k > 0:
407+
if n > 0 or k > 0:
408408
print(f"Exported {n} of {m} sessions ({k} failed)", file=sys.stderr)
409409
if n == 0 and k > 0:
410410
sys.exit(1)

tests/test_cli_export_exit_codes.py

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from __future__ import annotations
44

5+
import os
56
import re
67
import sys
78
import types
@@ -22,6 +23,12 @@
2223
)
2324

2425

26+
def _isolated_home_env(tmp_path: Path) -> dict[str, str]:
27+
"""Redirect ~/.claude-code-chat-browser export state for subprocess CLI runs."""
28+
home = str(tmp_path / "home")
29+
return {"HOME": home, "USERPROFILE": home}
30+
31+
2532
def _export_args(tmp_path: Path, base: Path, out_dir: Path) -> types.SimpleNamespace:
2633
return types.SimpleNamespace(
2734
base_dir=str(base),
@@ -96,14 +103,8 @@ def test_since_last_early_return_invokes_exit_bulk_export(
96103

97104
def _track_exit(result: BulkExportResult) -> None:
98105
exit_calls.append(result)
99-
if result.failure_count > 0:
100-
raise SystemExit(1)
101106

102-
fake_result = BulkExportResult(
103-
total_candidates=3,
104-
failure_count=1,
105-
latest_day=None,
106-
)
107+
fake_result = BulkExportResult(latest_day=None)
107108

108109
monkeypatch.setattr(export, "_exit_bulk_export", _track_exit)
109110
monkeypatch.setattr(
@@ -124,13 +125,36 @@ def _track_exit(result: BulkExportResult) -> None:
124125
exclude_rules=None,
125126
)
126127

127-
with pytest.raises(SystemExit) as exc_info:
128-
export.cmd_export(args)
128+
export.cmd_export(args)
129129

130-
assert exc_info.value.code == 1
131130
assert len(exit_calls) == 1
132131
assert exit_calls[0] is fake_result
133-
assert "no qualifying sessions" in capsys.readouterr().out.lower()
132+
captured = capsys.readouterr()
133+
assert "no qualifying sessions" in captured.out.lower()
134+
assert "Exported" not in captured.err
135+
136+
137+
def test_cli_export_incremental_noop_no_stderr_summary(tmp_path):
138+
"""Second incremental run after state is saved: exit 0, no stderr summary."""
139+
base = _seed_base_dir(tmp_path)
140+
out_dir = tmp_path / "out"
141+
home_env = _isolated_home_env(tmp_path)
142+
argv = [
143+
"export",
144+
"--base-dir",
145+
str(base),
146+
"--no-zip",
147+
"--out",
148+
str(out_dir),
149+
]
150+
first = _run_cli([*argv, "--since", "all"], env=home_env)
151+
assert first.returncode == 0, first.stderr
152+
assert list(out_dir.rglob("*.md"))
153+
154+
second = _run_cli([*argv, "--since", "incremental"], env=home_env)
155+
assert second.returncode == 0, second.stderr
156+
assert "Exported" not in second.stderr
157+
assert "Nothing to export" in second.stdout
134158

135159

136160
def test_cli_export_total_failure_exits_one(tmp_path, monkeypatch, capsys):

0 commit comments

Comments
 (0)