diff --git a/Sources/Path+ls.swift b/Sources/Path+ls.swift index 0b627a3..6b3bef6 100644 --- a/Sources/Path+ls.swift +++ b/Sources/Path+ls.swift @@ -5,7 +5,7 @@ public extension Path { class Finder { fileprivate init(path: Path) { self.path = path - self.enumerator = FileManager.default.enumerator(atPath: path.string) + self.enumerator = FileManager.default.enumerator(at: path.url, includingPropertiesForKeys: [.isDirectoryKey]) } /// The `path` find operations operate on. @@ -42,8 +42,8 @@ extension Path.Finder: Sequence, IteratorProtocol { guard let enumerator = enumerator else { return nil } - while let relativePath = enumerator.nextObject() as? String { - let path = self.path/relativePath + while let url = enumerator.nextObject() as? URL { + guard let path = Path(url: url) else { continue } #if !os(Linux) || swift(>=5.0) if enumerator.level > depth.upperBound { @@ -55,7 +55,9 @@ extension Path.Finder: Sequence, IteratorProtocol { } if !hidden, path.basename().hasPrefix(".") { - enumerator.skipDescendants() + if url.isDirectory { + enumerator.skipDescendants() + } continue } #endif @@ -217,3 +219,9 @@ public enum ListDirectoryOptions { /// Lists hidden files also case a } + +private extension URL { + var isDirectory: Bool { + return (try? resourceValues(forKeys: [.isDirectoryKey]))?.isDirectory == true + } +} diff --git a/Tests/PathTests/PathTests+ls().swift b/Tests/PathTests/PathTests+ls().swift index 58072d3..06e19b8 100644 --- a/Tests/PathTests/PathTests+ls().swift +++ b/Tests/PathTests/PathTests+ls().swift @@ -157,6 +157,31 @@ extension PathTests { #endif } } + + func testFindHiddenFileAlongsideDirectory() 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 tmpB.join("foo.txt").touch() + let dotBar = try tmpB.join(".bar.txt").touch() + let tmpC = try tmpdir.b.c.mkdir() + let bar = try tmpC.join("bar.txt").touch() + + XCTAssertEqual( + Set(tmpdir.find().hidden(true)), + Set([dotFoo,tmpDotA,tmpDotAFoo,tmpB,tmpBFoo,tmpC,dotBar,bar]), + relativeTo: tmpdir) + + #if !os(Linux) || swift(>=5) + XCTAssertEqual( + Set(tmpdir.find().hidden(false)), + Set([tmpB,tmpBFoo,tmpC,bar]), + relativeTo: tmpdir) + #endif + } + } func testFindExtension() throws { try Path.mktemp { tmpdir in