mirror of
https://github.com/apple/swift-nio.git
synced 2026-05-20 20:30:36 +00:00
66a85ba0e2
Motivation: In #3363 we converted `_NIOFileSystem` to `NIOFileSystem` and removed the (unreleased) overloads for FilePath/NIOFilePath. This change adds back `_NIOFileSystem` such that it matches the API it had at 2.86.0. Modifications: - Add back `_NIOFileSystem` and `_NIOFileSystemFoundationCompat` such that their API is at 2.86.0 Result: - `NIOFileSystem` uses `NIOFilePath` - `_NIOFileSystem` uses `FilePath`
73 lines
2.7 KiB
Swift
73 lines
2.7 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This source file is part of the SwiftNIO open source project
|
|
//
|
|
// Copyright (c) 2024 Apple Inc. and the SwiftNIO project authors
|
|
// Licensed under Apache License v2.0
|
|
//
|
|
// See LICENSE.txt for license information
|
|
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
import NIOCore
|
|
|
|
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
|
|
extension FileSystem {
|
|
/// Recursively walk all objects found in `path`. Call ourselves recursively
|
|
/// on each directory that we find, as soon as the file descriptor for
|
|
/// `path` has been closed; also delete all files that we come across.
|
|
func discoverAndRemoveItemsInTree(
|
|
at path: FilePath,
|
|
_ bucket: TokenBucket
|
|
) async throws -> Int {
|
|
// Discover current directory and find all files/directories. Free up
|
|
// the handle as fast as possible.
|
|
let (directoriesToRecurseInto, itemsToDelete) = try await bucket.withToken {
|
|
try await self.withDirectoryHandle(atPath: path) { directory in
|
|
var subdirectories: [FilePath] = []
|
|
var itemsInDirectory: [FilePath] = []
|
|
|
|
for try await batch in directory.listContents().batched() {
|
|
for entry in batch {
|
|
switch entry.type {
|
|
case .directory:
|
|
subdirectories.append(entry.path)
|
|
default:
|
|
itemsInDirectory.append(entry.path)
|
|
}
|
|
}
|
|
}
|
|
|
|
return (subdirectories, itemsInDirectory)
|
|
}
|
|
}
|
|
|
|
return try await withThrowingTaskGroup(of: Int.self) { group in
|
|
// Delete all items we found in the current directory.
|
|
for item in itemsToDelete {
|
|
group.addTask {
|
|
try await self.removeOneItem(at: item)
|
|
}
|
|
}
|
|
|
|
// Recurse into all newly found subdirectories.
|
|
for directory in directoriesToRecurseInto {
|
|
group.addTask {
|
|
try await self.discoverAndRemoveItemsInTree(at: directory, bucket)
|
|
}
|
|
}
|
|
|
|
// Await task groups to finish and sum all items deleted so far.
|
|
var numberOfDeletedItems = try await group.reduce(0, +)
|
|
|
|
// Remove top level directory.
|
|
numberOfDeletedItems += try await self.removeOneItem(at: path)
|
|
|
|
return numberOfDeletedItems
|
|
}
|
|
}
|
|
}
|