Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@

### Enhancements

* Print fixed code read from stdin to stdout.
* Add `--fail-on-unfixable` flag for single-pass fix and validation.
[omar-y-abdi](https://github.com/omar-y-abdi)
[#6450](https://github.com/realm/SwiftLint/issues/6450)

* Print fixed code read from stdin to stdout.
[SimplyDanny](https://github.com/SimplyDanny)
[#6501](https://github.com/realm/SwiftLint/issues/6501)

Expand Down
54 changes: 52 additions & 2 deletions Source/SwiftLintFramework/LintOrAnalyzeCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ package struct LintOrAnalyzeOptions {
let compilerLogPath: String?
let compileCommands: String?
let checkForUpdates: Bool
let failOnUnfixable: Bool

package init(mode: LintOrAnalyzeMode,
paths: [String],
Expand Down Expand Up @@ -86,7 +87,8 @@ package struct LintOrAnalyzeOptions {
disableSourceKit: Bool,
compilerLogPath: String?,
compileCommands: String?,
checkForUpdates: Bool) {
checkForUpdates: Bool,
failOnUnfixable: Bool = false) {
self.mode = mode
self.paths = paths
self.useSTDIN = useSTDIN
Expand Down Expand Up @@ -115,6 +117,42 @@ package struct LintOrAnalyzeOptions {
self.compilerLogPath = compilerLogPath
self.compileCommands = compileCommands
self.checkForUpdates = checkForUpdates
self.failOnUnfixable = failOnUnfixable
}

/// Returns a copy of these options with `autocorrect` set to `false` and `failOnUnfixable` set to `false`,
/// suitable for a re-lint pass after autocorrection.
func asLintOnly() -> Self {
Self(
mode: mode,
paths: paths,
useSTDIN: useSTDIN,
configurationFiles: configurationFiles,
strict: strict,
lenient: lenient,
forceExclude: forceExclude,
useExcludingByPrefix: useExcludingByPrefix,
useScriptInputFiles: useScriptInputFiles,
useScriptInputFileLists: useScriptInputFileLists,
benchmark: benchmark,
reporter: reporter,
baseline: baseline,
writeBaseline: writeBaseline,
workingDirectory: nil, // Already changed in run()
quiet: quiet,
output: output,
progress: progress,
cachePath: cachePath,
ignoreCache: true, // Must ignore cache since files were just modified
enableAllRules: enableAllRules,
onlyRule: onlyRule,
autocorrect: false,
format: false,
disableSourceKit: disableSourceKit,
compilerLogPath: compilerLogPath,
compileCommands: compileCommands,
checkForUpdates: false // Already checked in autocorrect pass
)
}

var verb: String {
Expand All @@ -140,7 +178,19 @@ package struct LintOrAnalyzeCommand {
}
}
try await Signposts.record(name: "LintOrAnalyzeCommand.run") {
try await options.autocorrect ? autocorrect(options) : lintOrAnalyze(options)
if options.autocorrect {
try await autocorrect(options)
if options.failOnUnfixable {
try await lintOrAnalyze(options.asLintOnly())
}
} else {
if options.failOnUnfixable {
queuedPrintError(
"warning: The option --fail-on-unfixable has no effect without --fix."
)
}
try await lintOrAnalyze(options)
}
}
}

Expand Down
3 changes: 2 additions & 1 deletion Source/swiftlint/Commands/Analyze.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ extension SwiftLint {
disableSourceKit: false,
compilerLogPath: compilerLogPath,
compileCommands: compileCommands,
checkForUpdates: common.checkForUpdates
checkForUpdates: common.checkForUpdates,
failOnUnfixable: common.failOnUnfixable
)

try await LintOrAnalyzeCommand.run(options)
Expand Down
5 changes: 3 additions & 2 deletions Source/swiftlint/Commands/Lint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ extension SwiftLint {
func run() async throws {
Issue.printDeprecationWarnings = !silenceDeprecationWarnings

if common.fix, let leniency = common.leniency {
if common.fix, !common.failOnUnfixable, let leniency = common.leniency {
Issue.genericWarning("The option --\(leniency) has no effect together with --fix.").print()
}

Expand Down Expand Up @@ -64,7 +64,8 @@ extension SwiftLint {
disableSourceKit: disableSourceKit,
compilerLogPath: nil,
compileCommands: nil,
checkForUpdates: common.checkForUpdates
checkForUpdates: common.checkForUpdates,
failOnUnfixable: common.failOnUnfixable
)
try await LintOrAnalyzeCommand.run(options)
}
Expand Down
2 changes: 2 additions & 0 deletions Source/swiftlint/Common/LintOrAnalyzeArguments.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ struct LintOrAnalyzeArguments: ParsableArguments {
"""
)
var onlyRule: [String] = []
@Flag(help: "Fail with a non-zero exit code if there are remaining violations after fix.")
var failOnUnfixable = false
}

// MARK: - Common Argument Help
Expand Down