Merge pull request #77 from ConfusedVorlon/find_hidden_modifier
Find hidden modifier
This commit is contained in:
@@ -227,7 +227,7 @@ We provide `find()` for recursive listing:
|
|||||||
|
|
||||||
```swift
|
```swift
|
||||||
for path in Path.home.find() {
|
for path in Path.home.find() {
|
||||||
// descends all directories, and includes hidden files
|
// descends all directories, and includes hidden files by default
|
||||||
// so it behaves the same as the terminal command `find`
|
// so it behaves the same as the terminal command `find`
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -235,7 +235,7 @@ for path in Path.home.find() {
|
|||||||
It is configurable:
|
It is configurable:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
for path in Path.home.find().depth(max: 1).extension("swift").type(.file) {
|
for path in Path.home.find().depth(max: 1).extension("swift").type(.file).hidden(false) {
|
||||||
//…
|
//…
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ public extension Path {
|
|||||||
|
|
||||||
/// The file extensions find operations will return. Files *and* directories unless you filter for `kinds`.
|
/// The file extensions find operations will return. Files *and* directories unless you filter for `kinds`.
|
||||||
private(set) public var extensions: Set<String>?
|
private(set) public var extensions: Set<String>?
|
||||||
|
|
||||||
|
/// Whether to return hidden files
|
||||||
|
public var hidden:Bool = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,8 +53,12 @@ extension Path.Finder: Sequence, IteratorProtocol {
|
|||||||
if enumerator.level < depth.lowerBound {
|
if enumerator.level < depth.lowerBound {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !hidden, path.basename().hasPrefix(".") {
|
||||||
|
enumerator.skipDescendants()
|
||||||
|
continue
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if let type = path.type, !types.contains(type) { continue }
|
if let type = path.type, !types.contains(type) { continue }
|
||||||
if let exts = extensions, !exts.contains(path.extension) { continue }
|
if let exts = extensions, !exts.contains(path.extension) { continue }
|
||||||
return path
|
return path
|
||||||
@@ -114,6 +121,15 @@ public extension Path.Finder {
|
|||||||
extensions!.insert(ext)
|
extensions!.insert(ext)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whether to skip hidden files and folders.
|
||||||
|
func hidden(_ hidden: Bool) -> Path.Finder {
|
||||||
|
#if os(Linux) && !swift(>=5.0)
|
||||||
|
fputs("warning: hidden not implemented for Swift < 5\n", stderr)
|
||||||
|
#endif
|
||||||
|
self.hidden = hidden
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
|
||||||
/// The return type for `Path.Finder`
|
/// The return type for `Path.Finder`
|
||||||
enum ControlFlow {
|
enum ControlFlow {
|
||||||
|
|||||||
@@ -136,6 +136,28 @@ extension PathTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testFindHidden() throws {
|
||||||
|
try Path.mktemp { tmpdir in
|
||||||
|
let dotFoo = try tmpdir.join(".foo.txt").touch()
|
||||||
|
let tmpDotA = try tmpdir.join(".a").mkdir()
|
||||||
|
let tmpDotAFoo = try tmpdir.join(".a").join("foo.txt").touch()
|
||||||
|
let tmpB = try tmpdir.b.mkdir()
|
||||||
|
let tmpBFoo = try tmpdir.b.join("foo.txt").touch()
|
||||||
|
|
||||||
|
XCTAssertEqual(
|
||||||
|
Set(tmpdir.find().hidden(true)),
|
||||||
|
Set([dotFoo,tmpDotA,tmpDotAFoo,tmpB,tmpBFoo]),
|
||||||
|
relativeTo: tmpdir)
|
||||||
|
|
||||||
|
#if !os(Linux) || swift(>=5)
|
||||||
|
XCTAssertEqual(
|
||||||
|
Set(tmpdir.find().hidden(false)),
|
||||||
|
Set([tmpB,tmpBFoo]),
|
||||||
|
relativeTo: tmpdir)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func testFindExtension() throws {
|
func testFindExtension() throws {
|
||||||
try Path.mktemp { tmpdir in
|
try Path.mktemp { tmpdir in
|
||||||
try tmpdir.join("foo.json").touch()
|
try tmpdir.join("foo.json").touch()
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ extension PathTests {
|
|||||||
("testFindDepthRange", testFindDepthRange),
|
("testFindDepthRange", testFindDepthRange),
|
||||||
("testFindExecute", testFindExecute),
|
("testFindExecute", testFindExecute),
|
||||||
("testFindExtension", testFindExtension),
|
("testFindExtension", testFindExtension),
|
||||||
|
("testFindHidden", testFindHidden),
|
||||||
("testFindMaxDepth1", testFindMaxDepth1),
|
("testFindMaxDepth1", testFindMaxDepth1),
|
||||||
("testFindMaxDepth2", testFindMaxDepth2),
|
("testFindMaxDepth2", testFindMaxDepth2),
|
||||||
("testFindMinDepth", testFindMinDepth),
|
("testFindMinDepth", testFindMinDepth),
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ private func logic<P: Pathish>(_ set1: Set<Path>, _ set2: Set<Path>, relativeTo:
|
|||||||
if set1 != set2 {
|
if set1 != set2 {
|
||||||
let cvt: (Path) -> String = { $0.relative(to: relativeTo) }
|
let cvt: (Path) -> String = { $0.relative(to: relativeTo) }
|
||||||
let out1 = set1.map(cvt).sorted()
|
let out1 = set1.map(cvt).sorted()
|
||||||
let out2 = set1.map(cvt).sorted()
|
let out2 = set2.map(cvt).sorted()
|
||||||
fail("Set(\(out1)) is not equal to Set(\(out2))")
|
fail("Set(\(out1)) is not equal to Set(\(out2))")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user