mirror of
https://github.com/apple/container.git
synced 2026-07-16 06:27:07 +00:00
0885cdd6a9
This PR introduces the `Differ` with methods: ```swift // Differ protocol func diff(base: Snapshot?, target: Snapshot) async throws -> Descriptor func apply(descriptor: Descriptor, to base: Snapshot?) async throws -> Snapshot ``` It also introduces `DiffKey`, which is a MerkeTree based key for fast diff computations between two dirs
83 lines
3.6 KiB
Swift
83 lines
3.6 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
// Copyright © 2025 Apple Inc. and the container project authors. All rights reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// https://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
import Foundation
|
|
|
|
// Simple temp-directory helper for tests
|
|
enum TestUtils {
|
|
static func withTempDir<T>(_ body: (URL) throws -> T) throws -> T {
|
|
let dir = FileManager.default.temporaryDirectory.appendingPathComponent("cb-snap-\(UUID().uuidString)", isDirectory: true)
|
|
try FileManager.default.createDirectory(at: dir, withIntermediateDirectories: true)
|
|
defer { try? FileManager.default.removeItem(at: dir) }
|
|
return try body(dir)
|
|
}
|
|
|
|
static func withTempDirAsync<T>(_ body: (URL) async throws -> T) async throws -> T {
|
|
let dir = FileManager.default.temporaryDirectory.appendingPathComponent("cb-snap-\(UUID().uuidString)", isDirectory: true)
|
|
try FileManager.default.createDirectory(at: dir, withIntermediateDirectories: true)
|
|
defer { try? FileManager.default.removeItem(at: dir) }
|
|
return try await body(dir)
|
|
}
|
|
|
|
@discardableResult
|
|
static func write(_ path: URL, contents: Data, permissions: UInt16? = nil) throws -> URL {
|
|
let fm = FileManager.default
|
|
try fm.createDirectory(at: path.deletingLastPathComponent(), withIntermediateDirectories: true)
|
|
fm.createFile(atPath: path.path, contents: contents)
|
|
if let mode = permissions {
|
|
try fm.setAttributes([.posixPermissions: NSNumber(value: mode)], ofItemAtPath: path.path)
|
|
}
|
|
return path
|
|
}
|
|
|
|
@discardableResult
|
|
static func writeString(_ path: URL, _ string: String, permissions: UInt16? = nil) throws -> URL {
|
|
try write(path, contents: Data(string.utf8), permissions: permissions)
|
|
}
|
|
|
|
static func readString(_ path: URL) throws -> String {
|
|
String(decoding: try Data(contentsOf: path), as: UTF8.self)
|
|
}
|
|
|
|
static func makeSymlink(at: URL, to relativeTarget: String) throws {
|
|
let fm = FileManager.default
|
|
try fm.createDirectory(at: at.deletingLastPathComponent(), withIntermediateDirectories: true)
|
|
try fm.createSymbolicLink(atPath: at.path, withDestinationPath: relativeTarget)
|
|
}
|
|
|
|
static func chmod(_ path: URL, mode: UInt16) throws {
|
|
try FileManager.default.setAttributes([.posixPermissions: NSNumber(value: mode)], ofItemAtPath: path.path)
|
|
}
|
|
|
|
static func fileExists(_ path: URL) -> Bool {
|
|
FileManager.default.fileExists(atPath: path.path)
|
|
}
|
|
|
|
static func mkdir(_ path: URL) throws {
|
|
try FileManager.default.createDirectory(at: path, withIntermediateDirectories: true)
|
|
}
|
|
|
|
static func listAll(relativeTo root: URL) throws -> [String] {
|
|
guard let en = FileManager.default.enumerator(at: root, includingPropertiesForKeys: nil) else { return [] }
|
|
var out: [String] = []
|
|
while let u = en.nextObject() as? URL {
|
|
let rel = u.path.replacingOccurrences(of: root.path + "/", with: "")
|
|
out.append(rel)
|
|
}
|
|
return out.sorted()
|
|
}
|
|
}
|