Exclude items by shell pattern as well as by name
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:
@@ -0,0 +1,33 @@
|
||||
#if canImport(Musl)
|
||||
import Musl
|
||||
#else
|
||||
import Glibc
|
||||
#endif
|
||||
|
||||
/// The item names an ``Inotify`` instance skips: exact names and shell
|
||||
/// patterns, both matched against an item's own name.
|
||||
struct ExclusionList: Sendable {
|
||||
private var names: Set<String> = []
|
||||
private var patterns: [String] = []
|
||||
|
||||
init(names: Set<String> = [], patterns: [String] = []) {
|
||||
self.names = names
|
||||
self.patterns = patterns
|
||||
}
|
||||
|
||||
mutating func add(name: String) {
|
||||
self.names.insert(name)
|
||||
}
|
||||
|
||||
mutating func add(pattern: String) {
|
||||
guard !self.patterns.contains(pattern) else { return }
|
||||
self.patterns.append(pattern)
|
||||
}
|
||||
|
||||
/// Patterns are matched as the shell matches file names: `*` and `?`
|
||||
/// stand for any characters, `[…]` for a set, and a leading dot needs
|
||||
/// no special treatment.
|
||||
func excludes(_ name: String) -> Bool {
|
||||
self.names.contains(name) || self.patterns.contains { fnmatch($0, name, 0) == 0 }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user