Skip to content
Merged
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
8 changes: 8 additions & 0 deletions simpler_setup/runtime_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,16 @@ def _invalidate_cache_if_stale(target_cache_dir: Path, current_commit: str) -> N
cannot detect that source files changed. Comparing the HEAD commit stored
at last build time against the current HEAD is a reliable signal that
sources may have changed and a clean rebuild is needed.

When the current commit can't be determined (no git, transient failure),
fall through to a clean rebuild — a fresh compile is cheap relative to
the risk of linking against stale objects.
"""
if not current_commit:
if target_cache_dir.is_dir():
logger.info("git HEAD unavailable, clearing cmake cache: %s", target_cache_dir)
shutil.rmtree(target_cache_dir)
target_cache_dir.mkdir(parents=True, exist_ok=True)
return
commit_file = target_cache_dir / _GIT_COMMIT_FILE
if commit_file.is_file():
Expand Down
48 changes: 48 additions & 0 deletions tests/ut/py/test_runtime_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,54 @@ def test_propagates_compiler_error(self, MockCompiler, tmp_path, default_test_pl
builder.get_binaries("test_rt", build=True)


# --- _invalidate_cache_if_stale unit tests ---


class TestInvalidateCacheIfStale:
"""Test cmake cache invalidation behavior under varying git state."""

def test_clears_when_commit_mismatches(self, tmp_path):
from simpler_setup.runtime_builder import _GIT_COMMIT_FILE, _invalidate_cache_if_stale # noqa: PLC0415

cache_dir = tmp_path / "cache"
cache_dir.mkdir()
(cache_dir / _GIT_COMMIT_FILE).write_text("old_sha\n")
(cache_dir / "stale_artifact.o").write_text("stale")

_invalidate_cache_if_stale(cache_dir, "new_sha")

assert not (cache_dir / "stale_artifact.o").exists()
assert (cache_dir / _GIT_COMMIT_FILE).read_text().strip() == "new_sha"

def test_keeps_when_commit_matches(self, tmp_path):
from simpler_setup.runtime_builder import _GIT_COMMIT_FILE, _invalidate_cache_if_stale # noqa: PLC0415

cache_dir = tmp_path / "cache"
cache_dir.mkdir()
(cache_dir / _GIT_COMMIT_FILE).write_text("same_sha\n")
artifact = cache_dir / "kept_artifact.o"
artifact.write_text("fresh")

_invalidate_cache_if_stale(cache_dir, "same_sha")

assert artifact.exists()

def test_clears_when_commit_unavailable(self, tmp_path):
"""No discoverable git HEAD should force a clean rebuild, not silently skip."""
from simpler_setup.runtime_builder import _GIT_COMMIT_FILE, _invalidate_cache_if_stale # noqa: PLC0415

cache_dir = tmp_path / "cache"
cache_dir.mkdir()
(cache_dir / _GIT_COMMIT_FILE).write_text("old_sha\n")
(cache_dir / "stale_artifact.o").write_text("stale")

_invalidate_cache_if_stale(cache_dir, "")

assert not (cache_dir / "stale_artifact.o").exists()
assert not (cache_dir / _GIT_COMMIT_FILE).exists()
assert cache_dir.is_dir()


# --- Full integration tests (real compilation) ---


Expand Down
Loading