zozo123 commented on code in PR #73182:
URL: https://github.com/apache/airflow/pull/73182#discussion_r4075151881


##########
scripts/ci/prek_cache_markers.py:
##########
@@ -0,0 +1,56 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+"""Snapshot prek installation metadata used to detect cache repairs."""
+
+from __future__ import annotations
+
+import base64
+import json
+import sys
+from pathlib import Path
+
+MARKERS = (("hooks", ".prek-hook.json"), ("repos", ".prek-repo.json"))
+
+
+def snapshot_markers(cache_dir: Path) -> dict[str, str]:
+    """Return shallow marker paths and their byte-for-byte contents."""
+    snapshot = {}
+    for directory, marker_name in MARKERS:
+        parent = cache_dir / directory
+        try:
+            entries = sorted(parent.iterdir())
+        except FileNotFoundError:
+            continue
+        for entry in entries:
+            marker = entry / marker_name
+            try:
+                contents = marker.read_bytes()
+            except FileNotFoundError:
+                continue
+            relative_path = marker.relative_to(cache_dir).as_posix()
+            snapshot[relative_path] = base64.b64encode(contents).decode()
+    return snapshot

Review Comment:
   Fixed in baa0bd3 — it now fails closed. `prek_cache_markers.py` exits 
non-zero when the cache directory has content but yields no recognised markers, 
and the install-hooks step already routes a snapshot failure to 
`change-detection-uncertain=true`, which `cache-policy` turns into `save=true, 
reason=change-detection-uncertain`. A future prek that renames its marker files 
gets one republish per key instead of a silent detection shutdown.
   
   Test-wise: `test_restored_hooks_are_always_validated` no longer pins the 
fail-open (it now runs against a cache that actually contains a marker), and a 
new `test_markerless_cache_refresh_policy` matrix covers 
missing/empty/renamed-marker caches end-to-end through both steps — in the 
default CI-run suite, not behind `RUN_PREK_INTEGRATION`. I also ran the gated 
integration test against real prek locally: it passes.
   
   On the smaller points: the unreachable `installation-failed` branch is gone 
from `cache-policy` (with its env var and test case), and 
`test_hook_install_failure_remains_fatal` now asserts the invariant that made 
it unreachable — no `continue-on-error` on install-hooks and no `if` on 
cache-policy — so it stays unreachable on purpose. The marker-equality-as-proxy 
caveat stands: a repair that leaves markers byte-identical would still read as 
unchanged; on 0.5.2 rebuilds rewrite the marker, and the uncertain path now 
catches the layout-change case, so I've left that as the residual risk.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to