Go to file
Simon Støvring e9bb860ee7
Adds documentation for ellipse and square shapes (#2)
2022-12-12 09:45:45 +01:00
.github Removes Markdown templates 2022-12-12 07:50:11 +01:00
.swiftpm/xcode/xcshareddata/xcschemes Adds shared scheme 2022-12-11 23:07:02 +01:00
Formula Adds formula 2022-12-12 06:39:56 +01:00
Sources Adds documentation for ellipse and square shapes (#2) 2022-12-12 09:45:45 +01:00
Tests Supports platformNames component in byName (#1) 2022-12-12 09:34:21 +01:00
.gitignore Adds shared scheme 2022-12-11 23:07:02 +01:00
.swiftlint.yml Initial commit 2022-12-05 13:25:51 +01:00
CODEOWNERS Adds CODEOWNERS 2022-12-12 07:50:30 +01:00
LICENSE Adds LICENSE 2022-12-12 07:43:32 +01:00
Package.resolved Initial commit 2022-12-05 13:25:51 +01:00
Package.swift Supports macOS 12 2022-12-11 23:11:21 +01:00
README.md Adds documentation for ellipse and square shapes (#2) 2022-12-12 09:45:45 +01:00
sample-swift-package.png Adds xcodeproj sample 2022-12-11 23:43:52 +01:00
sample-xcodeproj.png Adds xcodeproj sample 2022-12-11 23:43:52 +01:00

README.md

dependency-graph

Build and Test SwiftLint

dependency-graph is a command-line tool that can visualize the dependencies of packages. The tool takes the path to an Xcode project or a Package.swift file as input and outputs a graph that shows the dependencies of the packages in the project or file.

👀 Sample

The graph below shows the relationship of the products and targets in this package as of December 11, 2022. Click on the image to see a larger version.

Example graph showing the dependencies of this package.

Nodes shaped as an ellipse represent products, e.g. the libraries in a Swift package, and the square nodes represent targets.

🚀 Getting Started

Start off by installing the tool with Homebrew.

brew tap simonbs/dependency-graph git@github.com:simonbs/dependency-graph.git
brew install dependency-graph

You may now run the following command to verify that the tool was installed correctly. The following command should print information on how the tool can be used.

dependency-graph --help

Run the dependency-graph command with the path to a folder containing an .xcodeproj or Package.swift file.

dependency-graph ~/Developer/Example

You may also pass the full path to the .xcodeproj or Package.swift file as shown below.

dependency-graph ~/Developer/Example/Example.xcodeproj

Rendering a Graph

The dependency-graph command will output a textual representation of a graph. By default the tool will output a graph using the DOT syntax. For example, if the Xcode project or Package.swift file contains the following dependencies:

Library A in Package A depends on Target A
Library B in Package B depends on Target B
Library A in Package A depends on Library B in Package B

The output of the tool would be a graph that looks like this:

digraph g {
  subgraph cluster_packageA {
    label="Package A"
    libraryA [label="LibraryB", shape=ellipse]
    targetA [label="TargetA", shape=box]
  }

  subgraph cluster_packageB {
    label="Package B"
    libraryB [label="LibraryB", shape=ellipse]
    targetB [label="TargetB", shape=box]
  }

  libraryA -> targetA
  libraryB -> targetB
  libraryA -> libraryB
}

The output can be rendered to an image by piping it to the dot CLI, which is part of Graphviz.

Install Graphviz and run dependency-graph and pass the output to the newly installed dot CLI.

brew install graphviz
dependency-graph ~/Developer/Example | dot -Tsvg -o graph.svg

The output previous example output would look different but similar when using the Mermaid diagram syntax instead. The syntax is used by passing the --syntax mermaid option.

Output in the Mermaid diagram syntax can be rendered to an image using the the mermaid cli.

npm install -g @mermaid-js/mermaid-cli
dependency-graph --syntax mermaid ~/Developer/Example | mmdc -o graph.svg

🤷‍♂️ OK, why?

As I'm splitting my iOS and macOS applications into small Swift packages with several small targets, I started wishing for a way to visualise the relationship between the products and targets in my Swift packages. That's why I built this tool.

Several other tools can visualise a Swift package, however, I wanted a tool that can take both a Swift package and an Xcode project as input.

The example in the top of this README shows a visualization of a Swift package and the graph below shows a visualisation of an Xcode project. Notice that the left-most subgraph represents an Xcode project named ScriptUIEditor.xcodeproj and it has three targets: ScriptUIEditor, ScriptBrowserFeature, and ScriptBrowserFeatureUITests. Two of these depends on the Swift packages represented by the remaining subgraphs.

These graphs provide a good way to get an overview of a package or the relationship between several packages. Sometimes it can be helpful to generate multiple graphs to get a good overview, for example, a graph of the entire project and graphs of selected packages. Fortunately, the dependency-graph cLI makes this easy as it can take either an Xcode project and a Package.swift file as input.

Example graph showing the dependencies of an Xcode project.

🧐 ...but how?

dependency-graph parses Xcode project using XcodeProj and interprets Package.swift files using the output from the swift package dump-package command.

This means that dependency-graph does not perform any package resolution or build the project, making it very fast to run the dependency-graph command but also produces a less detailed output that tools that rely on package resolution.

The tool has a focus on visualising local dependencies, that is, Swift packages stored locally in a project. dependency-graph will include remote dependencies in the visualisation but it will not clone those dependencies to deterine their dependency graph. It is technically possible to include this but it has not been necessary for my use cases.