Skip to content

Swift

gspot checks Swift packages and Xcode projects. SwiftLint and SwiftFormat run at commit. At push, gspot builds the package or Xcode scheme, finds declarations that nothing uses, and measures test coverage. These checks run for the swift and xcode configurations:

CheckStageWhat it does
swift/swiftlintcommitLints Swift files with the SwiftLint files of each scope and nested folder, and treats warnings as errors.
swift/swiftformatcommitChecks the layout of every Swift file against the shipped SwiftFormat rules.
swift/buildpushBuilds the package or Xcode scheme incrementally to report compiler errors.
swift/swiftlint-analyzemanualRuns the SwiftLint analyzer rules over the compiler log of the build: unused imports and captured variables.
swift/peripherypushScans the built project for declarations nothing uses.
swift/skip-reasonscommitChecks that skip calls and disabled traits name a nonempty reason, and unavailable tests carry an explanation.
swift/coveragepushMeasures each source target in Xcode projects and Swift packages against coverage.lines and its coverage.swift_target floor.
xcode/plutilcommitParses every property list and entitlements file with plutil.
xcode/xcstringscommitChecks that each string catalog parses and translates every string into all its locales.
xcode/assetscommitChecks that each asset Contents.json parses, and that its image set holds each file it names.
xcode/unused-assetscommitFinds asset sets that no source or Xcode build setting names.
xcode/files-without-targetcommitFinds the Swift files in the tree that no target of the project names.
xcode/entitlementscommitChecks each entitlement against xcode.allowed_entitlements, when the settings hold that list.
xcode/app-transport-securitycommitRefuses a property list that allows arbitrary loads, which turns transport security off for every host.

Install the Swift toolchain, then install gspot with mise, as the Quickstart shows.

gspot init writes the Xcode project, scheme, and destination that it finds. To set them yourself:

gspot.toml
[swift]
xcode_project = "App.xcodeproj"
xcode_scheme = "App"
xcode_destination = "generic/platform=iOS Simulator"

With swift.xcode_project set, the build, Periphery, analyzer, and coverage checks use that project or workspace. These checks need macOS with Xcode selected by xcode-select, and Periphery runs on macOS only.

The xcode configuration also checks property lists, build settings files, string catalogs, asset catalogs, and entitlements against xcode.allowed_entitlements. Only xcode/plutil needs macOS.

swift/swiftlint-analyze runs the SwiftLint analyzer on the build log. It runs only on macOS, and only when you name it:

gspot check --only swift/swiftlint-analyze

List an import it flags in error under tools.swiftlint.always_keep_imports.

The swift configuration also checks your XCTest and Swift Testing tests. gspot writes a .swiftlint.yml into each Tests or *Tests folder. It turns off force_unwrapping, missing_docs, and no_magic_numbers in tests, while your source files keep those lint rules.

gspot check --only swift/swiftlint reads these nested files. In an editor, run SwiftLint without --config, because that option turns off the nested files.

swift/skip-reasons asks each disabled test for a reason. swift/coverage measures each target against its coverage floor, and skips a scope that holds no tests.

To set a line coverage limit for a Swift target, write a record by hand; gspot set writes no record lists:

gspot.toml
[[coverage.swift_target]]
name = "Orders"
lines = 80

Replace Orders with the target named in the coverage report. Add reason when lines falls below coverage.lines. Then apply the record and run the check:

gspot apply
gspot check --only swift/coverage

Semgrep also runs the Swift security lint rules of the swift configuration on Swift sources and plist files. The Swift configuration lists them.