diff --git a/Sources/ContainerCommands/Image/ImageList.swift b/Sources/ContainerCommands/Image/ImageList.swift index ba63c42b..5bf81be4 100644 --- a/Sources/ContainerCommands/Image/ImageList.swift +++ b/Sources/ContainerCommands/Image/ImageList.swift @@ -111,7 +111,36 @@ extension Application { } if format == .json { - let data = try JSONEncoder().encode(images.map { $0.description }) + var printableImages: [PrintableImage] = [] + for image in images { + let formatter = ByteCountFormatter() + for descriptor in try await image.index().manifests { + // Don't list attestation manifests + if let referenceType = descriptor.annotations?["vnd.docker.reference.type"], + referenceType == "attestation-manifest" + { + continue + } + + guard let platform = descriptor.platform else { + continue + } + var manifest: ContainerizationOCI.Manifest + do { + manifest = try await image.manifest(for: platform) + } catch { + continue + } + + let size = descriptor.size + manifest.config.size + manifest.layers.reduce(0, { (l, r) in l + r.size }) + let formattedSize = formatter.string(fromByteCount: size) + + printableImages.append( + PrintableImage(reference: image.reference, size: formattedSize, descriptor: image.descriptor) + ) + } + } + let data = try JSONEncoder().encode(printableImages) print(String(data: data, encoding: .utf8)!) return } @@ -160,6 +189,18 @@ extension Application { } try await printImages(images: images, format: options.format, options: options) } + + struct PrintableImage: Codable { + let reference: String + let size: String + let descriptor: Descriptor + + init(reference: String, size: String, descriptor: Descriptor) { + self.reference = reference + self.size = size + self.descriptor = descriptor + } + } } public struct ImageList: AsyncParsableCommand {