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
20 changes: 14 additions & 6 deletions src/socrates120x/journal.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,23 @@
from __future__ import annotations

import datetime as _dt
import re
import subprocess
import sys
from pathlib import Path

from socrates120x.prompting import editor_command

# Canonical entry filename: YYYY-MM-DD.md. `_list` and `_show_latest`
# must not pick up unrelated .md files (notes.md, ideas.md, README.md)
# that an operator may have dropped into the journal dir.
_ENTRY_NAME = re.compile(r"^\d{4}-\d{2}-\d{2}$")


def _is_journal_entry(p: Path) -> bool:
"""True if *p* is a canonical journal entry file (YYYY-MM-DD.md)."""
return p.suffix == ".md" and bool(_ENTRY_NAME.match(p.stem))


def create_or_open_entry(project: Path, *, show: bool = False, list_all: bool = False) -> int:
"""Create today's journal entry and open $EDITOR, or list/show.
Expand Down Expand Up @@ -73,10 +84,7 @@ def _template(date: str) -> str:


def _list(journal_dir: Path) -> int:
entries = sorted(
p for p in journal_dir.glob("*.md")
if p.name != "README.md"
)
entries = sorted(p for p in journal_dir.glob("*.md") if _is_journal_entry(p))
if not entries:
print("(no journal entries yet — run `socrates journal` to create today's)")
return 0
Expand All @@ -87,11 +95,11 @@ def _list(journal_dir: Path) -> int:

def _show_latest(journal_dir: Path) -> int:
entries = sorted(
(p for p in journal_dir.glob("*.md") if p.name != "README.md"),
(p for p in journal_dir.glob("*.md") if _is_journal_entry(p)),
reverse=True,
)
if not entries:
print("(no journal entries yet)")
return 0
print(entries[0].read_text())
print(entries[0].read_text(encoding="utf-8"))
return 0
58 changes: 58 additions & 0 deletions tests/test_journal.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,61 @@ def test_journal_errors_on_non_project(tmp_path: Path, capsys: pytest.CaptureFix
assert code == 2
err = capsys.readouterr().err
assert "does not exist" in err


# ---------------------------------------------------------------------------
# Only dated entries are listed/shown
# (bugfix/journal-only-dated-entries)
# ---------------------------------------------------------------------------


def test_journal_list_ignores_non_dated_files(tmp_path, capsys) -> None:
"""`socrates journal --list` must NOT enumerate notes.md, ideas.md,
drafts/ etc. that the operator may have dropped into the journal dir.
Only files named YYYY-MM-DD.md count."""
from socrates120x.journal import create_or_open_entry
from socrates120x.scaffold import scaffold

p = tmp_path / "demo"
scaffold(p)
journal_dir = p / "planning" / "journal"
# Create two real dated entries.
(journal_dir / "2025-09-01.md").write_text("# entry", encoding="utf-8")
(journal_dir / "2026-01-15.md").write_text("# entry", encoding="utf-8")
# And several decoy files.
(journal_dir / "notes.md").write_text("# random notes", encoding="utf-8")
(journal_dir / "ideas.md").write_text("# brainstorm", encoding="utf-8")
(journal_dir / "2025-9-1.md").write_text("# unpadded date", encoding="utf-8") # not canonical

rc = create_or_open_entry(p, list_all=True)
assert rc == 0
out = capsys.readouterr().out
assert "2025-09-01" in out
assert "2026-01-15" in out
assert "notes" not in out
assert "ideas" not in out
# README.md (already excluded by original code) stays excluded:
assert "README" not in out
# Unpadded date (2025-9-1) is not canonical:
assert "2025-9-1" not in out


def test_journal_show_picks_latest_dated_not_arbitrary(tmp_path, capsys) -> None:
"""`--show` must pick the LATEST dated entry, not whatever sorts last
alphabetically (which would include notes.md)."""
from socrates120x.journal import create_or_open_entry
from socrates120x.scaffold import scaffold

p = tmp_path / "demo"
scaffold(p)
journal_dir = p / "planning" / "journal"
(journal_dir / "2025-01-01.md").write_text("# old entry", encoding="utf-8")
(journal_dir / "2026-06-15.md").write_text("# latest dated entry body", encoding="utf-8")
# Decoy: 'zzz.md' would sort AFTER any date if we matched all .md.
(journal_dir / "zzz.md").write_text("# decoy notes — should NOT be shown", encoding="utf-8")

rc = create_or_open_entry(p, show=True)
assert rc == 0
out = capsys.readouterr().out
assert "latest dated entry body" in out
assert "decoy" not in out
Loading