mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
fix(backup): handle files with pre-1980 timestamps
ZipFile.write() raises ValueError for files with mtime before 1980-01-01 (the ZIP format uses MS-DOS timestamps which can't represent earlier dates). This crashes the entire backup. Add ValueError to the existing except clause so these files are skipped and reported in the warnings summary, matching the existing behavior for PermissionError and OSError.
This commit is contained in:
parent
afba54364e
commit
12c8cefbce
2 changed files with 29 additions and 1 deletions
|
|
@ -201,7 +201,7 @@ def run_backup(args) -> None:
|
||||||
else:
|
else:
|
||||||
zf.write(abs_path, arcname=str(rel_path))
|
zf.write(abs_path, arcname=str(rel_path))
|
||||||
total_bytes += abs_path.stat().st_size
|
total_bytes += abs_path.stat().st_size
|
||||||
except (PermissionError, OSError) as exc:
|
except (PermissionError, OSError, ValueError) as exc:
|
||||||
errors.append(f" {rel_path}: {exc}")
|
errors.append(f" {rel_path}: {exc}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -702,6 +702,34 @@ class TestBackupEdgeCases:
|
||||||
# Zip should still be created with the readable files
|
# Zip should still be created with the readable files
|
||||||
assert out_zip.exists()
|
assert out_zip.exists()
|
||||||
|
|
||||||
|
def test_pre1980_timestamp_skipped(self, tmp_path, monkeypatch):
|
||||||
|
"""Backup skips files with pre-1980 timestamps (ZIP limitation)."""
|
||||||
|
hermes_home = tmp_path / ".hermes"
|
||||||
|
hermes_home.mkdir()
|
||||||
|
(hermes_home / "config.yaml").write_text("model: test\n")
|
||||||
|
|
||||||
|
# Create a file with epoch timestamp (1970-01-01)
|
||||||
|
old_file = hermes_home / "ancient.txt"
|
||||||
|
old_file.write_text("old data")
|
||||||
|
os.utime(old_file, (0, 0))
|
||||||
|
|
||||||
|
monkeypatch.setenv("HERMES_HOME", str(hermes_home))
|
||||||
|
monkeypatch.setattr(Path, "home", lambda: tmp_path)
|
||||||
|
|
||||||
|
out_zip = tmp_path / "out.zip"
|
||||||
|
args = Namespace(output=str(out_zip))
|
||||||
|
|
||||||
|
from hermes_cli.backup import run_backup
|
||||||
|
run_backup(args)
|
||||||
|
|
||||||
|
# Zip should still be created with the valid files
|
||||||
|
assert out_zip.exists()
|
||||||
|
with zipfile.ZipFile(out_zip, "r") as zf:
|
||||||
|
names = zf.namelist()
|
||||||
|
assert "config.yaml" in names
|
||||||
|
# The pre-1980 file should be skipped, not crash the backup
|
||||||
|
assert "ancient.txt" not in names
|
||||||
|
|
||||||
def test_skips_output_zip_inside_hermes(self, tmp_path, monkeypatch):
|
def test_skips_output_zip_inside_hermes(self, tmp_path, monkeypatch):
|
||||||
"""Backup skips its own output zip if it's inside hermes root."""
|
"""Backup skips its own output zip if it's inside hermes root."""
|
||||||
hermes_home = tmp_path / ".hermes"
|
hermes_home = tmp_path / ".hermes"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue