| # /// script | |
| # requires-python = ">=3.12" | |
| # dependencies = [] | |
| # | |
| # [tool.ty.analysis] | |
| # return-type-inference = "always" | |
| # | |
| # [tool.ty.rules] | |
| # truthiness-test-of-none-union = "warn" | |
| # blanket-ignore-comment = "warn" | |
| # missing-type-argument = "warn" | |
| # possibly-unresolved-reference = "warn" | |
| # unsound-return-statement = "warn" | |
| # unsound-yield = "warn" | |
| # unsupported-dynamic-base = "warn" | |
| # division-by-zero = "warn" | |
| # dynamic-function-decorator-return = "warn" | |
| # unsound-assignment = "warn" | |
| # redundant-condition-strict = "warn" | |
| # disjoint-cast = "warn" | |
| # missing-direct-dependency = "warn" | |
| # | |
| # [tool.uv] | |
| # no-build = true | |
| # exclude-newer = "P7D" | |
| # require-build-hashes = true | |
| # preview-features = ["build-dependency-hashes", "missing-exclude-newer-package-lock"] | |
| # /// | |
| """Supplement cargo-deny bans with workspace dependency policy checks.""" | |
| from __future__ import annotations | |
| import json | |
| import subprocess | |
| import sys | |
| import tomllib | |
| from pathlib import Path | |
| from typing import Any | |
| ROOT = Path(__file__).resolve().parent.parent | |
| def inspect( | |
| metadata: dict[str, Any], workspace_dependencies: dict[str, Any] | |
| ) -> list[str]: | |
| """Return errors for workspace requests for external default features.""" | |
| root = Path(metadata["workspace_root"]).resolve() | |
| member_ids = set(metadata["workspace_members"]) | |
| members = [ | |
| package for package in metadata["packages"] if package["id"] in member_ids | |
| ] | |
| member_paths = { | |
| Path(package["manifest_path"]).resolve().parent for package in members | |
| } | |
| errors: set[str] = set() | |
| def is_external(path: str | None) -> bool: | |
| return path is None or (root / path).resolve() not in member_paths | |
| # Metadata omits unused workspace dependency definitions. | |
| for name, specification in workspace_dependencies.items(): | |
| dependency = {} if isinstance(specification, str) else specification | |
| if is_external(dependency.get("path")) and ( | |
| dependency.get("default-features", True) | |
| or "default" in dependency.get("features", []) | |
| ): | |
| errors.add( | |
| f"Cargo.toml: workspace.dependencies.{name} requests default features" | |
| ) | |
| for package in members: | |
| manifest = Path(package["manifest_path"]).resolve() | |
| location = ( | |
| manifest.relative_to(root) if manifest.is_relative_to(root) else manifest | |
| ) | |
| external_aliases = set() | |
| # Cargo has already applied workspace inheritance and target-specific rules. | |
| for dependency in package["dependencies"]: | |
| if not is_external(dependency.get("path")): | |
| continue | |
| alias = dependency.get("rename") or dependency["name"] | |
| external_aliases.add(alias) | |
| if ( | |
| dependency["uses_default_features"] | |
| or "default" in dependency["features"] | |
| ): | |
| errors.add( | |
| f"{location}: dependency {alias!r} requests default features" | |
| ) | |
| for feature, activations in package["features"].items(): | |
| for activation in activations: | |
| alias, separator, target = activation.partition("/") | |
| if ( | |
| separator | |
| and target == "default" | |
| and alias.removesuffix("?") in external_aliases | |
| ): | |
| errors.add( | |
| f"{location}: features.{feature} requests {activation!r}" | |
| ) | |
| return sorted(errors) | |
| def inspect_build_scripts( | |
| metadata: dict[str, Any], allow_build_scripts: list[str] | |
| ) -> list[str]: | |
| """Return errors for stale entries in the external build-script allowlist.""" | |
| member_ids = set(metadata["workspace_members"]) | |
| build_script_crates = { | |
| package["name"] | |
| for package in metadata["packages"] | |
| if package["id"] not in member_ids | |
| and any("custom-build" in target["kind"] for target in package["targets"]) | |
| } | |
| return [ | |
| f".cargo/deny.toml: bans.build.allow-build-scripts entry {name!r} " | |
| "does not match any dependency with a build script" | |
| for name in sorted(set(allow_build_scripts) - build_script_crates) | |
| ] | |
| def main() -> int: | |
| command = [ | |
| "cargo", | |
| "metadata", | |
| "--locked", | |
| "--offline", | |
| "--all-features", | |
| "--format-version", | |
| "1", | |
| ] | |
| try: | |
| raw_metadata = subprocess.check_output(command, cwd=ROOT, text=True) | |
| except subprocess.CalledProcessError as error: | |
| return error.returncode | |
| metadata = json.loads(raw_metadata) | |
| root = Path(metadata["workspace_root"]) | |
| with (root / "Cargo.toml").open("rb") as manifest: | |
| workspace_dependencies = ( | |
| tomllib.load(manifest).get("workspace", {}).get("dependencies", {}) | |
| ) | |
| with (root / ".cargo" / "deny.toml").open("rb") as config: | |
| allow_build_scripts = tomllib.load(config)["bans"]["build"][ | |
| "allow-build-scripts" | |
| ] | |
| feature_errors = inspect(metadata, workspace_dependencies) | |
| for error in feature_errors: | |
| print(f"error: {error}", file=sys.stderr) | |
| if feature_errors: | |
| print( | |
| "Set default-features = false and request named features explicitly.", | |
| file=sys.stderr, | |
| ) | |
| build_script_errors = inspect_build_scripts(metadata, allow_build_scripts) | |
| for error in build_script_errors: | |
| print(f"error: {error}", file=sys.stderr) | |
| if build_script_errors: | |
| print( | |
| "Remove stale entries from bans.build.allow-build-scripts.", file=sys.stderr | |
| ) | |
| if feature_errors or build_script_errors: | |
| return 1 | |
| print("Workspace external dependencies request no default features.") | |
| print("The cargo-deny build-script allowlist has no stale entries.") | |
| return 0 | |
| if __name__ == "__main__": | |
| sys.exit(main()) |