Skip to content

Commit 052fd6a

Browse files
mildm8nneredSimplyDanny
authored andcommitted
Adds baseline and write_baseline config file options (#5552)
* Adds `baseline` and `write_baseline` config file options, so baseline can be used by people who can't pass command line arguments (e.g. plugin users). * Added PR number * Fixed change log entry * Update Source/swiftlint/Helpers/LintOrAnalyzeCommand.swift Co-authored-by: Danny Mösch <[email protected]> * updated --------- Co-authored-by: Danny Mösch <[email protected]>
1 parent f91521e commit 052fd6a

File tree

8 files changed

+70
-12
lines changed

8 files changed

+70
-12
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@
1616
improvements done in the [SwiftSyntax](https://github.com/apple/swift-syntax)
1717
library.
1818

19+
* Adds `baseline` and `write_baseline` configuration file settings, equivalent
20+
to the `--baseline` and `--write-baseline` command line options.
21+
[Martin Redington](https://github.com/mildm8nnered)
22+
[#5552](https://github.com/realm/SwiftLint/issues/5552)
23+
1924
#### Bug Fixes
2025

2126
* Fix a few false positives and negatives by updating the parser to support

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,12 @@ allow_zero_lintable_files: false
697697
# If true, SwiftLint will treat all warnings as errors.
698698
strict: false
699699

700+
# The path to a baseline file, which will be used to filter out detected violations.
701+
baseline: Baseline.json
702+
703+
# The path to save detected violations to as a new baseline.
704+
write_baseline: Baseline.json
705+
700706
# configurable rules can be customized from this configuration file
701707
# binary rules can set their severity level
702708
force_cast: warning # implicitly

Source/SwiftLintCore/Extensions/Configuration+Merging.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ extension Configuration {
2525
reporter: reporter,
2626
cachePath: cachePath,
2727
allowZeroLintableFiles: childConfiguration.allowZeroLintableFiles,
28-
strict: childConfiguration.strict
28+
strict: childConfiguration.strict,
29+
baseline: childConfiguration.baseline,
30+
writeBaseline: childConfiguration.writeBaseline
2931
)
3032
}
3133

Source/SwiftLintCore/Extensions/Configuration+Parsing.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ extension Configuration {
1515
case analyzerRules = "analyzer_rules"
1616
case allowZeroLintableFiles = "allow_zero_lintable_files"
1717
case strict = "strict"
18+
case baseline = "baseline"
19+
case writeBaseline = "write_baseline"
1820
case childConfig = "child_config"
1921
case parentConfig = "parent_config"
2022
case remoteConfigTimeout = "remote_timeout"
@@ -95,7 +97,9 @@ extension Configuration {
9597
cachePath: cachePath ?? dict[Key.cachePath.rawValue] as? String,
9698
pinnedVersion: dict[Key.swiftlintVersion.rawValue].map { ($0 as? String) ?? String(describing: $0) },
9799
allowZeroLintableFiles: dict[Key.allowZeroLintableFiles.rawValue] as? Bool ?? false,
98-
strict: dict[Key.strict.rawValue] as? Bool ?? false
100+
strict: dict[Key.strict.rawValue] as? Bool ?? false,
101+
baseline: dict[Key.baseline.rawValue] as? String,
102+
writeBaseline: dict[Key.writeBaseline.rawValue] as? String
99103
)
100104
}
101105

Source/SwiftLintCore/Models/Configuration.swift

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,15 @@ public struct Configuration {
3535
/// Allow or disallow SwiftLint to exit successfully when passed only ignored or unlintable files.
3636
public let allowZeroLintableFiles: Bool
3737

38-
/// Treat warnings as errors
38+
/// Treat warnings as errors.
3939
public let strict: Bool
4040

41+
/// The path to read a baseline from.
42+
public let baseline: String?
43+
44+
/// The path to write a baseline to.
45+
public let writeBaseline: String?
46+
4147
/// This value is `true` iff the `--config` parameter was used to specify (a) configuration file(s)
4248
/// In particular, this means that the value is also `true` if the `--config` parameter
4349
/// was used to explicitly specify the default `.swiftlint.yml` as the configuration file
@@ -73,7 +79,9 @@ public struct Configuration {
7379
reporter: String?,
7480
cachePath: String?,
7581
allowZeroLintableFiles: Bool,
76-
strict: Bool
82+
strict: Bool,
83+
baseline: String?,
84+
writeBaseline: String?
7785
) {
7886
self.rulesWrapper = rulesWrapper
7987
self.fileGraph = fileGraph
@@ -85,6 +93,8 @@ public struct Configuration {
8593
self.cachePath = cachePath
8694
self.allowZeroLintableFiles = allowZeroLintableFiles
8795
self.strict = strict
96+
self.baseline = baseline
97+
self.writeBaseline = writeBaseline
8898
}
8999

90100
/// Creates a Configuration by copying an existing configuration.
@@ -102,6 +112,8 @@ public struct Configuration {
102112
cachePath = configuration.cachePath
103113
allowZeroLintableFiles = configuration.allowZeroLintableFiles
104114
strict = configuration.strict
115+
baseline = configuration.baseline
116+
writeBaseline = configuration.writeBaseline
105117
}
106118

107119
/// Creates a `Configuration` by specifying its properties directly,
@@ -122,8 +134,11 @@ public struct Configuration {
122134
/// - parameter reporter: The identifier for the `Reporter` to use to report style violations.
123135
/// - parameter cachePath: The location of the persisted cache to use whith this configuration.
124136
/// - parameter pinnedVersion: The SwiftLint version defined in this configuration.
125-
/// - parameter allowZeroLintableFiles: Allow SwiftLint to exit successfully when passed ignored or unlintable files
126-
/// - parameter strict: Treat warnings as errors
137+
/// - parameter allowZeroLintableFiles: Allow SwiftLint to exit successfully when passed ignored or unlintable
138+
/// files.
139+
/// - parameter strict: Treat warnings as errors.
140+
/// - parameter baseline: The path to read a baseline from.
141+
/// - parameter writeBaseline: The path to write a baseline to.
127142
package init(
128143
rulesMode: RulesMode = .default(disabled: [], optIn: []),
129144
allRulesWrapped: [ConfigurationRuleWrapper]? = nil,
@@ -137,7 +152,9 @@ public struct Configuration {
137152
cachePath: String? = nil,
138153
pinnedVersion: String? = nil,
139154
allowZeroLintableFiles: Bool = false,
140-
strict: Bool = false
155+
strict: Bool = false,
156+
baseline: String? = nil,
157+
writeBaseline: String? = nil
141158
) {
142159
if let pinnedVersion, pinnedVersion != Version.current.value {
143160
queuedPrintError(
@@ -163,7 +180,9 @@ public struct Configuration {
163180
reporter: reporter,
164181
cachePath: cachePath,
165182
allowZeroLintableFiles: allowZeroLintableFiles,
166-
strict: strict
183+
strict: strict,
184+
baseline: baseline,
185+
writeBaseline: writeBaseline
167186
)
168187
}
169188

@@ -268,6 +287,8 @@ extension Configuration: Hashable {
268287
hasher.combine(reporter)
269288
hasher.combine(allowZeroLintableFiles)
270289
hasher.combine(strict)
290+
hasher.combine(baseline)
291+
hasher.combine(writeBaseline)
271292
hasher.combine(basedOnCustomConfigurationFiles)
272293
hasher.combine(cachePath)
273294
hasher.combine(rules.map { type(of: $0).description.identifier })
@@ -286,6 +307,8 @@ extension Configuration: Hashable {
286307
lhs.fileGraph == rhs.fileGraph &&
287308
lhs.allowZeroLintableFiles == rhs.allowZeroLintableFiles &&
288309
lhs.strict == rhs.strict &&
310+
lhs.baseline == rhs.baseline &&
311+
lhs.writeBaseline == rhs.writeBaseline &&
289312
lhs.rulesMode == rhs.rulesMode
290313
}
291314
}

Source/swiftlint/Helpers/LintOrAnalyzeCommand.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ struct LintOrAnalyzeCommand {
4444
private static func lintOrAnalyze(_ options: LintOrAnalyzeOptions) async throws {
4545
let builder = LintOrAnalyzeResultBuilder(options)
4646
let files = try await collectViolations(builder: builder)
47-
if let baselineOutputPath = options.writeBaseline {
47+
if let baselineOutputPath = options.writeBaseline ?? builder.configuration.writeBaseline {
4848
try Baseline(violations: builder.unfilteredViolations).write(toPath: baselineOutputPath)
4949
}
5050
try Signposts.record(name: "LintOrAnalyzeCommand.PostProcessViolations") {
@@ -55,7 +55,7 @@ struct LintOrAnalyzeCommand {
5555
private static func collectViolations(builder: LintOrAnalyzeResultBuilder) async throws -> [SwiftLintFile] {
5656
let options = builder.options
5757
let visitorMutationQueue = DispatchQueue(label: "io.realm.swiftlint.lintVisitorMutation")
58-
let baseline = try baseline(options)
58+
let baseline = try baseline(options, builder.configuration)
5959
return try await builder.configuration.visitLintableFiles(options: options, cache: builder.cache,
6060
storage: builder.storage) { linter in
6161
let currentViolations: [StyleViolation]
@@ -121,8 +121,8 @@ struct LintOrAnalyzeCommand {
121121
guard numberOfSeriousViolations == 0 else { exit(2) }
122122
}
123123

124-
private static func baseline(_ options: LintOrAnalyzeOptions) throws -> Baseline? {
125-
if let baselinePath = options.baseline {
124+
private static func baseline(_ options: LintOrAnalyzeOptions, _ configuration: Configuration) throws -> Baseline? {
125+
if let baselinePath = options.baseline ?? configuration.baseline {
126126
do {
127127
return try Baseline(fromPath: baselinePath)
128128
} catch {

Tests/SwiftLintFrameworkTests/ConfigurationTests.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ final class ConfigurationTests: SwiftLintTestCase {
5656
XCTAssertEqual(reporterFrom(identifier: config.reporter).identifier, "xcode")
5757
XCTAssertFalse(config.allowZeroLintableFiles)
5858
XCTAssertFalse(config.strict)
59+
XCTAssertNil(config.baseline)
60+
XCTAssertNil(config.writeBaseline)
5961
}
6062

6163
func testInitWithRelativePathAndRootPath() {
@@ -70,6 +72,8 @@ final class ConfigurationTests: SwiftLintTestCase {
7072
XCTAssertEqual(config.reporter, expectedConfig.reporter)
7173
XCTAssertTrue(config.allowZeroLintableFiles)
7274
XCTAssertTrue(config.strict)
75+
XCTAssertNotNil(config.baseline)
76+
XCTAssertNotNil(config.writeBaseline)
7377
}
7478

7579
func testEnableAllRulesConfiguration() throws {
@@ -427,6 +431,18 @@ final class ConfigurationTests: SwiftLintTestCase {
427431
let configuration = try Configuration(dict: ["strict": true])
428432
XCTAssertTrue(configuration.strict)
429433
}
434+
435+
func testBaseline() throws {
436+
let baselinePath = "Baseline.json"
437+
let configuration = try Configuration(dict: ["baseline": baselinePath])
438+
XCTAssertEqual(configuration.baseline, baselinePath)
439+
}
440+
441+
func testWriteBaseline() throws {
442+
let baselinePath = "Baseline.json"
443+
let configuration = try Configuration(dict: ["write_baseline": baselinePath])
444+
XCTAssertEqual(configuration.writeBaseline, baselinePath)
445+
}
430446
}
431447

432448
// MARK: - ExcludeByPrefix option tests

Tests/SwiftLintFrameworkTests/Resources/ProjectMock/.swiftlint.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ line_length: 10000000000
88
reporter: "json"
99
allow_zero_lintable_files: true
1010
strict: true
11+
baseline: Baseline.json
12+
write_baseline: Baseline.json

0 commit comments

Comments
 (0)