Skip to content

Commit 7963ebc

Browse files
authored
[FileSystem] Add API for obtaining item replacement directory (#427)
This is used by many Foundation methods that take an `atomically` parameter and we need to expose this in order to allow sandboxes processes to write to it.
1 parent ef2db24 commit 7963ebc

File tree

1 file changed

+13
-0
lines changed

1 file changed

+13
-0
lines changed

Sources/TSCBasic/FileSystem.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,10 @@ public protocol FileSystem: Sendable {
196196
/// Check whether the given path is accessible and writable.
197197
func isWritable(_ path: AbsolutePath) -> Bool
198198

199+
/// Returns any known item replacement directories for a given path. These may be used by platform-specific
200+
/// libraries to handle atomic file system operations, such as deletion.
201+
func itemReplacementDirectories(for path: AbsolutePath) throws -> [AbsolutePath]
202+
199203
@available(*, deprecated, message: "use `hasAttribute(_:_:)` instead")
200204
func hasQuarantineAttribute(_ path: AbsolutePath) -> Bool
201205

@@ -346,6 +350,8 @@ public extension FileSystem {
346350
func hasQuarantineAttribute(_ path: AbsolutePath) -> Bool { false }
347351

348352
func hasAttribute(_ name: FileSystemAttribute, _ path: AbsolutePath) -> Bool { false }
353+
354+
func itemReplacementDirectories(for path: AbsolutePath) throws -> [AbsolutePath] { [] }
349355
}
350356

351357
/// Concrete FileSystem implementation which communicates with the local file system.
@@ -616,6 +622,13 @@ private struct LocalFileSystem: FileSystem {
616622
) async throws -> T {
617623
try await FileLock.withLock(fileToLock: path, type: type, body: body)
618624
}
625+
626+
func itemReplacementDirectories(for path: AbsolutePath) throws -> [AbsolutePath] {
627+
let result = try FileManager.default.url(for: .itemReplacementDirectory, in: .userDomainMask, appropriateFor: path.asURL, create: false)
628+
let path = try AbsolutePath(validating: result.path)
629+
// Foundation returns a path that is unique every time, so we return both that path, as well as its parent.
630+
return [path, path.parentDirectory]
631+
}
619632
}
620633

621634
/// Concrete FileSystem implementation which simulates an empty disk.

0 commit comments

Comments
 (0)