@@ -10,12 +10,15 @@ import Darwin
1010/// - path: the path whose children will be returned.
1111/// - recursive: set to `true` to include results from child directories in addition to that from `path`.
1212/// Defaults to `false`.
13+ /// - followSymlink: include content of a directroy, if it's pointed at by a symlink in the result.
1314///
1415/// - Returns: path to directories and files of all types in `path`, and their types, in pairs.
1516/// - Throws: A `SystemError` if path cannot be opened as a directory or there's not enough memory to hold all
1617/// data for the results.
1718/// - SeeAlso: To work with `Path` or `PathRepresentable`, use `PathRepresentable.children(recursive:)`.
18- public func children( inPath path: String , recursive: Bool = false ) throws -> [ ( String , FileType ) ] {
19+ public func children( inPath path: String , recursive: Bool = false , followSymlink: Bool = false ) throws
20+ -> [ ( String , FileType ) ]
21+ {
1922 var result = [ ( String, FileType) ] ( )
2023 guard let streamPtr = opendir ( path) else {
2124 throw SystemError ( posixErrorCode: errno)
@@ -40,7 +43,13 @@ public func children(inPath path: String, recursive: Bool = false) throws -> [(S
4043 let fullName = join ( paths: path, name)
4144 result. append ( ( fullName, pathType) )
4245
43- if recursive && pathType == . directory {
46+ if pathType == . symlink,
47+ followSymlink,
48+ let realName = try ? realPath ( ofPath: fullName) ,
49+ ( try ? isA ( . directory, atPath: realName) ) == true
50+ {
51+ result += try children ( inPath: fullName, recursive: true )
52+ } else if recursive && pathType == . directory {
4453 result += try children ( inPath: fullName, recursive: true )
4554 }
4655 }
@@ -72,13 +81,15 @@ extension PathRepresentable {
7281 /// Result will be empty if this path cannot be opened or there's not enough memory to hold all data for
7382 /// the results.
7483 ///
75- /// - Parameter recursive: set to `true` to include results from child directories in addition to that
76- /// in this path. Defaults to `false`.
84+ /// - Parameters:
85+ /// - recursive: set to `true` to include results from child directories in addition to that
86+ /// in this path. Defaults to `false`.
87+ /// - followSymlink: include content of a directroy, if it's pointed at by a symlink in the result.
7788 ///
7889 /// - Returns: paths to directories and files of all types in `path`, and their types, in pairs.
7990 /// - SeeAlso: `children(inPath:recursive:)`.
80- public func children( recursive: Bool = false ) -> [ ( Self , FileType ) ] {
81- return ( ( try ? children ( inPath: recursive: ) ( self . pathString, recursive) ) ?? [ ] )
91+ public func children( recursive: Bool = false , followSymlink : Bool = false ) -> [ ( Self , FileType ) ] {
92+ return ( ( try ? children ( inPath: recursive: followSymlink : ) ( self . pathString, recursive, followSymlink ) ) ?? [ ] )
8293 . map { ( . init( $0) , $1) }
8394 }
8495
@@ -87,15 +98,18 @@ extension PathRepresentable {
8798 /// Result will be empty if this path cannot be opened or there's not enough memory to hold all data for
8899 /// the results.
89100 ///
90- /// - Parameters
101+ /// - Parameters:
91102 /// - type: The file type in question.
92103 /// - recursive: set to `true` to include results from child directories in addition to that
93104 /// in this path. Defaults to `false`.
105+ /// - followSymlink: include content of a directroy, if it's pointed at by a symlink in the result.
94106 ///
95107 /// - Returns: paths to directories and files of all types in `path`, and their types, in pairs.
96108 /// - SeeAlso: `children(inPath:recursive:)`.
97- public func children( ofType type: FileType , recursive: Bool = false ) -> [ Self ] {
98- return ( ( try ? children ( inPath: recursive: ) ( self . pathString, recursive) ) ?? [ ] )
109+ public func children( ofType type: FileType , recursive: Bool = false , followSymlink: Bool = false )
110+ -> [ Self ]
111+ {
112+ return ( ( try ? children ( inPath: recursive: followSymlink: ) ( self . pathString, recursive, followSymlink) ) ?? [ ] )
99113 . filter { $1 == type }
100114 . map { . init( $0. 0 ) }
101115 }
0 commit comments