← All work

Open source · Bazel

swift_unused_deps

A Bazel check for unused and missing direct dependencies in Swift targets, with generated fixes.

swift_unused_deps

$ bazel test --config=swift-unused-deps //tools:swift_unused_deps

swift_unused_deps v0.1.0

Analyzing 2 targets...

//cases/Targets/UnusedImport:UnusedImport

Status: 1 issue found

[HIGH] UNUSED_IMPORT: //cases/Deps/LibA:LibA (module: LibA)

//cases/Targets/MissingDirectDep:MissingDirectDep

Status: 1 issue found

[HIGH] MISSING_DIRECT_DEP: //cases/Deps/TransitiveDep:TransitiveDep (module: TransitiveDep)

Summary: 2 targets analyzed, 2 issues found.

$ bazel run --config=swift-unused-deps //tools:swift_unused_deps_fix

Planned fixes:

remove //cases/Deps/LibA:LibA from deps of //cases/Targets/UnusedImport:UnusedImport

remove import LibA from cases/Targets/UnusedImport/UnusedImport.swift

add //cases/Deps/TransitiveDep:TransitiveDep to deps of //cases/Targets/MissingDirectDep:MissingDirectDep

$ bazel test --config=swift-unused-deps //tools:swift_unused_deps

Summary: 2 targets analyzed, 0 issues found.

//tools:swift_unused_deps PASSED

The check finds two dependency issues, applies the generated fixes, then passes on the next run.

A dependency check that runs with the rest of your tests

swift_unused_deps runs as a regular bazel test. It reads SwiftInfo and the index store to catch mistakes in the analyzed graph, so the same check works locally and in CI. When a fix is safe to automate, the generated fix target updates the BUILD or source file. Run the test again to verify the graph is clean.

What it catches

  • Unused dependencyListed in BUILD, but never loaded.
  • Unused importPresent in the source, but no symbols are used.
  • Missing direct dependencyUsed by the target, but only available through another dependency.
  • Private dependency candidateUsed internally and not exposed through the public API.
Type
Build tool
Focus
Dependency hygiene
Stack
Swift · Starlark