diff --git a/hermes_cli/dump.py b/hermes_cli/dump.py index 239a6994b61..82a49b03f1c 100644 --- a/hermes_cli/dump.py +++ b/hermes_cli/dump.py @@ -56,6 +56,30 @@ def _get_git_commit(project_root: Path) -> str: return "(unknown)" +def _get_git_commit_date(project_root: Path) -> str: + """Return the date the HEAD commit was authored (YYYY-MM-DD), or ''. + + Resolves live via ``git log`` on source installs. The published Docker + image excludes ``.git``, so this returns '' there — the dump line simply + drops the date suffix in that case (the baked SHA still identifies the + build). + """ + try: + result = subprocess.run( + ["git", "log", "-1", "--format=%cd", "--date=short", "HEAD"], + capture_output=True, text=True, timeout=5, + cwd=str(project_root), + ) + if result.returncode == 0: + value = result.stdout.strip() + if value: + return value + except Exception: + pass + + return "" + + def _redact(value: str) -> str: """Redact all but first 4 and last 4 chars. @@ -231,12 +255,12 @@ def run_dump(args): hermes_home = get_hermes_home() try: - from hermes_cli import __version__, __release_date__ + from hermes_cli import __version__ except ImportError: __version__ = "(unknown)" - __release_date__ = "" commit = _get_git_commit(project_root) + commit_date = _get_git_commit_date(project_root) try: config = load_config() @@ -283,10 +307,14 @@ def run_dump(args): lines = [] lines.append("--- hermes dump ---") + # Identify the build by commit + the date that commit was made, resolved + # live via git. __release_date__ (the package release date) is + # intentionally NOT shown here — it reads like a wall-clock timestamp and + # confuses support triage. The commit date is the real "as-of" date. ver_str = f"{__version__}" - if __release_date__: - ver_str += f" ({__release_date__})" ver_str += f" [{commit}]" + if commit_date: + ver_str += f" ({commit_date})" lines.append(f"version: {ver_str}") lines.append(f"os: {os_info}") lines.append(f"python: {sys.version.split()[0]}") diff --git a/tests/hermes_cli/test_dump_git_commit.py b/tests/hermes_cli/test_dump_git_commit.py index 264ad22a585..0cfa804f091 100644 --- a/tests/hermes_cli/test_dump_git_commit.py +++ b/tests/hermes_cli/test_dump_git_commit.py @@ -116,3 +116,44 @@ def test_get_git_commit_output_format_identical_between_sources(tmp_path): # Same length, same charset — no decoration in either branch. assert len(live) == 8 assert all(c in "0123456789abcdef" for c in live) + + +def test_get_git_commit_date_uses_live_git(tmp_path): + """Source install: ``git log -1 --format=%cd --date=short`` returns the date.""" + from hermes_cli import dump + + repo_dir = tmp_path / "repo" + repo_dir.mkdir() + + git_result = MagicMock(returncode=0, stdout="2026-06-17\n") + with patch("hermes_cli.dump.subprocess.run", return_value=git_result): + date = dump._get_git_commit_date(repo_dir) + + assert date == "2026-06-17" + + +def test_get_git_commit_date_empty_when_git_fails(tmp_path): + """Docker image / pip wheel: no git → '' so the dump line drops the date.""" + from hermes_cli import dump + + repo_dir = tmp_path / "no-git-here" + repo_dir.mkdir() + + failed = MagicMock(returncode=128, stdout="") + with patch("hermes_cli.dump.subprocess.run", return_value=failed): + date = dump._get_git_commit_date(repo_dir) + + assert date == "" + + +def test_get_git_commit_date_empty_when_git_raises(tmp_path): + """git binary missing → '' (no crash, suffix simply omitted).""" + from hermes_cli import dump + + repo_dir = tmp_path / "repo" + repo_dir.mkdir() + + with patch("hermes_cli.dump.subprocess.run", side_effect=FileNotFoundError("git")): + date = dump._get_git_commit_date(repo_dir) + + assert date == ""