Skip to content

Commit 9396a0a

Browse files
Bruschidy54jpsim
authored andcommitted
Fix bug where nested configuration excluded files are ignored (#2648)
Fixes #2447 When SwiftLint is linting files in `visitLintableFiles` in `Configuration+CommandLine`, it: 1. Gathers all lintable files in `getFiles`. This is where the exclusion of files occurs based on the parent configuration's exclusion list. 2. These files are grouped by their specific configuration in `groupFiles`. This is where configurations for each available file are determined (and if nested configurations exist, merged). After these configurations are determined and the files are grouped accordingly, no more files are excluded from the lintable files list. Even though a file's configuration thinks it should be excluded, these files are not removed from the list of lintable files, generating the bug. 3. Finally, each file is visited by the linter. My solution is to skip files whose merged configurations specify they should be excluded in step 2 or `groupFiles`. Therefore, they will not be visited in step 3.
1 parent 834df26 commit 9396a0a

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@
121121

122122
#### Bug Fixes
123123

124+
* Fix bug where SwiftLint ignores excluded files list in a nested configuration file.
125+
[Dylan Bruschi](https://github.com/Bruschidy54)
126+
[#2447](https://github.com/realm/SwiftLint/issues/2447)
127+
124128
* Fix false positives on `no_grouping_extension` rule when using `where`
125129
clause.
126130
[Almaz Ibragimov](https://github.com/almazrafi)

Source/swiftlint/Extensions/Configuration+CommandLine.swift

+23-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,29 @@ extension Configuration {
6161
let errorMessage = "No lintable files found at paths: '\(visitor.paths.joined(separator: ", "))'"
6262
return .failure(.usageError(description: errorMessage))
6363
}
64-
return .success(Dictionary(grouping: files, by: configuration(for:)))
64+
65+
var groupedFiles = [Configuration: [File]]()
66+
for file in files {
67+
// Files whose configuration specifies they should be excluded will be skipped
68+
let fileConfiguration = configuration(for: file)
69+
let excludedPaths = fileConfiguration.excluded
70+
.map { (fileConfiguration.rootPath ?? "").bridge().appendingPathComponent($0) }
71+
72+
let shouldSkip: Bool = excludedPaths.contains {
73+
file.path?.bridge().pathComponents.starts(with: $0.bridge().pathComponents) ?? false
74+
}
75+
76+
if !shouldSkip {
77+
if var configuredFiles = groupedFiles[fileConfiguration] {
78+
configuredFiles.append(file)
79+
groupedFiles[fileConfiguration] = configuredFiles
80+
} else {
81+
groupedFiles[fileConfiguration] = [file]
82+
}
83+
}
84+
}
85+
86+
return .success(groupedFiles)
6587
}
6688

6789
private func visit(filesPerConfiguration: [Configuration: [File]],

0 commit comments

Comments
 (0)