mirror of
https://github.com/MadsLorentzen/ai-job-search.git
synced 2026-09-17 00:26:26 +00:00
fix(upstream-checker): report files missing from the upstream ref instead of silent OK (#282)
The per-file 'git show' failure was swallowed with a bare continue, so a file renamed or deleted upstream (or any unexpected git error) ended with a clean '[OK] All framework files are up to date' - a false all-clear. Now the two failure modes are distinguished: files present locally but missing from the upstream ref are listed explicitly with a final [WARNING] instead of [OK], and unexpected git errors are added to the configuration errors with their stderr. Adds UpstreamRefMissingFileTests, which simulates upstream dropping AGENTS.md while the fork keeps its copy: it fails on master and passes with the fix.
This commit is contained in:
@@ -131,5 +131,33 @@ class UpstreamRemotePresentTests(UpstreamCheckerRepoFixture):
|
|||||||
self.assertIn("up to date with upstream/master", result.stdout)
|
self.assertIn("up to date with upstream/master", result.stdout)
|
||||||
|
|
||||||
|
|
||||||
|
class UpstreamRefMissingFileTests(UpstreamCheckerRepoFixture):
|
||||||
|
"""Simulates upstream renaming/deleting one framework file while the
|
||||||
|
fork still has its own copy: git show then fails, and the checker used
|
||||||
|
to swallow the error and report a clean '[OK]'."""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super().setUp()
|
||||||
|
self.add_remote("origin", FORK_URL)
|
||||||
|
self.add_remote("upstream", TEMPLATE_URL)
|
||||||
|
|
||||||
|
# Upstream drops AGENTS.md (rename/delete) in a new commit.
|
||||||
|
subprocess.run(["git", "rm", "-q", "AGENTS.md"], cwd=self.root, check=True, capture_output=True)
|
||||||
|
subprocess.run(["git", "commit", "-qm", "drop AGENTS.md"], cwd=self.root, check=True, capture_output=True)
|
||||||
|
self.materialize_remote_ref("upstream")
|
||||||
|
|
||||||
|
# The fork keeps its own copy locally, so only the upstream side
|
||||||
|
# lacks the file.
|
||||||
|
(self.root / "AGENTS.md").write_text(FRONTMATTER, encoding="utf-8")
|
||||||
|
|
||||||
|
def test_file_missing_upstream_is_reported_instead_of_silent_ok(self):
|
||||||
|
result = self.run_checker()
|
||||||
|
|
||||||
|
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
|
||||||
|
self.assertIn("AGENTS.md", result.stdout)
|
||||||
|
self.assertNotIn("[OK] All framework files are up to date", result.stdout)
|
||||||
|
self.assertIn("[WARNING]", result.stdout)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ def main() -> int:
|
|||||||
|
|
||||||
updates_available = []
|
updates_available = []
|
||||||
errors = []
|
errors = []
|
||||||
|
missing_upstream = []
|
||||||
|
|
||||||
for rel_path in FRAMEWORK_FILES:
|
for rel_path in FRAMEWORK_FILES:
|
||||||
local_path = ROOT / rel_path
|
local_path = ROOT / rel_path
|
||||||
@@ -125,9 +126,16 @@ def main() -> int:
|
|||||||
local_ver = get_framework_version_from_text(local_text)
|
local_ver = get_framework_version_from_text(local_text)
|
||||||
|
|
||||||
# Get upstream version
|
# Get upstream version
|
||||||
rc, upstream_text, _ = run_git(["show", f"{ref}:{rel_path}"])
|
rc, upstream_text, git_err = run_git(["show", f"{ref}:{rel_path}"])
|
||||||
if rc != 0:
|
if rc != 0:
|
||||||
# File might not exist upstream yet
|
# A file present locally but missing from the upstream ref means
|
||||||
|
# it was renamed or deleted upstream; any other git failure means
|
||||||
|
# the comparison is incomplete. Either way, never report a clean
|
||||||
|
# '[OK]' while silently skipping the file.
|
||||||
|
if "does not exist" in git_err or "exists on disk, but not in" in git_err:
|
||||||
|
missing_upstream.append(rel_path)
|
||||||
|
else:
|
||||||
|
errors.append(f"Failed to read upstream version of {rel_path}: {git_err.strip()}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
upstream_ver = get_framework_version_from_text(upstream_text)
|
upstream_ver = get_framework_version_from_text(upstream_text)
|
||||||
@@ -153,6 +161,12 @@ def main() -> int:
|
|||||||
print(f" - {err}")
|
print(f" - {err}")
|
||||||
print()
|
print()
|
||||||
|
|
||||||
|
if missing_upstream:
|
||||||
|
print("Files present locally but missing from the upstream ref (possibly renamed or deleted upstream):")
|
||||||
|
for path in missing_upstream:
|
||||||
|
print(f" - {path}")
|
||||||
|
print()
|
||||||
|
|
||||||
if updates_available:
|
if updates_available:
|
||||||
print("[UPDATE] Upstream updates available for framework methodology files:")
|
print("[UPDATE] Upstream updates available for framework methodology files:")
|
||||||
for up in updates_available:
|
for up in updates_available:
|
||||||
@@ -161,6 +175,13 @@ def main() -> int:
|
|||||||
print()
|
print()
|
||||||
print("Review these changes to see if they fit your personalized fork!")
|
print("Review these changes to see if they fit your personalized fork!")
|
||||||
return 0
|
return 0
|
||||||
|
else:
|
||||||
|
if errors or missing_upstream:
|
||||||
|
print(
|
||||||
|
f"[WARNING] Framework check incomplete against {ref}: "
|
||||||
|
f"{len(errors)} configuration error(s), {len(missing_upstream)} file(s) missing upstream. "
|
||||||
|
"Review the messages above before assuming you are up to date."
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
print(f"[OK] All framework files are up to date with {ref}!")
|
print(f"[OK] All framework files are up to date with {ref}!")
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
Reference in New Issue
Block a user