//===----------------------------------------------------------------------===// // 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 ContainerBuildIR import ContainerBuildSnapshotter import Foundation /// A protocol for computing differences between filesystem snapshots. public protocol Differ: Sendable { /// Compute the difference between two snapshots. /// /// - Parameters: /// - from: The base snapshot /// - to: The target snapshot /// - Returns: The filesystem changes needed to transform `from` into `to` func diff(from: Snapshot?, to: Snapshot) async throws -> FilesystemChanges /// Compute a digest representing the state of a filesystem path. /// /// - Parameter path: The filesystem path to digest /// - Returns: A digest representing the current state func digest(path: String) async throws -> Digest } /// A basic in-memory differ implementation. public struct MemoryDiffer: Differ { public init() {} public func diff(from base: Snapshot?, to target: Snapshot) async throws -> FilesystemChanges { // Stub implementation // In a real implementation, this would: // 1. Mount or access both snapshots // 2. Walk the filesystem trees // 3. Compare files, directories, and metadata // 4. Return the differences FilesystemChanges( added: Set(), modified: Set(), deleted: Set(), sizeChange: 0 ) } public func digest(path: String) async throws -> Digest { // Stub implementation // In a real implementation, this would compute a merkle tree // digest of the filesystem at the given path var digestBytes = Data(count: 32) digestBytes.withUnsafeMutableBytes { bytes in if let baseAddress = bytes.baseAddress { memset(baseAddress, 0, 32) } } return try Digest(algorithm: .sha256, bytes: digestBytes) } }