@@ -133,13 +133,16 @@ public struct PackageBuilder {
133133 /// The path of the package.
134134 private let packagePath : AbsolutePath
135135
136+ private let fileSystem : FileSystem
137+
136138 /// Create a builder for the given manifest and package `path`.
137139 ///
138140 /// - Parameters:
139141 /// - path: The root path of the package.
140142 public init ( manifest: Manifest , path: AbsolutePath ) {
141143 self . manifest = manifest
142144 self . packagePath = path
145+ self . fileSystem = localFileSystem
143146 }
144147
145148 /// Build a new package following the conventions.
@@ -168,9 +171,10 @@ public struct PackageBuilder {
168171 if path. basename. hasPrefix ( " . " ) { return false }
169172 if path == manifest. path { return false }
170173 if excludedPaths. contains ( path) { return false }
171- if !path. asString. isFile { return false }
172- guard let ext = path. asString. fileExt else { return false }
173- return validExtensions. contains ( ext)
174+ if !fileSystem. isFile ( path) { return false }
175+ guard let ext = path. suffix else { return false }
176+ // FIXME: This isn't efficient.
177+ return validExtensions. contains ( String ( ext. utf8. dropFirst ( ) ) )
174178 }
175179
176180 private func shouldConsiderDirectory( _ path: AbsolutePath ) -> Bool {
@@ -182,7 +186,7 @@ public struct PackageBuilder {
182186 if base. hasPrefix ( " . " ) { return false } // eg .git
183187 if excludedPaths. contains ( path) { return false }
184188 if path == packagesDirectory { return false }
185- if !path . asString . isDirectory { return false }
189+ if !fileSystem . isDirectory ( path ) { return false }
186190 return true
187191 }
188192
@@ -198,12 +202,29 @@ public struct PackageBuilder {
198202 guard let pkgConfig = manifest. package . pkgConfig else { return nil }
199203 return RelativePath ( pkgConfig)
200204 }
205+
206+ // FIXME: Should this be an extension on FileSystem and placed in Utility?
207+ /// Returns path to all the items in a directory.
208+ func directoryContents( _ path: AbsolutePath ) throws -> [ AbsolutePath ] {
209+ return try fileSystem. getDirectoryContents ( path) . map { path. appending ( component: $0) }
210+ }
211+
212+ // FIXME: Optimize.
213+ /// Returns path to all the items in a directory tree.
214+ func recursiveDirectoryContents( _ path: AbsolutePath , predicate: @noescape ( AbsolutePath ) -> Bool ) throws -> [ AbsolutePath ] {
215+ return try directoryContents ( path) . flatMap { ( entry) -> [ AbsolutePath ] in
216+ if predicate ( entry) {
217+ return try recursiveDirectoryContents ( entry, predicate: predicate)
218+ }
219+ return [ entry]
220+ }
221+ }
201222
202223 func sourceRoot( ) throws -> AbsolutePath {
203- let viableRoots = walk ( packagePath, recursively : false ) . filter { entry in
224+ let viableRoots = try directoryContents ( packagePath) . filter { entry in
204225 switch entry. basename. lowercased ( ) {
205226 case " sources " , " source " , " src " , " srcs " :
206- return entry . asString . isDirectory && !excludedPaths. contains ( entry)
227+ return fileSystem . isDirectory ( entry ) && !excludedPaths. contains ( entry)
207228 default :
208229 return false
209230 }
@@ -223,7 +244,7 @@ public struct PackageBuilder {
223244 /// Collects the modules which are defined by a package.
224245 private func constructModules( ) throws -> [ Module ] {
225246 let moduleMapPath = packagePath. appending ( " module.modulemap " )
226- if moduleMapPath . asString . isFile {
247+ if fileSystem . isFile ( moduleMapPath ) {
227248 let sources = Sources ( paths: [ moduleMapPath] , root: packagePath)
228249 return [ try CModule ( name: manifest. name, sources: sources, path: packagePath, pkgConfig: pkgConfigPath, providers: manifest. package . providers) ]
229250 }
@@ -235,16 +256,16 @@ public struct PackageBuilder {
235256 let srcroot = try sourceRoot ( )
236257
237258 if srcroot != packagePath {
238- let invalidRootFiles = walk ( packagePath, recursively : false ) . filter ( isValidSource)
259+ let invalidRootFiles = try directoryContents ( packagePath) . filter ( isValidSource)
239260 guard invalidRootFiles. isEmpty else {
240261 throw ModuleError . invalidLayout ( . invalidLayout( invalidRootFiles. map { $0. asString } ) )
241262 }
242263 }
243264
244- let maybeModules = walk ( srcroot, recursively : false ) . filter ( shouldConsiderDirectory)
265+ let maybeModules = try directoryContents ( srcroot) . filter ( shouldConsiderDirectory)
245266
246267 if maybeModules. count == 1 && maybeModules [ 0 ] != srcroot {
247- let invalidModuleFiles = walk ( srcroot, recursively : false ) . filter ( isValidSource)
268+ let invalidModuleFiles = try directoryContents ( srcroot) . filter ( isValidSource)
248269 guard invalidModuleFiles. isEmpty else {
249270 throw ModuleError . invalidLayout ( . invalidLayout( invalidModuleFiles. map { $0. asString } ) )
250271 }
@@ -313,7 +334,7 @@ public struct PackageBuilder {
313334 }
314335
315336 private func modulify( _ path: AbsolutePath , name: String , isTest: Bool ) throws -> Module {
316- let walked = walk ( path, recursing : shouldConsiderDirectory) . map { $0 }
337+ let walked = try recursiveDirectoryContents ( path, predicate : shouldConsiderDirectory) . map { $0 }
317338
318339 let cSources = walked. filter { isValidSource ( $0, validExtensions: SupportedLanguageExtension . cFamilyExtensions) }
319340 let swiftSources = walked. filter { isValidSource ( $0, validExtensions: SupportedLanguageExtension . swiftExtensions) }
@@ -400,11 +421,13 @@ public struct PackageBuilder {
400421 private func constructTestModules( modules: [ Module ] ) throws -> [ Module ] {
401422 let testsPath = packagePath. appending ( " Tests " )
402423
403- // Don't try to walk Tests if it is in excludes.
404- if testsPath. asString. isDirectory && excludedPaths. contains ( testsPath) { return [ ] }
424+ // Don't try to walk Tests if it is in excludes or doesn't exists.
425+ guard fileSystem. isDirectory ( testsPath) && !excludedPaths. contains ( testsPath) else {
426+ return [ ]
427+ }
405428
406429 // Create the test modules
407- let testModules = try walk ( testsPath, recursively : false ) . filter ( shouldConsiderDirectory) . flatMap { dir in
430+ let testModules = try directoryContents ( testsPath) . filter ( shouldConsiderDirectory) . flatMap { dir in
408431 return [ try modulify ( dir, name: dir. basename, isTest: true ) ]
409432 }
410433
0 commit comments