Exclude items by shell pattern as well as by name
Docs / docs (push) Canceled after 0s
Docs / deploy (push) Canceled after 0s

Patterns such as `.*` or `@*` are matched against an item's own name
with `fnmatch`, in the same places as excluded names: resolving a
tree, extending a watch to a directory that appears later, and
delivering events. Dependents that prune large trees can now skip
whole families of directories without listing each name.
This commit is contained in:
T. R. Bernstein
2026-09-16 11:21:45 +02:00
parent 442053eae2
commit 8af25be549
10 changed files with 154 additions and 22 deletions
@@ -39,6 +39,44 @@ struct RecursiveEventTests {
}
}
@Test func ignoresFileCreationInASubfolderMatchingAnExcludedPattern() async throws {
try await withTempDir { dir in
let subDirectory = "\(dir)/@eaDir"
let filepath = "\(subDirectory)/modify-target.txt"
try FileManager.default.createDirectory(atPath: subDirectory, withIntermediateDirectories: true)
let events = try await getEventsForTrigger(
in: dir,
mask: [.create],
recursive: .recursive,
excludePatterns: ["@*"]
) { _ in try createFile(at: "\(filepath)", contents: "hello") }
let createEvent = events.first { $0.mask.contains(.create) && $0.path.string == filepath }
#expect(createEvent == nil, "Did not expect CREATE for '\(filepath)', got: \(events)")
}
}
@Test func doesNotWatchANewSubfolderMatchingAnExcludedPattern() async throws {
try await withTempDir { dir in
let subDirectory = "\(dir)/@eaDir"
let filepath = "\(subDirectory)/modify-target.txt"
let events = try await getEventsForTrigger(
in: dir,
mask: [.create],
recursive: .withAutomaticSubtreeWatching,
excludePatterns: ["@*"]
) { _ in
try FileManager.default.createDirectory(atPath: subDirectory, withIntermediateDirectories: true)
try await Task.sleep(for: .milliseconds(400))
try createFile(at: "\(filepath)", contents: "hello")
}
#expect(events.isEmpty, "Did not expect any event, got: \(events)")
}
}
@Test func newSubfoldersOfRecursiveWatchAreAutomaticallyWatchedToo() async throws {
try await withTempDir { dir in
let subDirectory = "\(dir)/Subfolder"