Redundant dependencies detection

Hi folks,

We heavily rely on SPM as a dependency manager in our team and overall, it's been working well for us.

However, we continue to face a persistent issue with it - the inability to automatically check for redundant dependencies that are retained within the target setup.

Let's dive right into the example and examine a simple Package.swift file:

import PackageDescription

let package = Package(
    name: "Portfolio",
    defaultLocalization: "en",
    platforms: [
        .iOS(.v14),
    ],
    products: [
        .library(
            name: "Portfolio",
            targets: ["Portfolio", "PortfolioAccounts", "PortfolioHeader", "PortfolioProducts"]),
    ],
    dependencies: [
        .package(url: "https://github.com/Swinject/Swinject.git", from: "2.8.0"),
        .package(url: "https://github.com/CombineCommunity/CombineCocoa.git", from: "0.2.1"),
        .package(url: "https://github.com/SnapKit/SnapKit.git", .upToNextMajor(from: "5.0.1")),
    ],
    targets: [
        .target(
            name: "Portfolio",
            dependencies: [
                "Swinject",
                "CombineCocoa",
                "SnapKit",
            ]
        ),
    ]
)

that containg a single file with the following content:

import Foundation // system framework, not required to be declared as target's dependency
import CombineCocoa // external dependency, should be declared as target's dependency

// import SnapKit // toggled of extenal dependency

The above project would compile and function properly without throwing any errors or warnings regarding redundant dependencies being passed in the target.

One might argue that it is possible to manually check each dependency in the list by toggling them and verifying if the project would build successfully. However, I would object to this claim by stating that using SPM for this task is fragile and unstable.

There are situations where the project would not build successfully even if a necessary target's dependency is missing[1]. Moreover, the lack of continuous integration (CI) exacerbates the issue further.

In order to address the issue of redundant dependencies in a target's source imports more reliably, we are contemplating the implementation of a tool for this purpose. Our plan involves utilizing the swift-syntax library as a fundamental component of this tool.

Before we proceed, we would like to ask if anyone knows whether such a tool already exists.


  1. If it's declared in package dependencies list AND imported in some another target AND was deleted after first cold build (i.e. cached). ↩︎