🚧 Add file time information in commit message
This commit is contained in:
@@ -19,21 +19,30 @@ _SUMMARY_LABELS = (
|
|||||||
|
|
||||||
|
|
||||||
def _format_ts(moment: dt.datetime | None) -> str:
|
def _format_ts(moment: dt.datetime | None) -> str:
|
||||||
|
"""Render an aware datetime in local time with an explicit offset.
|
||||||
|
|
||||||
|
Local wall-clock time plus the UTC offset, e.g. 2026-09-12 08:00:00+02:00
|
||||||
|
(matching the log timestamp style in logging/setup.py, which also uses
|
||||||
|
local time rather than UTC).
|
||||||
|
"""
|
||||||
if moment is None:
|
if moment is None:
|
||||||
return ""
|
return ""
|
||||||
return moment.strftime("%Y-%m-%d %H:%M:%S%z")
|
return moment.astimezone().isoformat(sep=" ", timespec="seconds")
|
||||||
|
|
||||||
|
|
||||||
def _author_lines(record) -> list[str]: # noqa: ANN001 - ChangeRecord, avoid cycle
|
def _author_lines(record) -> list[str]: # noqa: ANN001 - ChangeRecord, avoid cycle
|
||||||
lines: list[str] = []
|
lines: list[str] = []
|
||||||
author = record.author
|
author = record.author
|
||||||
if author is not None:
|
identifier = author.identifier if author is not None else "UNKNOWN"
|
||||||
lines.append(f" Last modified by: {author.identifier}")
|
lines.append(f" Last modified by: {identifier}")
|
||||||
ts = _format_ts(author.timestamp)
|
# Filesystem last-modified time (Section 12: file_timestamp); rendered
|
||||||
if ts:
|
# in local time like the log timestamps. Resolver-provided timestamps
|
||||||
lines.append(f" Modified at: {ts}")
|
# (author.timestamp) stay authoritative and are shown as well.
|
||||||
else:
|
file_ts = _format_ts(record.file_timestamp)
|
||||||
lines.append(" Last modified by: UNKNOWN")
|
if file_ts:
|
||||||
|
lines.append(f" Modified at: {file_ts}")
|
||||||
|
if author is not None and author.timestamp is not None:
|
||||||
|
lines.append(f" Changed at: {_format_ts(author.timestamp)}")
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -102,6 +102,22 @@ class TestRunCycle:
|
|||||||
body = _git_out("log", "-1", "--format=%b", cwd=git_repo)
|
body = _git_out("log", "-1", "--format=%b", cwd=git_repo)
|
||||||
assert "Last modified by: DOMAIN\\jsmith" in body
|
assert "Last modified by: DOMAIN\\jsmith" in body
|
||||||
|
|
||||||
|
def test_file_mtime_appears_in_commit_local_time(
|
||||||
|
self, git_repo: Path, tracker_config: dict, tmp_path: Path
|
||||||
|
) -> None:
|
||||||
|
"""Section 12 file_timestamp rendered as 'Modified at' (local time)."""
|
||||||
|
import re as re_mod
|
||||||
|
|
||||||
|
(git_repo / "config.xml").write_text("<c/>", encoding="utf-8")
|
||||||
|
_run(tracker_config, tmp_path)
|
||||||
|
body = _git_out("log", "-1", "--format=%b", cwd=git_repo)
|
||||||
|
# Local-time format with explicit +/-HH:MM offset (Section 15)
|
||||||
|
assert re_mod.search(
|
||||||
|
r"Modified at: \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}[+-]\d{2}:\d{2}\b", body
|
||||||
|
)
|
||||||
|
# The timestamp block sits directly under the changed file entry
|
||||||
|
assert " config.xml\n Last modified by: UNKNOWN\n Modified at:" in body
|
||||||
|
|
||||||
def test_excluded_files_not_committed(
|
def test_excluded_files_not_committed(
|
||||||
self, git_repo: Path, tracker_config: dict, tmp_path: Path
|
self, git_repo: Path, tracker_config: dict, tmp_path: Path
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import datetime as dt
|
import datetime as dt
|
||||||
|
import re
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
@@ -152,6 +153,7 @@ class TestCommitMessage:
|
|||||||
ChangeRecord(
|
ChangeRecord(
|
||||||
path="Stations/PS101/project.xml",
|
path="Stations/PS101/project.xml",
|
||||||
change_type=ChangeType.MODIFIED,
|
change_type=ChangeType.MODIFIED,
|
||||||
|
file_timestamp=dt.datetime(2026, 9, 11, 6, 42, 9, tzinfo=dt.UTC),
|
||||||
author=AuthorIdentity(
|
author=AuthorIdentity(
|
||||||
identifier="DOMAIN\\jsmith",
|
identifier="DOMAIN\\jsmith",
|
||||||
source="scada_audit_log",
|
source="scada_audit_log",
|
||||||
@@ -175,6 +177,13 @@ class TestCommitMessage:
|
|||||||
assert "Added: 1" in message
|
assert "Added: 1" in message
|
||||||
assert "Last modified by: DOMAIN\\jsmith" in message
|
assert "Last modified by: DOMAIN\\jsmith" in message
|
||||||
assert "Last modified by: UNKNOWN" in message
|
assert "Last modified by: UNKNOWN" in message
|
||||||
|
# Filesystem mtime rendered as 'Modified at' in local time with offset
|
||||||
|
assert " Modified at: " in message
|
||||||
|
assert re.search(
|
||||||
|
r"Modified at: \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}[+-]\d{2}:\d{2}\b", message
|
||||||
|
)
|
||||||
|
# Resolver-provided timestamp kept as a separate 'Changed at' line
|
||||||
|
assert " Changed at: " in message
|
||||||
assert "Stations/PS027/old.xml" in message
|
assert "Stations/PS027/old.xml" in message
|
||||||
# Trailers last (Section 36)
|
# Trailers last (Section 36)
|
||||||
assert "Tracker-Version: 1.0.0" in message
|
assert "Tracker-Version: 1.0.0" in message
|
||||||
|
|||||||
Reference in New Issue
Block a user