-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix superfluous disable command for custom_rules
#5670
Fix superfluous disable command for custom_rules
#5670
Conversation
Generated by 🚫 Danger |
8c02874
to
15da439
Compare
1cae064
to
44af4af
Compare
1d55b97
to
d37875b
Compare
custom_rules
776cd9d
to
88051e0
Compare
cb3a854
to
11e4322
Compare
4e95358
to
36d4ca6
Compare
cf7183c
to
0cdf41e
Compare
@@ -46,7 +46,10 @@ public struct Region: Equatable { | |||
/// | |||
/// - returns: True if the specified rule is disabled in this region. | |||
public func isRuleDisabled(_ rule: some Rule) -> Bool { | |||
areRulesDisabled(ruleIDs: type(of: rule).description.allIdentifiers) | |||
if let rule = rule as? CustomRules { | |||
return areRulesDisabled(ruleIDs: rule.customRuleIdentifiers + [type(of: rule).description.identifier]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this mean a custom rule custom_1
will be disabled if custom_2
is actually named in the disable command? rule.customRuleIdentifiers
are all custom identifiers defined, aren't they?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this specific function will return true
in that case, yes, but the actual identifiers will be checked afterwards, here in the construction of identifiersWithRegions
func superfluousDisableCommandViolations(regions: [Region],
superfluousDisableCommandRule: SuperfluousDisableCommandRule?,
allViolations: [StyleViolation]) -> [StyleViolation] {
guard regions.isNotEmpty, let superfluousDisableCommandRule else {
return []
}
let regionsDisablingSuperfluousDisableRule = regions.filter { region in
region.isRuleDisabled(superfluousDisableCommandRule)
}
let identifiersWithRegions: [(String, [Region])] = {
The proof of the pudding 🤞 is (slightly expanded for clarity):
func testUnviolatedSpecificCustomRulesTriggersSuperfluousDisableCommand() throws {
let customRules = [
"forbidden": [
"regex": "FORBIDDEN",
],
"forbidden2": [
"regex": "FORBIDDEN2",
],
]
let example = Example("""
// swiftlint:disable:next forbidden forbidden2
let FORBIDDEN = 1
""")
let violations = try self.violations(forExample: example, customRules: customRules)
XCTAssertEqual(violations.count, 1)
XCTAssertTrue(violations[0].isSuperfluousDisableCommandViolation(for: "forbidden2"))
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if a naming change might make this clearer, but I don't have a good candidate ...
0cdf41e
to
94488d7
Compare
I still have my concerns with the special handling of custom rules and some improvement ideas in my backlog. Do you mind if I push some changes to your branch later? |
ea19066
to
db114fb
Compare
Yes, I think there are still some oddities outside of superfluous_disable Feel free to add more changes! |
I managed to avoid explicit type checks at a few places. There are more in other (untouched) code, though, that we should get rid of in the long run. Please check if my changes make sense to you, @mildm8nnered. |
} | ||
|
||
let customRulesIDs: [String] = { | ||
guard let customRules = self as? CustomRules else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we could get rid of this by letting Self.description.allIdentifiers
contain the custom IDs in case of custom rules.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't see an easy way to customize allIdentifiers
, as the RuleDescription currently can't see the configuration :-(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, also what I struggled with. We'd need to move allIdentifiers
into Rule
, but this has other disadvantages. So let's not bother with that in this PR. I think it's good as it is. The special handling of custom rules is a broader topic we may address in follow-ups.
So it may take me a while to digest those, but straight away it looks a lot shorter and cleaner. One change request - I think you should add yourself to the authors in the changelog. |
Co-authored-by: Danny Mösch <[email protected]>
7abd386
to
17eb866
Compare
I think your changes look great @SimplyDanny. Am I ok to hit merge on this? Hopefully we'll do better than #4755 🤞 |
Oh, I misread this as a statement. Just merged it. 🫣
People will let us know ... 😅 |
So this is a kind of scary PR - addresses #4754 - The
superfluous_disable_command
rule should work for individualcustom_rules
.#4755 attempted to address this, but had issues, and was reverted in #5336
This PR is based on @marcelofabri 's work in #4755 with a few additional fixes.
A fair few times I thought I had this cracked, only to find a big hole. I think it's right now, but this PR definitely deserves additional scrutiny.
Consider the example below:
The following code should trigger a
superfluous_disable_command
violation:Today this would produce:
and after this PR is applied, we get:
It is currently also possible to disable all custom rules with:
That behaviour is still supported.