From 31268da515abd446ef300f8b33ae05d671941062 Mon Sep 17 00:00:00 2001 From: Silvio Giebl Date: Mon, 15 Jul 2024 10:15:50 +0200 Subject: [PATCH] Revert "Rename OciMetadata(Task) -> OciVariantMetadata(Task)" This reverts commit fd21809b --- .../gradle/oci/OciImagesInputTask.kt | 4 +- ...iantMetadataTask.kt => OciMetadataTask.kt} | 2 +- .../gradle/oci/internal/OciNaming.kt | 2 +- .../internal/dsl/OciImageDefinitionImpl.kt | 57 +++++++++---------- .../registry/OciImageMetadataRegistry.kt | 24 ++++---- .../internal/registry/OciRepositoryHandler.kt | 48 ++++++++-------- .../{OciVariantMetadata.kt => OciMetadata.kt} | 2 +- ...tadataBuilder.kt => OciMetadataBuilder.kt} | 4 +- .../oci/metadata/OciMetadataJsonCodec.kt | 8 +-- 9 files changed, 72 insertions(+), 79 deletions(-) rename src/main/kotlin/io/github/sgtsilvio/gradle/oci/{OciVariantMetadataTask.kt => OciMetadataTask.kt} (94%) rename src/main/kotlin/io/github/sgtsilvio/gradle/oci/metadata/{OciVariantMetadata.kt => OciMetadata.kt} (98%) rename src/main/kotlin/io/github/sgtsilvio/gradle/oci/metadata/{OciVariantMetadataBuilder.kt => OciMetadataBuilder.kt} (98%) diff --git a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciImagesInputTask.kt b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciImagesInputTask.kt index cc10c820..d2b01772 100644 --- a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciImagesInputTask.kt +++ b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciImagesInputTask.kt @@ -41,7 +41,7 @@ internal class OciImage( ) internal class OciVariant( - val metadata: OciVariantMetadata, + val metadata: OciMetadata, val layers: List, ) @@ -102,7 +102,7 @@ abstract class OciImagesInputTask : DefaultTask() { } private fun OciVariantInput.toVariant(): OciVariant { - val metadata = metadataFile.readText().decodeAsJsonToOciVariantMetadata() + val metadata = metadataFile.readText().decodeAsJsonToOciMetadata() val layerFiles = layerFiles val layers = ArrayList(layerFiles.size) var layerFileIndex = 0 diff --git a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciVariantMetadataTask.kt b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciMetadataTask.kt similarity index 94% rename from src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciVariantMetadataTask.kt rename to src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciMetadataTask.kt index 020b3601..e4bf5017 100644 --- a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciVariantMetadataTask.kt +++ b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/OciMetadataTask.kt @@ -13,7 +13,7 @@ import org.gradle.kotlin.dsl.property /** * @author Silvio Giebl */ -abstract class OciVariantMetadataTask : DefaultTask() { +abstract class OciMetadataTask : DefaultTask() { @get:Input val encodedMetadata: Property = project.objects.property() diff --git a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/internal/OciNaming.kt b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/internal/OciNaming.kt index 67409f41..2c08fec3 100644 --- a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/internal/OciNaming.kt +++ b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/internal/OciNaming.kt @@ -19,7 +19,7 @@ internal fun createOciVariantName(imageDefName: String, platform: Platform): Str internal fun createOciVariantInternalName(imageDefName: String, platform: Platform): String = createOciVariantName(imageDefName).concatCamelCase("internal") + createPlatformPostfix(platform) -internal fun createOciVariantMetadataClassifier(imageDefName: String): String = +internal fun createOciMetadataClassifier(imageDefName: String): String = imageDefName.mainToEmpty().kebabCase().concatKebabCase("oci-metadata") internal fun createOciLayerClassifier(imageDefName: String, layerName: String): String = diff --git a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/internal/dsl/OciImageDefinitionImpl.kt b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/internal/dsl/OciImageDefinitionImpl.kt index 5d57e021..1e2d0bc5 100644 --- a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/internal/dsl/OciImageDefinitionImpl.kt +++ b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/internal/dsl/OciImageDefinitionImpl.kt @@ -2,7 +2,7 @@ package io.github.sgtsilvio.gradle.oci.internal.dsl import io.github.sgtsilvio.gradle.oci.OciCopySpec import io.github.sgtsilvio.gradle.oci.OciLayerTask -import io.github.sgtsilvio.gradle.oci.OciVariantMetadataTask +import io.github.sgtsilvio.gradle.oci.OciMetadataTask import io.github.sgtsilvio.gradle.oci.TASK_GROUP_NAME import io.github.sgtsilvio.gradle.oci.attributes.* import io.github.sgtsilvio.gradle.oci.dsl.OciImageDefinition @@ -232,9 +232,8 @@ internal abstract class OciImageDefinitionImpl @Inject constructor( objectFactory.newInstance(imageDefinition.name, Optional.ofNullable(platform)) init { - val metadata = createVariantMetadata(providerFactory) - val metadataTask = - taskContainer.createVariantMetadataTask(imageDefinition.name, platform, metadata, projectLayout) + val metadata = createMetadata(providerFactory) + val metadataTask = taskContainer.createMetadataTask(imageDefinition.name, platform, metadata, projectLayout) configuration.outgoing.addArtifacts(providerFactory.provider { listOf(LazyPublishArtifact(objectFactory).apply { file.set(metadataTask.flatMap { it.file }) @@ -254,31 +253,31 @@ internal abstract class OciImageDefinitionImpl @Inject constructor( }) } - private fun createVariantMetadata(providerFactory: ProviderFactory): Provider = - providerFactory.provider { OciVariantMetadataBuilder() } - .zip(imageDefinition.imageReference, OciVariantMetadataBuilder::imageReference) - .zipAbsentAsNull(config.creationTime, OciVariantMetadataBuilder::creationTime) - .zipAbsentAsNull(config.author, OciVariantMetadataBuilder::author) - .zipAbsentAsNull(config.user, OciVariantMetadataBuilder::user) - .zip(config.ports.orElse(emptySet()), OciVariantMetadataBuilder::ports) - .zip(config.environment.orElse(emptyMap()), OciVariantMetadataBuilder::environment) - .zipAbsentAsNull(config.entryPoint, OciVariantMetadataBuilder::entryPoint) - .zipAbsentAsNull(config.arguments, OciVariantMetadataBuilder::arguments) - .zip(config.volumes.orElse(emptySet()), OciVariantMetadataBuilder::volumes) - .zipAbsentAsNull(config.workingDirectory, OciVariantMetadataBuilder::workingDirectory) - .zipAbsentAsNull(config.stopSignal, OciVariantMetadataBuilder::stopSignal) - .zip(config.configAnnotations.orElse(emptyMap()), OciVariantMetadataBuilder::configAnnotations) + private fun createMetadata(providerFactory: ProviderFactory): Provider = + providerFactory.provider { OciMetadataBuilder() } + .zip(imageDefinition.imageReference, OciMetadataBuilder::imageReference) + .zipAbsentAsNull(config.creationTime, OciMetadataBuilder::creationTime) + .zipAbsentAsNull(config.author, OciMetadataBuilder::author) + .zipAbsentAsNull(config.user, OciMetadataBuilder::user) + .zip(config.ports.orElse(emptySet()), OciMetadataBuilder::ports) + .zip(config.environment.orElse(emptyMap()), OciMetadataBuilder::environment) + .zipAbsentAsNull(config.entryPoint, OciMetadataBuilder::entryPoint) + .zipAbsentAsNull(config.arguments, OciMetadataBuilder::arguments) + .zip(config.volumes.orElse(emptySet()), OciMetadataBuilder::volumes) + .zipAbsentAsNull(config.workingDirectory, OciMetadataBuilder::workingDirectory) + .zipAbsentAsNull(config.stopSignal, OciMetadataBuilder::stopSignal) + .zip(config.configAnnotations.orElse(emptyMap()), OciMetadataBuilder::configAnnotations) .zip( config.configDescriptorAnnotations.orElse(emptyMap()), - OciVariantMetadataBuilder::configDescriptorAnnotations, + OciMetadataBuilder::configDescriptorAnnotations, ) - .zip(config.manifestAnnotations.orElse(emptyMap()), OciVariantMetadataBuilder::manifestAnnotations) + .zip(config.manifestAnnotations.orElse(emptyMap()), OciMetadataBuilder::manifestAnnotations) .zip( config.manifestDescriptorAnnotations.orElse(emptyMap()), - OciVariantMetadataBuilder::manifestDescriptorAnnotations, + OciMetadataBuilder::manifestDescriptorAnnotations, ) - .zip(imageDefinition.indexAnnotations.orElse(emptyMap()), OciVariantMetadataBuilder::indexAnnotations) - .zip(createLayerMetadataList(providerFactory), OciVariantMetadataBuilder::layers) + .zip(imageDefinition.indexAnnotations.orElse(emptyMap()), OciMetadataBuilder::indexAnnotations) + .zip(createLayerMetadataList(providerFactory), OciMetadataBuilder::layers) .map { it.build() } private fun createLayerMetadataList(providerFactory: ProviderFactory): Provider> = @@ -594,19 +593,17 @@ internal abstract class OciImageDefinitionImpl @Inject constructor( } } -private fun TaskContainer.createVariantMetadataTask( +private fun TaskContainer.createMetadataTask( imageDefName: String, platform: Platform?, - variantMetadata: Provider, + metadata: Provider, projectLayout: ProjectLayout, -) = register( - createOciVariantMetadataClassifier(imageDefName).camelCase() + createPlatformPostfix(platform) -) { +) = register(createOciMetadataClassifier(imageDefName).camelCase() + createPlatformPostfix(platform)) { group = TASK_GROUP_NAME description = "Assembles the metadata json file of the '$imageDefName' OCI image" + if (platform == null) "." else " for the platform $platform" - encodedMetadata.set(variantMetadata.map { it.encodeToJsonString() }) + encodedMetadata.set(metadata.map { it.encodeToJsonString() }) destinationDirectory.set(projectLayout.buildDirectory.dir("oci/images/$imageDefName")) - classifier.set(createOciVariantMetadataClassifier(imageDefName) + createPlatformPostfix(platform)) + classifier.set(createOciMetadataClassifier(imageDefName) + createPlatformPostfix(platform)) } private fun TaskContainer.createLayerTask( diff --git a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/internal/registry/OciImageMetadataRegistry.kt b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/internal/registry/OciImageMetadataRegistry.kt index 0e747cc6..3b94fea7 100644 --- a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/internal/registry/OciImageMetadataRegistry.kt +++ b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/internal/registry/OciImageMetadataRegistry.kt @@ -13,11 +13,7 @@ import java.util.* */ internal class OciImageMetadataRegistry(val registryApi: OciRegistryApi) { - class OciImageMetadata( - val platformToVariantMetadata: Map, - val digest: OciDigest, - val size: Int, - ) + class OciImageMetadata(val platformToMetadata: Map, val digest: OciDigest, val size: Int) fun pullImageMetadata( registry: String, @@ -102,7 +98,7 @@ internal class OciImageMetadataRegistry(val registryApi: OciRegistryApi) { ): Mono { val indexJsonObject = jsonObject(String(index.bytes)) val indexAnnotations = indexJsonObject.getStringMapOrEmpty("annotations") - val platformVariantMetadataMonoList = indexJsonObject.get("manifests") { + val metadataMonoList = indexJsonObject.get("manifests") { asArray().toList { val (manifestDescriptorPlatform, manifestDescriptor) = asObject().decodeOciManifestDescriptor() if (manifestDescriptor.mediaType != manifestMediaType) { // TODO support nested index @@ -118,7 +114,7 @@ internal class OciImageMetadataRegistry(val registryApi: OciRegistryApi) { if (manifest.mediaType != manifestMediaType) { throw IllegalStateException("media type in manifest descriptor ($manifestMediaType) and manifest (${manifest.mediaType}) do not match") } - transformManifestToPlatformVariantMetadata( + transformManifestToMetadata( registry, imageReference, manifest, @@ -139,10 +135,10 @@ internal class OciImageMetadataRegistry(val registryApi: OciRegistryApi) { indexJsonObject.requireStringOrNull("mediaType", index.mediaType) indexJsonObject.requireLong("schemaVersion", 2) // the same order as in the manifest is guaranteed by mergeSequential - return Flux.mergeSequential(platformVariantMetadataMonoList) + return Flux.mergeSequential(metadataMonoList) // linked to preserve the platform order - .collect({ LinkedHashMap() }) { map, (platform, variantMetadata) -> - if (map.putIfAbsent(platform, variantMetadata) != null) { + .collect({ LinkedHashMap() }) { map, (platform, metadata) -> + if (map.putIfAbsent(platform, metadata) != null) { throw IllegalStateException("duplicate platform in image index: $platform") } } @@ -156,7 +152,7 @@ internal class OciImageMetadataRegistry(val registryApi: OciRegistryApi) { credentials: Credentials?, configMediaType: String, layerMediaTypePrefix: String, - ): Mono = transformManifestToPlatformVariantMetadata( + ): Mono = transformManifestToMetadata( registry, imageReference, manifest, @@ -167,7 +163,7 @@ internal class OciImageMetadataRegistry(val registryApi: OciRegistryApi) { layerMediaTypePrefix, ).map { OciImageMetadata(mapOf(it), manifest.digest, manifest.bytes.size) } - private fun transformManifestToPlatformVariantMetadata( + private fun transformManifestToMetadata( registry: String, imageReference: OciImageReference, manifest: OciData, @@ -176,7 +172,7 @@ internal class OciImageMetadataRegistry(val registryApi: OciRegistryApi) { credentials: Credentials?, configMediaType: String, layerMediaTypePrefix: String, - ): Mono> { + ): Mono> { val manifestJsonObject = jsonObject(String(manifest.bytes)) val manifestAnnotations = manifestJsonObject.getStringMapOrEmpty("annotations") val configDescriptor = manifestJsonObject.get("config") { asObject().decodeOciDescriptor() } @@ -273,7 +269,7 @@ internal class OciImageMetadataRegistry(val registryApi: OciRegistryApi) { } Pair( Platform(os, architecture, variant, osVersion, osFeatures), - OciVariantMetadata( + OciMetadata( imageReference, creationTime, author, diff --git a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/internal/registry/OciRepositoryHandler.kt b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/internal/registry/OciRepositoryHandler.kt index 519fb87d..f3318960 100644 --- a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/internal/registry/OciRepositoryHandler.kt +++ b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/internal/registry/OciRepositoryHandler.kt @@ -98,13 +98,13 @@ internal class OciRepositoryHandler( } val last = segments.last() return when { - last.endsWith(".json") -> getOrHeadVariantMetadata(registryUri, segments, isGet, response) + last.endsWith(".json") -> getOrHeadMetadata(registryUri, segments, isGet, response) last.endsWith("oci-layer") -> getOrHeadLayer(registryUri, segments, isGet, response) else -> response.sendNotFound() } } - private fun getOrHeadVariantMetadata( + private fun getOrHeadMetadata( registryUri: URI, segments: List, isGet: Boolean, @@ -133,17 +133,17 @@ internal class OciRepositoryHandler( } catch (e: IllegalArgumentException) { return response.sendBadRequest() } - val variantMetadataJsonMono = + val metadataJsonMono = getImageMetadata(registryUri, imageReference, digest, size, credentials).handle { imageMetadata, sink -> - val variantMetadata = imageMetadata.platformToVariantMetadata[platform] - if (variantMetadata == null) { + val metadata = imageMetadata.platformToMetadata[platform] + if (metadata == null) { response.status(400) } else { - sink.next(variantMetadata.encodeToJsonString().toByteArray()) + sink.next(metadata.encodeToJsonString().toByteArray()) } } response.header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.APPLICATION_JSON) - return response.sendByteArray(variantMetadataJsonMono, isGet) + return response.sendByteArray(metadataJsonMono, isGet) } private fun getOrHeadLayer( @@ -189,7 +189,7 @@ internal class OciRepositoryHandler( data class OciImageVariantsMetadata( val imageDefName: String, val capabilities: Set, - val platformToVariantMetadata: Map, + val platformToMetadata: Map, val digest: OciDigest, val size: Int, ) @@ -199,7 +199,7 @@ internal class OciRepositoryHandler( OciImageVariantsMetadata( imageDefName, variant.capabilities, - imageMetadata.platformToVariantMetadata, + imageMetadata.platformToMetadata, imageMetadata.digest, imageMetadata.size, ) @@ -218,18 +218,18 @@ internal class OciRepositoryHandler( } val fileNamePrefix = "${componentId.name}-${componentId.version}-" addArray("variants") { - for ((imageDefName, capabilities, platformToVariantMetadata, digest, size) in imageVariantsMetadataList) { + for ((imageDefName, capabilities, platformToMetadata, digest, size) in imageVariantsMetadataList) { addObject { addString("name", createOciVariantName(imageDefName)) addOciVariantAttributes(MULTIPLE_PLATFORMS_ATTRIBUTE_VALUE) addCapabilities("capabilities", capabilities, componentId) addArray("dependencies") { - for (platform in platformToVariantMetadata.keys) { + for (platform in platformToMetadata.keys) { addDependency(componentId, capabilities, platform) } } } - for ((platform, variantMetadata) in platformToVariantMetadata) { + for ((platform, metadata) in platformToMetadata) { addObject { addString("name", createOciVariantName(imageDefName, platform)) addOciVariantAttributes(platform.toString()) @@ -244,19 +244,19 @@ internal class OciRepositoryHandler( addCapabilities("capabilities", capabilities, platform) addArray("files") { addObject { - val variantMetadataJson = variantMetadata.encodeToJsonString().toByteArray() - val variantMetadataName = fileNamePrefix + createOciVariantMetadataClassifier(imageDefName) + createPlatformPostfix(platform) + ".json" - val escapedImageReference = variantMetadata.imageReference.toString().escapePathSegment() - addString("name", variantMetadataName) - addString("url", "$escapedImageReference/$digest/$size/$platform/$variantMetadataName") - addNumber("size", variantMetadataJson.size.toLong()) - addString("sha512", DigestUtils.sha512Hex(variantMetadataJson)) - addString("sha256", DigestUtils.sha256Hex(variantMetadataJson)) - addString("sha1", DigestUtils.sha1Hex(variantMetadataJson)) - addString("md5", DigestUtils.md5Hex(variantMetadataJson)) + val metadataJson = metadata.encodeToJsonString().toByteArray() + val metadataName = fileNamePrefix + createOciMetadataClassifier(imageDefName) + createPlatformPostfix(platform) + ".json" + val escapedImageReference = metadata.imageReference.toString().escapePathSegment() + addString("name", metadataName) + addString("url", "$escapedImageReference/$digest/$size/$platform/$metadataName") + addNumber("size", metadataJson.size.toLong()) + addString("sha512", DigestUtils.sha512Hex(metadataJson)) + addString("sha256", DigestUtils.sha256Hex(metadataJson)) + addString("sha1", DigestUtils.sha1Hex(metadataJson)) + addString("md5", DigestUtils.md5Hex(metadataJson)) } - val escapedImageName = variantMetadata.imageReference.name.escapePathSegment() - for (layerMetadata in variantMetadata.layers) { + val escapedImageName = metadata.imageReference.name.escapePathSegment() + for (layerMetadata in metadata.layers) { layerMetadata.descriptor?.let { layerDescriptor -> addObject { val layerDigest = layerDescriptor.digest diff --git a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/metadata/OciVariantMetadata.kt b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/metadata/OciMetadata.kt similarity index 98% rename from src/main/kotlin/io/github/sgtsilvio/gradle/oci/metadata/OciVariantMetadata.kt rename to src/main/kotlin/io/github/sgtsilvio/gradle/oci/metadata/OciMetadata.kt index 612f1b76..7d932d15 100644 --- a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/metadata/OciVariantMetadata.kt +++ b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/metadata/OciMetadata.kt @@ -6,7 +6,7 @@ import java.util.* /** * @author Silvio Giebl */ -class OciVariantMetadata( +class OciMetadata( val imageReference: OciImageReference, // not inherited val creationTime: Instant?, // not inherited val author: String?, // not inherited diff --git a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/metadata/OciVariantMetadataBuilder.kt b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/metadata/OciMetadataBuilder.kt similarity index 98% rename from src/main/kotlin/io/github/sgtsilvio/gradle/oci/metadata/OciVariantMetadataBuilder.kt rename to src/main/kotlin/io/github/sgtsilvio/gradle/oci/metadata/OciMetadataBuilder.kt index 6f2990d4..eeadce07 100644 --- a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/metadata/OciVariantMetadataBuilder.kt +++ b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/metadata/OciMetadataBuilder.kt @@ -5,7 +5,7 @@ import java.time.Instant /** * @author Silvio Giebl */ -internal class OciVariantMetadataBuilder { +internal class OciMetadataBuilder { private var imageReference: OciImageReference? = null private var creationTime: SerializableInstant? = null private var author: String? = null @@ -42,7 +42,7 @@ internal class OciVariantMetadataBuilder { fun indexAnnotations(v: Map) = apply { indexAnnotations = v } fun layers(v: List) = apply { layers = v } - fun build() = OciVariantMetadata( + fun build() = OciMetadata( imageReference!!, creationTime?.toInstant(), author, diff --git a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/metadata/OciMetadataJsonCodec.kt b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/metadata/OciMetadataJsonCodec.kt index 9470d4cd..9d11e5a4 100644 --- a/src/main/kotlin/io/github/sgtsilvio/gradle/oci/metadata/OciMetadataJsonCodec.kt +++ b/src/main/kotlin/io/github/sgtsilvio/gradle/oci/metadata/OciMetadataJsonCodec.kt @@ -2,9 +2,9 @@ package io.github.sgtsilvio.gradle.oci.metadata import io.github.sgtsilvio.gradle.oci.internal.json.* -internal fun OciVariantMetadata.encodeToJsonString() = jsonObject { encodeOciVariantMetadata(this@encodeToJsonString) } +internal fun OciMetadata.encodeToJsonString() = jsonObject { encodeOciMetadata(this@encodeToJsonString) } -private fun JsonObjectStringBuilder.encodeOciVariantMetadata(metadata: OciVariantMetadata) { +private fun JsonObjectStringBuilder.encodeOciMetadata(metadata: OciMetadata) { addString("imageReference", metadata.imageReference.toString()) addStringIfNotNull("creationTime", metadata.creationTime?.toString()) addStringIfNotNull("author", metadata.author) @@ -44,9 +44,9 @@ private fun JsonObjectStringBuilder.encodeOciLayerDescriptor(descriptor: OciLaye addObjectIfNotEmpty("annotations", descriptor.annotations) } -internal fun String.decodeAsJsonToOciVariantMetadata() = jsonObject(this).decodeOciVariantMetadata() +internal fun String.decodeAsJsonToOciMetadata() = jsonObject(this).decodeOciMetadata() -private fun JsonObject.decodeOciVariantMetadata() = OciVariantMetadata( +private fun JsonObject.decodeOciMetadata() = OciMetadata( get("imageReference") { asString().toOciImageReference() }, getInstantOrNull("creationTime"), getStringOrNull("author"),