From d33fee54fa513744f6549d4d44001a8d6613d9a7 Mon Sep 17 00:00:00 2001 From: Austin Seipp Date: Wed, 3 Jul 2024 21:29:36 -0500 Subject: [PATCH] tools: add a script for checking workspace dependencies buck run -v0 tools/scripts:unused_workspace_deps Signed-off-by: Austin Seipp --- tools/scripts/BUILD | 6 +++ tools/scripts/unused_workspace_deps.py | 60 ++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 tools/scripts/BUILD create mode 100644 tools/scripts/unused_workspace_deps.py diff --git a/tools/scripts/BUILD b/tools/scripts/BUILD new file mode 100644 index 000000000..c1c448c14 --- /dev/null +++ b/tools/scripts/BUILD @@ -0,0 +1,6 @@ + +python_bootstrap_binary( + name = 'unused_workspace_deps', + main = 'unused_workspace_deps.py', + visibility = [], +) diff --git a/tools/scripts/unused_workspace_deps.py b/tools/scripts/unused_workspace_deps.py new file mode 100644 index 000000000..04b115363 --- /dev/null +++ b/tools/scripts/unused_workspace_deps.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 + +# tools like cargo-udeps will only check if the dependencies listed in a +# crate's Cargo.toml file are actually used; it doesn't cross reference the +# workspace cargo file to find unused workspace deps. this script will do that + +import tomllib + +CRATE_TOML_FILES = [ + 'cli/Cargo.toml', + 'lib/Cargo.toml', + 'lib/proc-macros/Cargo.toml', + 'lib/gen-protos/Cargo.toml', + 'lib/testutils/Cargo.toml', +] + +def check_unused_deps(): + all_deps = None + with open("Cargo.toml", "rb") as f: + dat = tomllib.load(f) + all_deps = dat["workspace"]["dependencies"] + + total_deps = len(all_deps) + print(f"Found {total_deps} top-level dependencies in workspace Cargo.toml") + + # now, iterate over all the crate.toml files and check for unused dependencies + # by deleting entries from all_deps, if they exist + deleted_deps = 0 + for crate_toml in CRATE_TOML_FILES: + with open(crate_toml, "rb") as f: + dat = tomllib.load(f) + deps = dat["dependencies"] + + if "build-dependencies" in dat: + for x, v in dat["build-dependencies"].items(): + deps[x] = v + + if "dev-dependencies" in dat: + for x, v in dat["dev-dependencies"].items(): + deps[x] = v + + if "target" in dat: + for target in dat["target"]: + if target.startswith("cfg("): + for x, v in dat["target"][target]["dependencies"].items(): + deps[x] = v + + for x in deps.keys(): + if x in all_deps: + del all_deps[x] + deleted_deps += 1 + + print(f'Found {deleted_deps} unique dependencies among {len(CRATE_TOML_FILES)} Cargo.toml files') + if len(all_deps) > 0: + print(f"Found {len(all_deps)} unused dependencies:") + for x in all_deps.keys(): + print(f" {x}") + +if __name__ == '__main__': + check_unused_deps()