Skip to content

Commit

Permalink
Accept with files or folders as the last part of the pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
SimplyDanny committed Mar 22, 2024
1 parent dad51eb commit 61acd6d
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ extension Configuration {
#else
let result = NSMutableOrderedSet(array: allPaths)
#endif
let exclusionPatterns = self.excludedPaths.map { Glob.createFilenameMatcher(root: rootDirectory, pattern: $0) }
let exclusionPatterns = self.excludedPaths.flatMap {
Glob.createFilenameMatchers(root: rootDirectory, pattern: $0)
}
return result
.map { $0 as! String } // swiftlint:disable:this force_cast
.filter { !exclusionPatterns.anyMatch(filename: $0) }
Expand Down
23 changes: 17 additions & 6 deletions Source/SwiftLintCore/Helpers/Glob.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,26 @@ struct Glob {
.map { $0.absolutePathStandardized() }
}

static func createFilenameMatcher(root: String, pattern: String) -> FilenameMatcher {
var fullPattern = pattern
static func createFilenameMatchers(root: String, pattern: String) -> [FilenameMatcher] {
var absolutPathPattern = pattern
if !pattern.starts(with: root) {
fullPattern = root + (root.hasSuffix("/") ? "" : "/") + fullPattern
// If the root is not already part of the pattern, prepend it.
absolutPathPattern = root + (root.hasSuffix("/") ? "" : "/") + absolutPathPattern
}
if !pattern.hasSuffix(".swift"), !pattern.hasSuffix("/**") {
fullPattern += pattern.hasSuffix("/") ? "**" : "/**"
if pattern.hasSuffix(".swift") || pattern.hasSuffix("/**") {
// Suffix is already well defined.
return [FilenameMatcher(pattern: absolutPathPattern)]
}
return FilenameMatcher(pattern: fullPattern)
if pattern.hasSuffix("/") {
// Matching all files in the folder.
return [FilenameMatcher(pattern: absolutPathPattern + "**")]
}
// The pattern could match files in the last folder in the path or all contained files if the last component
// represents folders.
return [
FilenameMatcher(pattern: absolutPathPattern),
FilenameMatcher(pattern: absolutPathPattern + "/**")
]
}

// MARK: Private
Expand Down
47 changes: 34 additions & 13 deletions Tests/SwiftLintFrameworkTests/GlobTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,18 +83,39 @@ final class GlobTests: SwiftLintTestCase {
XCTAssertEqual(files.sorted(), expectedFiles.sorted())
}

func testCreateFilenameMatcher() {
XCTAssert(Glob.createFilenameMatcher(root: "/a/b/", pattern: "c/*.swift").match(filename: "/a/b/c/d.swift"))
XCTAssert(Glob.createFilenameMatcher(root: "/a", pattern: "**/*.swift").match(filename: "/a/b/c/d.swift"))
XCTAssert(Glob.createFilenameMatcher(root: "/a/b", pattern: "/a/b/c/*.swift").match(filename: "/a/b/c/d.swift"))
XCTAssert(Glob.createFilenameMatcher(root: "/a/", pattern: "/a/b/c/*.swift").match(filename: "/a/b/c/d.swift"))

XCTAssert(Glob.createFilenameMatcher(root: "", pattern: "/a/b/c").match(filename: "/a/b/c/d.swift"))
XCTAssert(Glob.createFilenameMatcher(root: "", pattern: "/a/b/c/").match(filename: "/a/b/c/d.swift"))
XCTAssert(Glob.createFilenameMatcher(root: "", pattern: "/a/b/c/*.swift").match(filename: "/a/b/c/d.swift"))
XCTAssert(Glob.createFilenameMatcher(root: "", pattern: "/d.swift/*.swift").match(filename: "/d.swift/e.swift"))
XCTAssert(Glob.createFilenameMatcher(root: "", pattern: "/a/**").match(filename: "/a/b/c/d.swift"))

XCTAssertFalse(Glob.createFilenameMatcher(root: "/a/", pattern: "**/*.swift").match(filename: "/a/b.swift"))
func testCreateFilenameMatchers() {
struct MatcherTest {
let root: String
let pattern: String
let filenames: [String]

func matchesAll() -> Bool {
filenames.allSatisfy { name in
Glob.createFilenameMatchers(root: root, pattern: pattern).anyMatch(filename: name)
}
}

func matchesNone() -> Bool {
filenames.allSatisfy { name in
!Glob.createFilenameMatchers(root: root, pattern: pattern).anyMatch(filename: name)
}
}
}

[
.init(root: "/a/b/", pattern: "c/*.swift", filenames: ["/a/b/c/d.swift"]),
.init(root: "/a", pattern: "**/*.swift", filenames: ["/a/b/c/d.swift"]),
.init(root: "/a/b", pattern: "/a/b/c/*.swift", filenames: ["/a/b/c/d.swift"]),
.init(root: "/a/", pattern: "/a/b/c/*.swift", filenames: ["/a/b/c/d.swift"]),

.init(root: "", pattern: "/a/b/c", filenames: ["/a/b/c/d.swift"]),
.init(root: "", pattern: "/a/b/c/", filenames: ["/a/b/c/d.swift"]),
.init(root: "", pattern: "/a/b/c/*.swift", filenames: ["/a/b/c/d.swift"]),
.init(root: "", pattern: "/d.swift/*.swift", filenames: ["/d.swift/e.swift"]),
.init(root: "", pattern: "/a/**", filenames: ["/a/b/c/d.swift"]),
.init(root: "", pattern: "**/*Test*", filenames: ["/a/b/c/MyTest2.swift", "/a/b/MyTests/c.swift"])
].forEach { (test: MatcherTest) in XCTAssert(test.matchesAll()) }

XCTAssert(MatcherTest(root: "/a/", pattern: "**/*.swift", filenames: ["/a/b.swift"]).matchesNone())
}
}

0 comments on commit 61acd6d

Please sign in to comment.