feat(artifacts): add immutable artifact store

This commit is contained in:
2026-08-25 18:06:33 +03:00
parent 182bde8ac0
commit 497e1b740f
13 changed files with 2198 additions and 3 deletions
+21 -3
View File
@@ -53,6 +53,8 @@ def package_category(name: str, manifest_path: Path, workspace_root: Path) -> st
return "metrics"
if name == "crank-config":
return "config"
if name == "crank-artifacts":
return "artifacts"
if name == "crank-observability":
return "observability"
if name == "crank-registry":
@@ -86,13 +88,22 @@ def workspace_packages(metadata: dict[str, Any]) -> dict[str, Package]:
return packages
def dependency_package_ids(raw_package: dict[str, Any], packages_by_name: dict[str, str]) -> list[str]:
def dependency_package_ids(
raw_package: dict[str, Any],
packages_by_name: dict[str, str],
*,
skip_dev: bool = False,
) -> list[str]:
dependency_ids: list[str] = []
seen: set[str] = set()
for dependency in raw_package.get("dependencies", []):
if skip_dev and dependency.get("kind") == "dev":
continue
dependency_name = dependency["name"]
dependency_id = packages_by_name.get(dependency_name)
if dependency_id is not None:
if dependency_id is not None and dependency_id not in seen:
dependency_ids.append(dependency_id)
seen.add(dependency_id)
return dependency_ids
@@ -128,6 +139,9 @@ def boundary_reason(source: Package, dependency: Package) -> str | None:
if source.category == "config":
return "crank-config must not depend on other workspace crates"
if source.category == "artifacts":
return "crank-artifacts must not depend on other workspace crates"
if source.category == "observability" and dependency.category != "metrics":
return "crank-observability must not depend on other workspace crates"
@@ -161,7 +175,11 @@ def find_violations(metadata: dict[str, Any]) -> list[Violation]:
for source in sorted(packages.values(), key=lambda package: package.name):
raw_package = raw_packages_by_id[source.id]
violations.extend(direct_dependency_violations(raw_package))
for dependency_id in dependency_package_ids(raw_package, packages_by_name):
for dependency_id in dependency_package_ids(
raw_package,
packages_by_name,
skip_dev=source.category == "artifacts",
):
dependency = packages[dependency_id]
reason = boundary_reason(source, dependency)
if reason is not None: