MCPcopy Create free account
hub / github.com/MaterializeInc/materialize / fingerprint

Method fingerprint

misc/python/materialize/mzbuild.py:1283–1340  ·  view source on GitHub ↗

Fingerprint the inputs to the image. Compute the fingerprint of the image. Changing the contents of any of the files or adding or removing files to the image will change the fingerprint, as will modifying the inputs to any of its dependencies. The image considers al

(self)

Source from the content-addressed store, hash-verified

1281
1282 @cache
1283 def fingerprint(self) -> Fingerprint:
1284 """Fingerprint the inputs to the image.
1285
1286 Compute the fingerprint of the image. Changing the contents of any of
1287 the files or adding or removing files to the image will change the
1288 fingerprint, as will modifying the inputs to any of its dependencies.
1289
1290 The image considers all non-gitignored files in its mzbuild context to
1291 be inputs. If it has a pre-image action, that action may add additional
1292 inputs via `PreImage.inputs`.
1293 """
1294 self_hash = hashlib.sha1()
1295 # When inputs come from precomputed sources (crate and image context
1296 # batching + resolved CargoPreImage paths), they are already individual
1297 # file paths from git. Skip the expensive expand_globs subprocess calls.
1298 inputs = self.inputs()
1299 if self.image._context_files_cache is not None:
1300 resolved_inputs = sorted(inputs)
1301 else:
1302 resolved_inputs = sorted(set(git.expand_globs(self.image.rd.root, *inputs)))
1303 for rel_path in resolved_inputs:
1304 abs_path = self.image.rd.root / rel_path
1305 file_hash = hashlib.sha1()
1306 raw_file_mode = os.lstat(abs_path).st_mode
1307 # Compute a simplified file mode using the same rules as Git.
1308 # https://github.com/git/git/blob/3bab5d562/Documentation/git-fast-import.txt#L610-L616
1309 if stat.S_ISLNK(raw_file_mode):
1310 file_mode = 0o120000
1311 elif raw_file_mode & stat.S_IXUSR:
1312 file_mode = 0o100755
1313 else:
1314 file_mode = 0o100644
1315 with open(abs_path, "rb") as f:
1316 file_hash.update(f.read())
1317 self_hash.update(file_mode.to_bytes(2, byteorder="big"))
1318 self_hash.update(rel_path.encode())
1319 self_hash.update(file_hash.digest())
1320 self_hash.update(b"\0")
1321
1322 for pre_image in self.image.pre_images:
1323 self_hash.update(pre_image.extra().encode())
1324 self_hash.update(b"\0")
1325
1326 self_hash.update(f"profile={self.image.rd.profile}".encode())
1327 self_hash.update(f"arch={self.image.rd.arch}".encode())
1328 self_hash.update(f"coverage={self.image.rd.coverage}".encode())
1329 self_hash.update(f"sanitizer={self.image.rd.sanitizer}".encode())
1330 # This exists to make sure all hashes from before we had a GHCR mirror are invalidated, so that we rebuild when an image doesn't exist on GHCR yet
1331 self_hash.update(b"mirror=ghcr")
1332
1333 full_hash = hashlib.sha1()
1334 full_hash.update(self_hash.digest())
1335 for dep in sorted(self.dependencies.values(), key=lambda d: d.name):
1336 full_hash.update(dep.name.encode())
1337 full_hash.update(dep.fingerprint())
1338 full_hash.update(b"\0")
1339
1340 return Fingerprint(full_hash.digest())

Callers 2

specMethod · 0.95
mainFunction · 0.45

Calls 9

inputsMethod · 0.95
FingerprintClass · 0.70
setFunction · 0.50
updateMethod · 0.45
readMethod · 0.45
to_bytesMethod · 0.45
encodeMethod · 0.45
extraMethod · 0.45
valuesMethod · 0.45

Tested by

no test coverage detected