Linting swift package with swift-format

I'm using this plugin to lint my package with swift-format:

// SwiftFormatPlugin.swift

import Foundation
import PackagePlugin

@main struct SwiftFormatPlugin: BuildToolPlugin {
    func createBuildCommands(context: PluginContext, target: Target) throws -> [Command] {
        let directory = context.package.directoryURL
        let plugin = directory.appending(path: "Plugins/SwiftFormatPlugin")
        return [
            .buildCommand(
                displayName: "SwiftFormatPlugin",
                executable: URL(filePath: "/bin/bash"),
                arguments: [
                    plugin.appending(component: "script.sh").path,
                    directory.path,
                    directory.appending(path: ".swift-format").path
                ],
                environment: [:],
                inputFiles: [],
                outputFiles: []
            )
        ]
    }
}

This is the contents of my Package.swift file:

// Package.swift

import PackageDescription

let package = Package(
    name: "MyLibrary",
    products: [
        .library(
            name: "MyLibrary",
            targets: ["MyLibrary"]
        )
    ],
    targets: [
        .target(
            name: "MyLibrary",
            plugins: [
                .plugin(name: "SwiftFormatPlugin")
            ]
        ),
        .plugin(
            name: "SwiftFormatPlugin",
            capability: .buildTool(),
            path: "Plugins/SwiftFormatPlugin"
        )
    ]
)

And finally the script my plugin is executing:

#!/bin/bash
# script.sh

echo "SwiftFormatPlugin test .................."

It works alright as I am getting desired output when building:

SwiftFormatPlugin test ..................

But I'm also getting this:

I want to fix that, but how do I "check" that option? The script phase or the mentioned checkbox is nowhere in the UI for package targets.

Unfortunately I think this is more of an Xcode question (or the intersection of Xcode and SwiftPM) rather than a swift-format question specifically, and I'm not an expert on the former. I think that warning comes from Xcode itself, and if there's nothing in the UI to silence it, I'm not sure how else you'd be able to handle it.

Thank you!

FTM it's not the warning per se that bothers me.. I believe the underlying issue behind that warning is what somehow results into multiple entries for the same swift-format warning being listed, like hundreds of identical warnings per one issue. Hope to solve it one day :)

FWIW, this time I started from scratch and redone it differently, without involving plugin:

  • got rid of SwiftFormatPlugin.swift
  • got rid of the corresponding change in Package.swift
  • got rid of the corresponding script that plugin was using
  • in the main app target (not the package) introduced a build-phase:
xcrun swift-format lint --recursive "$SRCROOT"
xcrun swift-format lint --recursive "$SRCROOT/../Library/Sources"

The first line of that lints the app target itself and the second - lints the library (package) files.

  • I also unchecked the build phases's Run script: Based on dependency analysis - not sure if that's needed will give it a go with it enabled to see if it's actually needed.

To my delight this works wonderfully.

The most painful step was making 5K+ changes IRT spacing and indentation rules. swift-format could benefit from having those rules customisable, e.g. the trailing spaces rule could be "keep as it is" (in addition to what it currently has "no spaces at all" and "properly indented spaces").

I wonder how popular is using swift-format as a linter, but it's +1 team now. :raising_hands:

1 Like