Skip to content

Commit

Permalink
FileSystem: Add API to create a file using a path
Browse files Browse the repository at this point in the history
Just like creating a folder from `FileSystem`, you can now create a file
using just a path, and any intermediate parent folders in that path will
also be created.
  • Loading branch information
JohnSundell committed Mar 20, 2017
1 parent 8eb374d commit fb2dec4
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 15 deletions.
62 changes: 47 additions & 15 deletions Sources/Files.swift
Original file line number Diff line number Diff line change
Expand Up @@ -164,20 +164,9 @@ public class FileSystem {

/// The folder that the item is contained in, or `nil` if this item is the root folder of the file system
public var parent: Folder? {
guard path != "/" else {
return nil
return fileManager.parentPath(for: path).flatMap { parentPath in
return try? Folder(path: parentPath, using: fileManager)
}

var pathComponents = path.pathComponents

switch kind {
case .file:
pathComponents.removeLast()
case .folder:
pathComponents.removeLast(2)
}

return try? Folder(path: pathComponents.joined(separator: "/"), using: fileManager)
}

/// A string describing the item
Expand Down Expand Up @@ -312,18 +301,45 @@ public class FileSystem {
self.fileManager = fileManager
}

/**
* Create a new file at a given path
*
* - parameter path: The path at which a file should be created. If the path is missing intermediate
* parent folders, those will be created as well.
*
* - throws: `File.Error.writeFailed`
*
* - returns: The file that was created
*/
@discardableResult public func createFile(at path: String, contents: Data = Data()) throws -> File {
let path = fileManager.absolutePath(for: path)

guard let parentPath = fileManager.parentPath(for: path) else {
throw File.Error.writeFailed
}

do {
let name = path.substring(from: path.index(path.startIndex, offsetBy: parentPath.characters.count))
return try createFolder(at: parentPath).createFile(named: name, contents: contents)
} catch {
throw File.Error.writeFailed
}
}

/**
* Create a new folder at a given path
*
* - parameter path: The path at which a folder should be created. If the path is missing intermediate
* parent folders, those will be created as well.
*
* - throws: `Folder.Error.creatingFolderFailed`
*
* - returns: The folder that was created
*/
@discardableResult public func createFolder(at path: String) throws -> Folder {
do {
let absolutePath = fileManager.absolutePath(for: path)
try fileManager.createDirectory(atPath: absolutePath, withIntermediateDirectories: true, attributes: nil)
let path = fileManager.absolutePath(for: path)
try fileManager.createDirectory(atPath: path, withIntermediateDirectories: true, attributes: nil)
return try Folder(path: path, using: fileManager)
} catch {
throw Folder.Error.creatingFolderFailed
Expand Down Expand Up @@ -827,6 +843,22 @@ private extension FileManager {

return currentDirectoryPath + "/" + path
}

func parentPath(for path: String) -> String? {
guard path != "/" else {
return nil
}

var pathComponents = path.pathComponents

if path.hasSuffix("/") {
pathComponents.removeLast(2)
} else {
pathComponents.removeLast()
}

return pathComponents.joined(separator: "/")
}
}

private extension String {
Expand Down
9 changes: 9 additions & 0 deletions Tests/FilesTests/FilesTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,15 @@ class FilesTests: XCTestCase {
}
}

func testCreatingFileFromFileSystem() {
performTest {
let filePath = folder.path + "one/two/three"
let contents = Data()
try FileSystem().createFile(at: filePath, contents: contents)
try XCTAssertEqual(File(path: filePath).read(), contents)
}
}

func testCreatingFolderFromFileSystem() {
performTest {
let folderPath = folder.path + "one/two/three"
Expand Down

0 comments on commit fb2dec4

Please sign in to comment.