'Simple way to run SwiftLint for our Swift package
So far what I found is this blog article: It's time to use Swift Package Manager which recommends integrate SwiftLint and other tools with Package.swift
.
I was able to add dependency to the package file, build and test successfully but SwiftLint never warns me about syntax violations.
Before we used this Build Phases step in Xcode project:
if which swiftlint >/dev/null; then
swiftlint
else
echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
fi
The article suggests adopting Komondor which itself useless without PackageConfigs. The idea is to run SwiftLint command during commit. I have tried to add both projects and couldn't get it working in reasonable amount of time. During commit, I see warnings like this:
Illegal instruction: 4 $komondor run pre-commit
This is still early days for Swift Package Manager and there's almost no information on the internet.
Ideally I would like to have any solution which allows our team to automate SwiftLint, and ideally that wouldn't require adding 22 dependencies, config files, and require dynamic library.
Solution 1:[1]
A proposal in Swift, called Package Manager Extensible Build Tools (SE-0303) has been implemented, and is available in Swift 5.6, which is not yet released, as of October 2021.
A new target type, plugin
(alongside executable
and library
) will be available to configure commands during the build. This means SwiftLint has some work to be a Swift package plugin. The SwiftLint authors could implement a package plugin that creates a command to run Swiftlint before the build.
I'll update when this proposal is implemented, and also when SwiftLint supports Extensible Build Tools
Solution 2:[2]
It is possible to attach SwiftLint to Swift Package since version 0.47.1.
You can use .artifactbundle.zip
artefact:
In your Package.swift
:
(...)
targets: [
.binaryTarget(
name: "SwiftLintBinary",
url: "https://github.com/realm/SwiftLint/releases/download/0.47.1/SwiftLintBinary-macos.artifactbundle.zip",
checksum: "cdc36c26225fba80efc3ac2e67c2e3c3f54937145869ea5dbcaa234e57fc3724"
),
.plugin(
name: "SwiftLintPlugin",
capability: .buildTool(),
dependencies: ["SwiftLintBinary"]
),
.target(
name: "YourPackageName",
dependencies: [],
plugins: ["SwiftLintPlugin"]
),
(...)
]
Next you have to set up a plugin configuration. In your "Plugins/SwiftLintPlugin" directory create a "plugin.swift" file:
import PackagePlugin
@main
struct SwiftLintPlugins: BuildToolPlugin {
func createBuildCommands(context: PluginContext, target: Target) async throws -> [Command] {
return [
.buildCommand(
displayName: "Linting \(target.name)...",
executable: try context.tool(named: "swiftlint").path,
arguments: [
"lint",
"--in-process-sourcekit",
"--path",
target.directory.string // only lint the files in the target directory
],
environment: [:]
)
]
}
}
And that's it.
If you need more context how it is done, you can also check out my repository here: https://github.com/Filozoff/Kukulka
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Filozoff |