Skip to content

getyourguide/spmgraph

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

spmgraph logo SwiftPM dependency graphs supercharged

CI status Toolchain Mint Swift Package Manager

A CLI tool that unlocks Swift dependency graphs, giving you extra information and capabilities.
With it, you can visualize your dependency graph, run selective tests, and enforce architectural rules for an optimal modular setup.
spmgraph can be run for any local Package.swift.

Visualize

Generate an image that visually represents your dependency graph. Open the map!

spmgraph visualize <package-path> --help

Tests

Selective testing based on git changes or a given list of changed files.
The output is a comma-separated list of test targets that can be fed into xcodebuild's -only-testing:TEST-IDENTIFIER or fastlane scan's only_testing

spmgraph tests <package-path> --help

Lint

Verifies whether the dependency graph follows the team-defined best practices.

It's built on top of a user-defined SPMGraphConfig.swift, which allows teams to configure their own dependency graph rules leveraging Swift and the SwiftPM library.

SPMGraphConfig.default provides the standard definition with built-in rules and extensible rules that can also be used on custom configurations.

For that, the steps are:

Config & Load

1. Config

Init or edit your spmgraph config

spmgraph config <package-path> --help
  • if none, it creates an initial SPMGraphConfig.swift on the same path as your Package.swift
  • spmgraph opens up a temporary Swift Package where you configure spmgraph in Swift and build to check that everything is correct

Examples

For example, enforce that

  • Feature modules don't depend on each other
  • Linked dependencies are imported (used) at least once
  • Base modules don't depend on feature modules
  • The dependency graph isn't too deep

All possible using Swift. Below is an example of creating your own lint rule by traversing the dependency graph:

extension SPMGraphConfig.Lint.Rule {
  static let unregisteredLiveModules = Self(
    id: "unregisteredLiveModules",
    name: "Unregistered Live modules",
    abstract: "Live modules need to be added to the app target/feature module as dependencies.",
    validate: { package, excludedSuffixes in
      let liveModules = package
        .modules
        .compactMap { module -> Module? in
          guard !module.containsOneOf(suffixes: excludedSuffixes), module.isLiveModule else {
            return nil
          }
          return module
        }

      guard
        let featureModule = package
          .modules
          .first(where: { $0.name == "GetYourGuideFeature" }),
        case let featureModuleDependencies = featureModule
          .dependencies
          .compactMap(\.module)
      else {
        return [LintError.missingFeatureModule]
      }

      return liveModules.compactMap { liveModule in
        if !featureModuleDependencies.contains(liveModule) {
          return LintError.unregisteredLiveModules(
            moduleName: liveModule.name,
            appModule: featureModule.name
          )
        }

        return nil
      }
    }
  )
}

2. Load

Load the latest SPMGraphConfig.swift into spmgraph

spmgraph load <package-path> --help

Run the linter

spmgraph lint <package-path> --help

Fail on warnings

spmgraph lint <package-path> --strict <other-options>

Allowed warnings count

Bypass the strict mode on a given number of allowed warnings

spmgraph lint <package-path> --strict --warningsCount 3 <other-options>

CI

Custom GitHub actions are available for running the different spmgraph commands in CI environments.

To speed up builds

  • Pass a custom config build directory via the --config-build-directory/--build-dir option
  • It allows caching and pre-warming the config package

Cache warm

  • Run config, load, and lint passing the --config-build-directory/--build-dir option
  • Store the whole directory as an artifact

Cache pull

  • Pull the stored directory used when warming the cache
  • Skip running config and load, unless the SPMGraphConfig.swift has changed
  • Run lint passing the cached directory to the --config-build-directory/--build-dir option

Requirements

  • graphviz (available via brew install graphviz)
  • Xcode 16.3+ and the Swift 6.1+ toolchain

Installation

mint install getyourguide/spmgraph
  • For optimal build times, make sure ~/.mint/bin/spmgraph is cached on your CI runner.

Acknowledgments

  • Inspired by the work that the Tuist team does for the Apple developers community and their focus on leveraging the dependency graph to provide amazing features for engineers. Also, a source of inspiration for our shell abstraction layer.

Contributing

Check the CONTRIBUTING.md file.

About

A dependency graph management tool for the Swift Package Manager

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  

Languages