mirror of
https://github.com/realm/SwiftLint.git
synced 2026-05-07 20:12:49 +00:00
134 lines
5.7 KiB
Swift
134 lines
5.7 KiB
Swift
public extension Configuration {
|
|
/// Returns the rule for the specified ID, if configured in this configuration.
|
|
///
|
|
/// - parameter ruleID: The identifier for the rule to look up.
|
|
///
|
|
/// - returns: The rule for the specified ID, if configured in this configuration.
|
|
func configuredRule(forID ruleID: String) -> (any Rule)? {
|
|
rules.first { rule in
|
|
if type(of: rule).identifier == ruleID {
|
|
if let customRules = rule as? CustomRules {
|
|
return customRules.configuration.customRuleConfigurations.isNotEmpty
|
|
}
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
}
|
|
|
|
/// Represents how a Configuration object can be configured with regards to rules.
|
|
enum RulesMode: Equatable {
|
|
/// The default rules mode, which will enable all rules that aren't defined as being opt-in
|
|
/// (conforming to the `OptInRule` protocol), minus the rules listed in `disabled`, plus the rules listed in
|
|
/// `optIn`.
|
|
case defaultConfiguration(disabled: Set<String>, optIn: Set<String>)
|
|
|
|
/// Only enable the rules explicitly listed in the configuration files.
|
|
case onlyConfiguration(Set<String>)
|
|
|
|
/// Only enable the rule(s) explicitly listed on the command line (and their aliases). `--only-rule` can be
|
|
/// specified multiple times to enable multiple rules.
|
|
case onlyCommandLine(Set<String>)
|
|
|
|
/// Enable all available rules.
|
|
case allCommandLine
|
|
|
|
internal init(
|
|
enableAllRules: Bool,
|
|
onlyRule: [String],
|
|
onlyRules: [String],
|
|
optInRules: [String],
|
|
disabledRules: [String],
|
|
analyzerRules: [String]
|
|
) throws {
|
|
func warnAboutDuplicates(in identifiers: [String]) {
|
|
if Set(identifiers).count != identifiers.count {
|
|
let duplicateRules = identifiers.reduce(into: [String: Int]()) { $0[$1, default: 0] += 1 }
|
|
.filter { $0.1 > 1 }
|
|
for duplicateRule in duplicateRules {
|
|
Issue.listedMultipleTime(ruleID: duplicateRule.0, times: duplicateRule.1).print()
|
|
}
|
|
}
|
|
}
|
|
|
|
if enableAllRules {
|
|
self = .allCommandLine
|
|
} else if onlyRule.isNotEmpty {
|
|
self = .onlyCommandLine(Set(onlyRule))
|
|
} else if onlyRules.isNotEmpty {
|
|
if disabledRules.isNotEmpty || optInRules.isNotEmpty {
|
|
throw Issue.genericWarning(
|
|
"'\(Configuration.Key.disabledRules.rawValue)' or " +
|
|
"'\(Configuration.Key.optInRules.rawValue)' cannot be used in combination " +
|
|
"with '\(Configuration.Key.onlyRules.rawValue)'"
|
|
)
|
|
}
|
|
|
|
warnAboutDuplicates(in: onlyRules + analyzerRules)
|
|
self = .onlyConfiguration(Set(onlyRules + analyzerRules))
|
|
} else {
|
|
warnAboutDuplicates(in: disabledRules)
|
|
|
|
let effectiveOptInRules: [String]
|
|
if optInRules.contains(RuleIdentifier.all.stringRepresentation) {
|
|
let allOptInRules = RuleRegistry.shared.list.list.compactMap { ruleID, ruleType in
|
|
ruleType is any OptInRule.Type && !(ruleType is any AnalyzerRule.Type) ? ruleID : nil
|
|
}
|
|
effectiveOptInRules = Array(Set(allOptInRules + optInRules))
|
|
} else {
|
|
effectiveOptInRules = optInRules
|
|
}
|
|
|
|
let effectiveAnalyzerRules: [String]
|
|
if analyzerRules.contains(RuleIdentifier.all.stringRepresentation) {
|
|
let allAnalyzerRules = RuleRegistry.shared.list.list.compactMap { ruleID, ruleType in
|
|
ruleType is any AnalyzerRule.Type ? ruleID : nil
|
|
}
|
|
effectiveAnalyzerRules = allAnalyzerRules
|
|
} else {
|
|
effectiveAnalyzerRules = analyzerRules
|
|
}
|
|
|
|
warnAboutDuplicates(in: effectiveOptInRules + effectiveAnalyzerRules)
|
|
self = .defaultConfiguration(
|
|
disabled: Set(disabledRules), optIn: Set(effectiveOptInRules + effectiveAnalyzerRules)
|
|
)
|
|
}
|
|
}
|
|
|
|
internal func applied(aliasResolver: (String) -> String) -> Self {
|
|
switch self {
|
|
case let .defaultConfiguration(disabled, optIn):
|
|
return .defaultConfiguration(
|
|
disabled: Set(disabled.map(aliasResolver)),
|
|
optIn: Set(optIn.map(aliasResolver))
|
|
)
|
|
|
|
case let .onlyConfiguration(onlyRules):
|
|
return .onlyConfiguration(Set(onlyRules.map(aliasResolver)))
|
|
|
|
case let .onlyCommandLine(onlyRules):
|
|
return .onlyCommandLine(Set(onlyRules.map(aliasResolver)))
|
|
|
|
case .allCommandLine:
|
|
return .allCommandLine
|
|
}
|
|
}
|
|
|
|
internal func activateCustomRuleIdentifiers(allRulesWrapped: [ConfigurationRuleWrapper]) -> Self {
|
|
// In the only mode, if the custom rules rule is enabled, all custom rules are also enabled implicitly
|
|
// This method makes the implicitly explicit
|
|
switch self {
|
|
case let .onlyConfiguration(onlyRules) where onlyRules.contains {
|
|
$0 == CustomRules.identifier
|
|
}:
|
|
let customRulesRule = allRulesWrapped.customRules
|
|
return .onlyConfiguration(onlyRules.union(Set(customRulesRule?.customRuleIdentifiers ?? [])))
|
|
|
|
default:
|
|
return self
|
|
}
|
|
}
|
|
}
|
|
}
|