Skip to content

Commit 8ae7236

Browse files
marcelofabrisjavora
authored andcommitted
Warn if a configured rule is not enabled.
Fixes realm#1350
1 parent 8203c48 commit 8ae7236

File tree

2 files changed

+53
-7
lines changed

2 files changed

+53
-7
lines changed

CHANGELOG.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
* Make `redundant_objc_attribute` rule autocorrectable.
3333
[Daniel Metzing](https://github.com/dirtydanee)
34-
34+
3535
* Add `required_deinit` opt-in rule to ensure that all classes have a deinit
3636
method. The purpose of this is to make memory leak debugging easier so all
3737
classes have a place to set a breakpoint to track deallocation.
@@ -41,7 +41,11 @@
4141
* `nimble_operator` now warns about `beTrue()` and `beFalse()`.
4242
[Igor-Palaguta](https://github.com/Igor-Palaguta)
4343
[#2613](https://github.com/realm/SwiftLint/issues/2613)
44-
44+
45+
* Warn if a configured rule is not enabled.
46+
[Marcelo Fabri](https://github.com/marcelofabri)
47+
[#1350](https://github.com/realm/SwiftLint/issues/1350)
48+
4549
#### Bug Fixes
4650

4751
* Fix `explicit_type_interface` when used in statements.

Source/SwiftLintFramework/Extensions/Configuration+Parsing.swift

+47-5
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ extension Configuration {
1515
case analyzerRules = "analyzer_rules"
1616
}
1717

18-
private static func validKeys(ruleList: RuleList) -> [String] {
19-
return [
18+
private static let validGlobalKeys: Set<String> = {
19+
return Set([
2020
Key.cachePath,
2121
.disabledRules,
2222
.enabledRules,
@@ -30,7 +30,13 @@ extension Configuration {
3030
.whitelistRules,
3131
.indentation,
3232
.analyzerRules
33-
].map({ $0.rawValue }) + ruleList.allValidIdentifiers()
33+
].map({ $0.rawValue }))
34+
}()
35+
36+
private static func validKeys(ruleList: RuleList) -> Set<String> {
37+
var keys = validGlobalKeys
38+
keys.formUnion(ruleList.allValidIdentifiers())
39+
return keys
3440
}
3541

3642
private static func getIndentationLogIfInvalid(from dict: [String: Any]) -> IndentationStyle {
@@ -90,7 +96,8 @@ extension Configuration {
9096
swiftlintVersion: swiftlintVersion,
9197
cachePath: cachePath ?? dict[Key.cachePath.rawValue] as? String,
9298
indentation: indentation,
93-
customRulesIdentifiers: customRulesIdentifiers)
99+
customRulesIdentifiers: customRulesIdentifiers,
100+
dict: dict)
94101
}
95102

96103
private init?(disabledRules: [String],
@@ -107,7 +114,8 @@ extension Configuration {
107114
swiftlintVersion: String?,
108115
cachePath: String?,
109116
indentation: IndentationStyle,
110-
customRulesIdentifiers: [String]) {
117+
customRulesIdentifiers: [String],
118+
dict: [String: Any]) {
111119
let rulesMode: RulesMode
112120
if enableAllRules {
113121
rulesMode = .allEnabled
@@ -123,6 +131,9 @@ extension Configuration {
123131
rulesMode = .default(disabled: disabledRules, optIn: optInRules + analyzerRules)
124132
}
125133

134+
Configuration.validateConfiguredRulesAreEnabled(configurationDictionary: dict, ruleList: ruleList,
135+
rulesMode: rulesMode)
136+
126137
self.init(rulesMode: rulesMode,
127138
included: included,
128139
excluded: excluded,
@@ -178,6 +189,37 @@ extension Configuration {
178189
queuedPrintError("Configuration contains invalid keys:\n\(invalidKeys)")
179190
}
180191
}
192+
193+
private static func validateConfiguredRulesAreEnabled(configurationDictionary dict: [String: Any],
194+
ruleList: RuleList,
195+
rulesMode: RulesMode) {
196+
for key in dict.keys where !validGlobalKeys.contains(key) {
197+
guard let identifier = ruleList.identifier(for: key),
198+
let rule = ruleList.list[identifier] else {
199+
continue
200+
}
201+
202+
let message = "Found a configuration for '\(identifier)' rule"
203+
204+
switch rulesMode {
205+
case .allEnabled:
206+
return
207+
case .whitelisted(let whitelist):
208+
if Set(whitelist).isDisjoint(with: rule.description.allIdentifiers) {
209+
queuedPrintError("\(message), but it is not present on " +
210+
"'\(Key.whitelistRules.rawValue)'.")
211+
}
212+
case let .default(disabled: disabledRules, optIn: optInRules):
213+
if rule is OptInRule.Type, Set(optInRules).isDisjoint(with: rule.description.allIdentifiers) {
214+
queuedPrintError("\(message), but it is not enabled on " +
215+
"'\(Key.optInRules.rawValue)'.")
216+
} else if Set(disabledRules).isSuperset(of: rule.description.allIdentifiers) {
217+
queuedPrintError("\(message), but it is disabled on " +
218+
"'\(Key.disabledRules.rawValue)'.")
219+
}
220+
}
221+
}
222+
}
181223
}
182224

183225
private func defaultStringArray(_ object: Any?) -> [String] {

0 commit comments

Comments
 (0)