Skip to content

Commit

Permalink
Add strict configuration file setting (#5226)
Browse files Browse the repository at this point in the history
  • Loading branch information
mildm8nnered authored Sep 18, 2023
1 parent f62411e commit f783b02
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 12 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@
[Martin Redington](https://github.com/mildm8nnered)
[#5215](https://github.com/realm/SwiftLint/issues/5215)

* Adds a `strict` configuration file setting, equivalent to the `--strict`
command line option.
[Martin Redington](https://github.com/mildm8nnered)
[#5226](https://github.com/realm/SwiftLint/issues/5226)

#### Bug Fixes

* Respect grapheme clusters in counting the number of characters in the `collection_alignment` rule.
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,9 @@ excluded: # case-sensitive paths to ignore during linting. Takes precedence over
# If true, SwiftLint will not fail if no lintable files are found.
allow_zero_lintable_files: false

# If true, SwiftLint will treat all warnings as errors.
strict: false

# configurable rules can be customized from this configuration file
# binary rules can set their severity level
force_cast: warning # implicitly
Expand Down
3 changes: 2 additions & 1 deletion Source/SwiftLintCore/Extensions/Configuration+Merging.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ extension Configuration {
warningThreshold: mergedWarningTreshold(with: childConfiguration),
reporter: reporter,
cachePath: cachePath,
allowZeroLintableFiles: childConfiguration.allowZeroLintableFiles
allowZeroLintableFiles: childConfiguration.allowZeroLintableFiles,
strict: childConfiguration.strict
)
}

Expand Down
4 changes: 3 additions & 1 deletion Source/SwiftLintCore/Extensions/Configuration+Parsing.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ extension Configuration {
case indentation = "indentation"
case analyzerRules = "analyzer_rules"
case allowZeroLintableFiles = "allow_zero_lintable_files"
case strict = "strict"
case childConfig = "child_config"
case parentConfig = "parent_config"
case remoteConfigTimeout = "remote_timeout"
Expand Down Expand Up @@ -88,7 +89,8 @@ extension Configuration {
reporter: dict[Key.reporter.rawValue] as? String ?? XcodeReporter.identifier,
cachePath: cachePath ?? dict[Key.cachePath.rawValue] as? String,
pinnedVersion: dict[Key.swiftlintVersion.rawValue].map { ($0 as? String) ?? String(describing: $0) },
allowZeroLintableFiles: dict[Key.allowZeroLintableFiles.rawValue] as? Bool ?? false
allowZeroLintableFiles: dict[Key.allowZeroLintableFiles.rawValue] as? Bool ?? false,
strict: dict[Key.strict.rawValue] as? Bool ?? false
)
}

Expand Down
19 changes: 15 additions & 4 deletions Source/SwiftLintCore/Models/Configuration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ public struct Configuration {
/// Allow or disallow SwiftLint to exit successfully when passed only ignored or unlintable files.
public let allowZeroLintableFiles: Bool

/// Treat warnings as errors
public let strict: Bool

/// This value is `true` iff the `--config` parameter was used to specify (a) configuration file(s)
/// In particular, this means that the value is also `true` if the `--config` parameter
/// was used to explicitly specify the default `.swiftlint.yml` as the configuration file
Expand Down Expand Up @@ -69,7 +72,8 @@ public struct Configuration {
warningThreshold: Int?,
reporter: String,
cachePath: String?,
allowZeroLintableFiles: Bool
allowZeroLintableFiles: Bool,
strict: Bool
) {
self.rulesWrapper = rulesWrapper
self.fileGraph = fileGraph
Expand All @@ -80,6 +84,7 @@ public struct Configuration {
self.reporter = reporter
self.cachePath = cachePath
self.allowZeroLintableFiles = allowZeroLintableFiles
self.strict = strict
}

/// Creates a Configuration by copying an existing configuration.
Expand All @@ -96,6 +101,7 @@ public struct Configuration {
basedOnCustomConfigurationFiles = configuration.basedOnCustomConfigurationFiles
cachePath = configuration.cachePath
allowZeroLintableFiles = configuration.allowZeroLintableFiles
strict = configuration.strict
}

/// Creates a `Configuration` by specifying its properties directly,
Expand All @@ -117,6 +123,7 @@ public struct Configuration {
/// - parameter cachePath: The location of the persisted cache to use whith this configuration.
/// - parameter pinnedVersion: The SwiftLint version defined in this configuration.
/// - parameter allowZeroLintableFiles: Allow SwiftLint to exit successfully when passed ignored or unlintable files
/// - parameter strict: Treat warnings as errors
@_spi(TestHelper)
public init(
rulesMode: RulesMode = .default(disabled: [], optIn: []),
Expand All @@ -130,7 +137,8 @@ public struct Configuration {
reporter: String? = nil,
cachePath: String? = nil,
pinnedVersion: String? = nil,
allowZeroLintableFiles: Bool = false
allowZeroLintableFiles: Bool = false,
strict: Bool = false
) {
if let pinnedVersion, pinnedVersion != Version.current.value {
queuedPrintError(
Expand All @@ -155,7 +163,8 @@ public struct Configuration {
warningThreshold: warningThreshold,
reporter: reporter ?? XcodeReporter.identifier,
cachePath: cachePath,
allowZeroLintableFiles: allowZeroLintableFiles
allowZeroLintableFiles: allowZeroLintableFiles,
strict: strict
)
}

Expand Down Expand Up @@ -259,6 +268,7 @@ extension Configuration: Hashable {
hasher.combine(warningThreshold)
hasher.combine(reporter)
hasher.combine(allowZeroLintableFiles)
hasher.combine(strict)
hasher.combine(basedOnCustomConfigurationFiles)
hasher.combine(cachePath)
hasher.combine(rules.map { type(of: $0).description.identifier })
Expand All @@ -275,7 +285,8 @@ extension Configuration: Hashable {
lhs.cachePath == rhs.cachePath &&
lhs.rules == rhs.rules &&
lhs.fileGraph == rhs.fileGraph &&
lhs.allowZeroLintableFiles == rhs.allowZeroLintableFiles
lhs.allowZeroLintableFiles == rhs.allowZeroLintableFiles &&
lhs.strict == rhs.strict
}
}

Expand Down
23 changes: 18 additions & 5 deletions Source/swiftlint/Helpers/LintOrAnalyzeCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,22 @@ struct LintOrAnalyzeCommand {
let start = Date()
let (violationsBeforeLeniency, currentRuleTimes) = linter
.styleViolationsAndRuleTimes(using: builder.storage)
currentViolations = applyLeniency(options: options, violations: violationsBeforeLeniency)
currentViolations = applyLeniency(
options: options,
strict: builder.configuration.strict,
violations: violationsBeforeLeniency
)
visitorMutationQueue.sync {
builder.fileBenchmark.record(file: linter.file, from: start)
currentRuleTimes.forEach { builder.ruleBenchmark.record(id: $0, time: $1) }
builder.violations += currentViolations
}
} else {
currentViolations = applyLeniency(options: options,
violations: linter.styleViolations(using: builder.storage))
currentViolations = applyLeniency(
options: options,
strict: builder.configuration.strict,
violations: linter.styleViolations(using: builder.storage)
)
visitorMutationQueue.sync {
builder.violations += currentViolations
}
Expand Down Expand Up @@ -139,8 +146,14 @@ struct LintOrAnalyzeCommand {
reason: "Number of warnings exceeded threshold of \(threshold).")
}

private static func applyLeniency(options: LintOrAnalyzeOptions, violations: [StyleViolation]) -> [StyleViolation] {
switch (options.lenient, options.strict) {
private static func applyLeniency(
options: LintOrAnalyzeOptions,
strict: Bool,
violations: [StyleViolation]
) -> [StyleViolation] {
let strict = (strict && !options.lenient) || options.strict

switch (options.lenient, strict) {
case (false, false):
return violations

Expand Down
9 changes: 8 additions & 1 deletion Tests/SwiftLintFrameworkTests/ConfigurationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class ConfigurationTests: SwiftLintTestCase {
XCTAssertEqual(config.reporter, "xcode")
XCTAssertEqual(reporterFrom(identifier: config.reporter).identifier, "xcode")
XCTAssertFalse(config.allowZeroLintableFiles)
XCTAssertFalse(config.strict)
}

func testInitWithRelativePathAndRootPath() {
Expand All @@ -69,6 +70,7 @@ class ConfigurationTests: SwiftLintTestCase {
XCTAssertEqual(config.indentation, expectedConfig.indentation)
XCTAssertEqual(config.reporter, expectedConfig.reporter)
XCTAssertTrue(config.allowZeroLintableFiles)
XCTAssertTrue(config.strict)
}

func testEnableAllRulesConfiguration() throws {
Expand Down Expand Up @@ -100,7 +102,7 @@ class ConfigurationTests: SwiftLintTestCase {

let config = try Configuration(dict: ["only_rules": only, "custom_rules": customRules])
guard let resultingCustomRules = config.rules.first(where: { $0 is CustomRules }) as? CustomRules
else {
else {
XCTFail("Custom rules are expected to be present")
return
}
Expand Down Expand Up @@ -421,6 +423,11 @@ class ConfigurationTests: SwiftLintTestCase {
let configuration = try Configuration(dict: ["allow_zero_lintable_files": true])
XCTAssertTrue(configuration.allowZeroLintableFiles)
}

func testStrict() throws {
let configuration = try Configuration(dict: ["strict": true])
XCTAssertTrue(configuration.strict)
}
}

// MARK: - ExcludeByPrefix option tests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ excluded:
line_length: 10000000000
reporter: "json"
allow_zero_lintable_files: true
strict: true

0 comments on commit f783b02

Please sign in to comment.