Add SwiftLint build phase to SwiftUI App template#65
Open
ssestak wants to merge 3 commits into
Open
Conversation
added 3 commits
May 12, 2026 14:08
Adds a Run Script build phase that runs swiftlint --fix followed by swiftlint, so generated projects autocorrect and surface remaining warnings in Xcode's issue navigator. Falls back to a friendly warning when SwiftLint is not installed.
Declare the full BuildPhases array so SwiftLint runs first, ensuring --fix corrects sources before they are compiled. Also disable ENABLE_USER_SCRIPT_SANDBOXING so SwiftLint can read project files under Xcode 15+'s default sandbox.
Xcode template inheritance only appends BuildPhases — declaring Sources/Frameworks/Resources in the child template creates empty duplicates instead of replacing the inherited ones. Keep only the SwiftLint phase and surface a #warning telling the developer to drag it above Compile Sources so --fix corrections apply to the current build instead of the next one.
5fb78e5 to
cc2e525
Compare
jmarek41
reviewed
May 15, 2026
| <string>___VARIABLE_bundleIdentifierPrefix:bundleIdentifier___.___PACKAGENAMEASRFC1034IDENTIFIER___.beta</string> | ||
| </dict> | ||
| </dict> | ||
| <key>BuildPhases</key> |
Member
There was a problem hiding this comment.
Na iRozhlase jsem si ten script upravoval takto:
if [[ "${BUILD_DIR}" =~ "Previews" ]]; then
echo "SwiftLint not enabled when compiling for previews"
exit
fi
if test -d "/opt/homebrew/bin/"; then
PATH="/opt/homebrew/bin/:${PATH}"
fi
export PATH
if which swiftlint >/dev/null; then
swiftlint --fix --quiet
swiftlint
else
echo "error: SwiftLint not installed, run: brew install swiftlint"
fi
Aby se to nedělalo když buildíš pro previews. Dává ti to smysl?
Member
There was a problem hiding this comment.
Dále jsem přidával i ten SwiftFormat, nedáme to taky by default do všech projektů? Já bych byl za.
if [[ "${BUILD_DIR}" =~ "Previews" ]]; then
echo "SwiftFormat not enabled when compiling for previews"
exit
fi
if test -d "/opt/homebrew/bin/"; then
PATH="/opt/homebrew/bin/:${PATH}"
fi
export PATH
if which swiftformat >/dev/null; then
swiftformat "$SRCROOT"
else
echo "warning: SwiftFormat not installed, run: brew install swiftformat"
fi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a SwiftLint Run Script build phase to the SwiftUI App Xcode project template. Generated projects autocorrect on every build and surface remaining warnings in Xcode's issue navigator — no manual install of the phase itself needed after project creation.
Flow
flowchart LR A[Build starts] --> B[Compile Sources] B --> C[Link Frameworks] C --> D[Copy Resources] D --> E[SwiftLint phase] E --> F{swiftlint on PATH?} F -- yes --> G[swiftlint --fix --quiet] G --> H[swiftlint] H --> I[Warnings in Xcode] F -- no --> J[Build-log warning:<br/>'brew install swiftlint']Key Changes
Templates/SwiftUI App.xctemplate/TemplateInfo.plistBuildPhasesarray on the app target with a singleShellScriptphase namedSwiftLint.ENABLE_USER_SCRIPT_SANDBOXING = NOadded toSharedSettings— Xcode 15+ sandboxes script phases by default, which blocks SwiftLint from reading project files (Sandbox: swiftlint deny file-read-data …).Templates/SwiftUI App.xctemplate/App.swift— new#warninginstructing the developer to drag the SwiftLint phase aboveCompile Sources./opt/homebrew/binfor Apple Silicon, runsswiftlint --fix --quietthenswiftlint. Graceful fallback emits a build-log warning when SwiftLint isn't installed.Known Limitation — Phase Position
Xcode project templates can only append custom phases to a target — there is no documented key (
InsertBefore,Position,ReplaceBuildPhases, …) to insert before phases inherited fromcom.apple.dt.unit.applicationBase. Confirmed empirically (declaringSources/Frameworks/Resourcesin the child array creates duplicate empty phases instead of replacing the inherited ones) and via research of public Xcode templates on disk and community projects (surfstudio, GoodRequest) — all of them rely on the same after-Sources position.Consequence: as generated, the SwiftLint phase runs after Compile Sources, so
--fixcorrections apply to the next build. The new#warninginApp.swifttells the developer to drag the phase above Compile Sources once — the reorder persists inproject.pbxproj.Out of Scope
.swiftlint.ymlinside the template — left to the developer.project.pbxproj— would require shipping a Ruby/Python script with the template.Test Plan
SwiftLintbuild phase appears on the target (one, not duplicated)--fixcorrects it on the same buildSandbox: swiftlint deny …errors in the build log#warningabout reordering appears in the issue navigator on first build