diff --git a/src/specify_cli/integrations/catalog.py b/src/specify_cli/integrations/catalog.py index 1794caad83..c90d6eca4d 100644 --- a/src/specify_cli/integrations/catalog.py +++ b/src/specify_cli/integrations/catalog.py @@ -841,5 +841,8 @@ def tools(self) -> List[Dict[str, Any]]: def get_hash(self) -> str: """SHA-256 hash of the descriptor file.""" + h = hashlib.sha256() with open(self.path, "rb") as fh: - return f"sha256:{hashlib.sha256(fh.read()).hexdigest()}" + for chunk in iter(lambda: fh.read(8192), b""): + h.update(chunk) + return f"sha256:{h.hexdigest()}" diff --git a/src/specify_cli/presets/__init__.py b/src/specify_cli/presets/__init__.py index e2f6c089a4..ee053ea08d 100644 --- a/src/specify_cli/presets/__init__.py +++ b/src/specify_cli/presets/__init__.py @@ -452,8 +452,11 @@ def tags(self) -> List[str]: def get_hash(self) -> str: """Calculate SHA256 hash of manifest file.""" + h = hashlib.sha256() with open(self.path, 'rb') as f: - return f"sha256:{hashlib.sha256(f.read()).hexdigest()}" + for chunk in iter(lambda: f.read(8192), b""): + h.update(chunk) + return f"sha256:{h.hexdigest()}" class PresetRegistry: diff --git a/tests/integrations/test_integration_catalog.py b/tests/integrations/test_integration_catalog.py index 4688c6a21e..c5ac6e34ae 100644 --- a/tests/integrations/test_integration_catalog.py +++ b/tests/integrations/test_integration_catalog.py @@ -642,6 +642,10 @@ def test_get_hash(self, tmp_path): desc = IntegrationDescriptor(p) h = desc.get_hash() assert h.startswith("sha256:") + import hashlib + content = p.read_bytes() + expected = f"sha256:{hashlib.sha256(content).hexdigest()}" + assert h == expected def test_tools_accessor(self, tmp_path): data = {**VALID_DESCRIPTOR, "requires": { diff --git a/tests/test_presets.py b/tests/test_presets.py index f4813eae13..993e968f31 100644 --- a/tests/test_presets.py +++ b/tests/test_presets.py @@ -337,7 +337,10 @@ def test_get_hash(self, pack_dir): manifest = PresetManifest(pack_dir / "preset.yml") hash_val = manifest.get_hash() assert hash_val.startswith("sha256:") - assert len(hash_val) > 10 + import hashlib + content = (pack_dir / "preset.yml").read_bytes() + expected = f"sha256:{hashlib.sha256(content).hexdigest()}" + assert hash_val == expected def test_multiple_templates(self, temp_dir, valid_pack_data): """Test pack with multiple templates of different types."""