diff --git a/Sources/Path+FileManager.swift b/Sources/Path+FileManager.swift index 5b52708..58adbed 100644 --- a/Sources/Path+FileManager.swift +++ b/Sources/Path+FileManager.swift @@ -5,10 +5,18 @@ public extension Path { /** Copies a file. + + try Path.root.join("bar").copy(to: Path.home/"foo") + // => "/Users/mxcl/foo" + - Note: `throws` if `to` is a directory. - Parameter to: Destination filename. - Parameter overwrite: If `true` and both `self` and `to` are files, overwrites `to`. - Note: If either `self` or `to are directories, `overwrite` is ignored. + - Note: Throws if `overwrite` is `false` yet `to` is *already* identical to + `self` because even though *Path.swift’s* policy is to noop if the desired + end result preexists, checking for this condition is too expensive a + trade-off. - Returns: `to` to allow chaining - SeeAlso: `copy(into:overwrite:)` */ @@ -24,15 +32,22 @@ public extension Path { /** Copies a file into a directory - If the destination does not exist, this function creates the directory first. - - // Create ~/.local/bin, copy `ls` there and make the new copy executable - try Path.root.join("bin/ls").copy(into: Path.home.join(".local/bin").mkpath()).chmod(0o500) + try Path.root.join("bar").copy(into: .home) + // => "/Users/mxcl/bar" + + // Create ~/.local/bin, copy `ls` there and make the new copy executable + try Path.root.join("bin/ls").copy(into: Path.home.join(".local/bin").mkdir(.p)).chmod(0o500) + + If the destination does not exist, this function creates the directory first. - - Note: `throws` if `into` is a file. - Parameter into: Destination directory - Parameter overwrite: If true overwrites any file that already exists at `into`. - Returns: The `Path` of the newly copied file. + - Note: `throws` if `into` is a file. + - Note: Throws if `overwrite` is `false` yet `to` is *already* identical to + `self` because even though *Path.swift’s* policy is to noop if the desired + end result preexists, checking for this condition is too expensive a + trade-off. - SeeAlso: `copy(into:overwrite:)` */ @discardableResult @@ -59,10 +74,18 @@ public extension Path { /** Moves a file. - - Note: `throws` if `to` is a directory. + + try Path.root.join("bar").move(to: Path.home/"foo") + // => "/Users/mxcl/foo" + - Parameter to: Destination filename. - Parameter overwrite: If true overwrites any file that already exists at `to`. - Returns: `to` to allow chaining + - Note: `throws` if `to` is a directory. + - Note: Throws if `overwrite` is `false` yet `to` is *already* identical to + `self` because even though *Path.swift’s* policy is to noop if the desired + end result preexists, checking for this condition is too expensive a + trade-off. - SeeAlso: move(into:overwrite:) */ @discardableResult @@ -77,18 +100,21 @@ public extension Path { /** Moves a file into a directory + try Path.root.join("bar").move(into: .home) + // => "/Users/mxcl/bar" + If the destination does not exist, this function creates the directory first. - - Note: `throws` if `into` is a file. - Parameter into: Destination directory - - Parameter overwrite: If true overwrites any file that already exists at `into`. + - Parameter overwrite: If true *overwrites* any file that already exists at `into`. + - Note: `throws` if `into` is a file. - Returns: The `Path` of destination filename. - SeeAlso: move(into:overwrite:) */ @discardableResult func move(into: Path) throws -> Path { if !into.exists { - try into.mkpath() + try into.mkdir(.p) } else if !into.isDirectory { throw CocoaError.error(.fileWriteFileExists) } @@ -113,49 +139,37 @@ public extension Path { return try "".write(to: self) } - /// Helper due to Linux Swift being incomplete. - private func _foo(go: () throws -> Void) throws { - #if !os(Linux) + /** + Creates the directory at this path. + - Note: Does not create any intermediary directories. + - Parameter options: Specify `mkdir(.p)` to create intermediary directories. + - Note: We do not error if the directory already exists (even without `.p`) + because *Path.swift* noops if the desired end result preexists. + - Returns: `self` to allow chaining. + */ + @discardableResult + func mkdir(_ options: MakeDirectoryOptions? = nil) throws -> Path { do { - try go() + let wid = options == .p + try FileManager.default.createDirectory(at: self.url, withIntermediateDirectories: wid, attributes: nil) } catch CocoaError.Code.fileWriteFileExists { - // noop - } - #else - do { - try go() + //noop (fails to trigger on Linux) } catch { + #if os(Linux) let error = error as NSError guard error.domain == NSCocoaErrorDomain, error.code == CocoaError.Code.fileWriteFileExists.rawValue else { throw error } - } - #endif - } - - /** - Creates the directory at this path. - - Note: Does not create any intermediary directories. - - Returns: `self` to allow chaining. - */ - @discardableResult - func mkdir() throws -> Path { - try _foo { - try FileManager.default.createDirectory(at: self.url, withIntermediateDirectories: false, attributes: nil) - } - return self - } - - /** - Creates the directory at this path. - - Note: Creates any intermediary directories, if required. - - Returns: `self` to allow chaining. - */ - @discardableResult - func mkpath() throws -> Path { - try _foo { - try FileManager.default.createDirectory(at: url, withIntermediateDirectories: true, attributes: nil) + #else + throw error + #endif } return self } } + +/// Options for `Path.mkdir` +public enum MakeDirectoryOptions { + /// Creates intermediary directories. Works the same as mkdir -p. + case p +} diff --git a/Tests/PathTests/PathTests.swift b/Tests/PathTests/PathTests.swift index 6d23262..aa88eba 100644 --- a/Tests/PathTests/PathTests.swift +++ b/Tests/PathTests/PathTests.swift @@ -83,7 +83,7 @@ class PathTests: XCTestCase { try Path.mktemp { for _ in 0...1 { try $0.join("a").mkdir() - try $0.join("b/c").mkpath() + try $0.join("b/c").mkdir(.p) } } }