Skip to content

Commit ba4f3cd

Browse files
authored
Merge pull request #31 from Flinesoft/wip/cg_repeat
Add new repeatIfAutoCorrected option
2 parents 75681be + e783908 commit ba4f3cd

File tree

5 files changed

+100
-8
lines changed

5 files changed

+100
-8
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ If needed, pluralize to `Tasks`, `PRs` or `Authors` and list multiple entries se
1919

2020
## [Unreleased]
2121
### Added
22-
- None.
22+
- Added new `repeatIfAutoCorrected` option to `checkFileContents` method to repeat the check if last run did any auto-corrections.
23+
Issue: [#29](https://github.com/Flinesoft/AnyLint/issues/29) | PR: [#31](https://github.com/Flinesoft/AnyLint/pull/31) | Author: [Cihat Gündüz](https://github.com/Jeehut)
2324
### Changed
2425
- None.
2526
### Deprecated

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ There's 3 more parameters you can optionally set if needed:
277277
1. `excludeFilters`: Array of `Regex` objects to exclude from the file paths to check.
278278
2. `autoCorrectReplacement`: Replacement string which can reference any capture groups in the `regex`.
279279
3. `autoCorrectExamples`: Example structs with `before` and `after` for autocorrection validation.
280+
4. `repeatIfAutoCorrected`: Repeat check if at least one auto-correction was applied in last run. Defaults to `false`.
280281

281282
The `excludeFilters` can be used alternatively to the `includeFilters` or alongside them. If used alongside, exclusion will take precedence over inclusion.
282283

Sources/AnyLint/Checkers/FileContentsChecker.swift

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ struct FileContentsChecker {
66
let regex: Regex
77
let filePathsToCheck: [String]
88
let autoCorrectReplacement: String?
9+
let repeatIfAutoCorrected: Bool
910
}
1011

1112
extension FileContentsChecker: Checker {
@@ -85,6 +86,24 @@ extension FileContentsChecker: Checker {
8586
Statistics.shared.checkedFiles(at: [filePath])
8687
}
8788

88-
return violations.reversed()
89+
violations = violations.reversed()
90+
91+
if repeatIfAutoCorrected && violations.contains(where: { $0.appliedAutoCorrection != nil }) {
92+
log.message("Repeating check \(checkInfo) because auto-corrections were applied on last run.", level: .debug)
93+
94+
// only paths where auto-corrections were applied need to be re-checked
95+
let filePathsToReCheck = Array(Set(violations.filter { $0.appliedAutoCorrection != nil }.map { $0.filePath! })).sorted()
96+
97+
let violationsOnRechecks = try FileContentsChecker(
98+
checkInfo: checkInfo,
99+
regex: regex,
100+
filePathsToCheck: filePathsToReCheck,
101+
autoCorrectReplacement: autoCorrectReplacement,
102+
repeatIfAutoCorrected: repeatIfAutoCorrected
103+
).performCheck()
104+
violations.append(contentsOf: violationsOnRechecks)
105+
}
106+
107+
return violations
89108
}
90109
}

Sources/AnyLint/Lint.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public enum Lint {
1414
/// - excludeFilters: An array of regexes defining which files should be excluded from the check. Will ignore all files matching any of the given regexes. Takes precedence over includes.
1515
/// - autoCorrectReplacement: A replacement string which can reference any capture groups in the `regex` to use for autocorrection.
1616
/// - autoCorrectExamples: An array of example structs with a `before` and an `after` String object to check if autocorrection works properly.
17+
/// - repeatIfAutoCorrected: Repeat check if at least one auto-correction was applied in last run. Defaults to `false`.
1718
public static func checkFileContents(
1819
checkInfo: CheckInfo,
1920
regex: Regex,
@@ -22,7 +23,8 @@ public enum Lint {
2223
includeFilters: [Regex] = [#".*"#],
2324
excludeFilters: [Regex] = [],
2425
autoCorrectReplacement: String? = nil,
25-
autoCorrectExamples: [AutoCorrection] = []
26+
autoCorrectExamples: [AutoCorrection] = [],
27+
repeatIfAutoCorrected: Bool = false
2628
) throws {
2729
validate(regex: regex, matchesForEach: matchingExamples, checkInfo: checkInfo)
2830
validate(regex: regex, doesNotMatchAny: nonMatchingExamples, checkInfo: checkInfo)
@@ -58,7 +60,8 @@ public enum Lint {
5860
checkInfo: checkInfo,
5961
regex: regex,
6062
filePathsToCheck: filePathsToCheck,
61-
autoCorrectReplacement: autoCorrectReplacement
63+
autoCorrectReplacement: autoCorrectReplacement,
64+
repeatIfAutoCorrected: repeatIfAutoCorrected
6265
).performCheck()
6366

6467
Statistics.shared.found(violations: violations, in: checkInfo)

Tests/AnyLintTests/Checkers/FileContentsCheckerTests.swift

Lines changed: 72 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
@testable import Utility
33
import XCTest
44

5+
// swiftlint:disable function_body_length
6+
57
final class FileContentsCheckerTests: XCTestCase {
68
override func setUp() {
79
log = Logger(outputType: .test)
@@ -20,7 +22,8 @@ final class FileContentsCheckerTests: XCTestCase {
2022
checkInfo: checkInfo,
2123
regex: #"(let|var) \w+=\w+"#,
2224
filePathsToCheck: filePathsToCheck,
23-
autoCorrectReplacement: nil
25+
autoCorrectReplacement: nil,
26+
repeatIfAutoCorrected: false
2427
).performCheck()
2528

2629
XCTAssertEqual(violations.count, 2)
@@ -50,7 +53,8 @@ final class FileContentsCheckerTests: XCTestCase {
5053
checkInfo: checkInfo,
5154
regex: #"(let|var) \w+=\w+"#,
5255
filePathsToCheck: filePathsToCheck,
53-
autoCorrectReplacement: nil
56+
autoCorrectReplacement: nil,
57+
repeatIfAutoCorrected: false
5458
).performCheck()
5559

5660
XCTAssertEqual(violations.count, 2)
@@ -81,7 +85,8 @@ final class FileContentsCheckerTests: XCTestCase {
8185
checkInfo: checkInfo,
8286
regex: #"(let|var) \w+=\w+"#,
8387
filePathsToCheck: filePathsToCheck,
84-
autoCorrectReplacement: nil
88+
autoCorrectReplacement: nil,
89+
repeatIfAutoCorrected: false
8590
).performCheck()
8691

8792
XCTAssertEqual(violations.count, 6)
@@ -130,7 +135,8 @@ final class FileContentsCheckerTests: XCTestCase {
130135
checkInfo: checkInfo,
131136
regex: #"(let|var) (\w+)\s*=\s*(\w+)"#,
132137
filePathsToCheck: filePathsToCheck,
133-
autoCorrectReplacement: "$1 $2 = $3"
138+
autoCorrectReplacement: "$1 $2 = $3",
139+
repeatIfAutoCorrected: false
134140
).performCheck()
135141

136142
XCTAssertEqual(violations.count, 2)
@@ -146,4 +152,66 @@ final class FileContentsCheckerTests: XCTestCase {
146152
XCTAssertEqual(violations[1].locationInfo!.charInLine, 1)
147153
}
148154
}
155+
156+
func testRepeatIfAutoCorrected() {
157+
let temporaryFiles: [TemporaryFile] = [
158+
(subpath: "Sources/Hello.swift", contents: "let x = 500\nvar y = 10000"),
159+
(subpath: "Sources/World.swift", contents: "let x = 50000000\nvar y = 100000000000000"),
160+
]
161+
162+
withTemporaryFiles(temporaryFiles) { filePathsToCheck in
163+
let checkInfo = CheckInfo(id: "LongNumbers", hint: "Format long numbers with `_` after each triple of digits from the right.", severity: .warning)
164+
let violations = try FileContentsChecker(
165+
checkInfo: checkInfo,
166+
regex: #"(?<!\d)(\d+)(\d{3})(?!\d)"#,
167+
filePathsToCheck: filePathsToCheck,
168+
autoCorrectReplacement: "$1_$2",
169+
repeatIfAutoCorrected: true
170+
).performCheck()
171+
172+
XCTAssertEqual(violations.count, 7)
173+
174+
XCTAssertEqual(violations[0].checkInfo, checkInfo)
175+
XCTAssertEqual(violations[0].filePath, "\(tempDir)/Sources/Hello.swift")
176+
XCTAssertEqual(violations[0].locationInfo!.line, 2)
177+
XCTAssertEqual(violations[0].locationInfo!.charInLine, 9)
178+
XCTAssertEqual(violations[0].appliedAutoCorrection!.after, "10_000")
179+
180+
XCTAssertEqual(violations[1].checkInfo, checkInfo)
181+
XCTAssertEqual(violations[1].filePath, "\(tempDir)/Sources/World.swift")
182+
XCTAssertEqual(violations[1].locationInfo!.line, 1)
183+
XCTAssertEqual(violations[1].locationInfo!.charInLine, 9)
184+
XCTAssertEqual(violations[1].appliedAutoCorrection!.after, "50000_000")
185+
186+
XCTAssertEqual(violations[2].checkInfo, checkInfo)
187+
XCTAssertEqual(violations[2].filePath, "\(tempDir)/Sources/World.swift")
188+
XCTAssertEqual(violations[2].locationInfo!.line, 2)
189+
XCTAssertEqual(violations[2].locationInfo!.charInLine, 9)
190+
XCTAssertEqual(violations[2].appliedAutoCorrection!.after, "100000000000_000")
191+
192+
XCTAssertEqual(violations[3].checkInfo, checkInfo)
193+
XCTAssertEqual(violations[3].filePath, "\(tempDir)/Sources/World.swift")
194+
XCTAssertEqual(violations[3].locationInfo!.line, 1)
195+
XCTAssertEqual(violations[3].locationInfo!.charInLine, 9)
196+
XCTAssertEqual(violations[3].appliedAutoCorrection!.after, "50_000")
197+
198+
XCTAssertEqual(violations[4].checkInfo, checkInfo)
199+
XCTAssertEqual(violations[4].filePath, "\(tempDir)/Sources/World.swift")
200+
XCTAssertEqual(violations[4].locationInfo!.line, 2)
201+
XCTAssertEqual(violations[4].locationInfo!.charInLine, 9)
202+
XCTAssertEqual(violations[4].appliedAutoCorrection!.after, "100000000_000")
203+
204+
XCTAssertEqual(violations[5].checkInfo, checkInfo)
205+
XCTAssertEqual(violations[5].filePath, "\(tempDir)/Sources/World.swift")
206+
XCTAssertEqual(violations[5].locationInfo!.line, 2)
207+
XCTAssertEqual(violations[5].locationInfo!.charInLine, 9)
208+
XCTAssertEqual(violations[5].appliedAutoCorrection!.after, "100000_000")
209+
210+
XCTAssertEqual(violations[6].checkInfo, checkInfo)
211+
XCTAssertEqual(violations[6].filePath, "\(tempDir)/Sources/World.swift")
212+
XCTAssertEqual(violations[6].locationInfo!.line, 2)
213+
XCTAssertEqual(violations[6].locationInfo!.charInLine, 9)
214+
XCTAssertEqual(violations[6].appliedAutoCorrection!.after, "100_000")
215+
}
216+
}
149217
}

0 commit comments

Comments
 (0)