A simple command-line tool for analysing (local) dependencies between targets defined in Swift Package Manager projects, as well as catch any non-dependency import errors that can arise in larger target graphs.
Swift 5.5
Clone the repository and build with swift build
, and then use swift run TargetDependencyChecker <options>
:
$ swift run TargetDependencyChecker check --help
OVERVIEW:
Inspects a Swift Package Manager project and produce warnings about targets that include other targets that are not declared as dependencies in the Package.swift manifest.
USAGE: TargetDependencyChecker check [--package-path <package-path>] [--output-type <output-type>] [--warn-once-per-framework] [--warn-indirect-dependencies] [--no-color] [--print-full-paths] [--ignore-includes <ignore-includes>]
OPTIONS:
-p, --package-path <package-path>
Specifies the path for the directory containing a Package.swift manifest for a Swift Package Manager project.
If not specified, defaults to the current working directory.
-t, --output-type <output-type>
Specifies the format of the output.
Defaults to 'terminal' if not provided.
terminal
Prints output of conversion in a format proper for terminal's standard output.
xcode
Prints output with leading file/line numbers as warnings that Xcode can detect when used as a build phase.
-o, --warn-once-per-framework
When specified, omits warnings of violations for frameworks that where already reported in previous files in the same target.
-i, --warn-indirect-dependencies
When specified, warns when importing a target that is not a direct dependency into another target.
-c, --no-color When specified along with --output-type terminal, produces a non-colorized output in stdout.
-f, --print-full-paths When specified along with --output-type terminal, prints the full path of each file in the diagnostics.
--ignore-includes <ignore-includes>
Ignores all includes in the string separated by commas provided to this argument.
-h, --help Show help information.
There's a small test package included that can be used to test the program:
$ swift run TargetDependencyChecker check -iop ./TestPackage/
Will output:
Note that some of the arguments to TargetDependencyChecker
can overlap with arguments recognized by swift run
, in this case you can find the path of the built binary using swift build --show-bin-path
and execute TargetDependencyChecker
from there directly.
Graphviz files containing the dependency tree of a package can be generated using TargetDependencyChecker graph
:
$ swift run TargetDependencyChecker graph --help
OVERVIEW:
Produces a GraphViz .dot file describing the internal dependency graph of a Swift Package Manager project.
USAGE: TargetDependencyChecker graph [--package-path <package-path>] [--output <output>] [--include-indirect] [--include-tests] [--include-folder-hierarchy]
OPTIONS:
-p, --package-path <package-path>
Specifies the path for the directory containing a Package.swift manifest for a Swift Package Manager project.
If not specified, defaults to the current working directory.
-o, --output <output> A .dot file to write the results to, relative to the current working directory. If not provided, prints the result to stdout, instead.
-i, --include-indirect Include indirect dependencies via `import` statements on target's files.
-t, --include-tests Include test targets in the graph.
-f, --include-folder-hierarchy
Include information about the target's folder hierarchy as clusters in the graph.
-h, --help Show help information.
You can also use the sample project to generate a demo graph file:
$ swift run TargetDependencyChecker graph -p ./TestPackage/
Will produce:
digraph {
graph [rankdir=LR]
0 [label="Core"]
1 [label="IndirectCore"]
2 [label="IndirectCoreRoot"]
3 [label="TestPackage"]
0 -> 1
1 -> 2
3 -> 0 [label="@ /Sources/TestPackage/TestPackage.swift", color=red]
}