Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support arbitrary metadata in the manifest #1153

Merged
merged 4 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import okio.ByteString.Companion.decodeHex
import org.gradle.api.DefaultTask
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.MapProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputDirectory
Expand Down Expand Up @@ -62,6 +63,10 @@ abstract class ZiplineCompileTask : DefaultTask() {
@get:Input
abstract val version: Property<String>

@get:Optional
@get:Input
abstract val metadata: MapProperty<String, String>

internal fun configure(
jsProductionTask: JsProductionTask,
extension: ZiplineExtension,
Expand Down Expand Up @@ -111,6 +116,7 @@ abstract class ZiplineCompileTask : DefaultTask() {
else -> null
}
val version = version.orNull
val metadata = metadata.orNull ?: mapOf()

if (inputChanges.isIncremental) {
fun filterByChangeType(filter: (ChangeType) -> Boolean): List<File> {
Expand All @@ -128,6 +134,7 @@ abstract class ZiplineCompileTask : DefaultTask() {
mainModuleId = mainModuleId,
manifestSigner = manifestSigner,
version = version,
metadata = metadata,
)
} else {
ZiplineCompiler.compile(
Expand All @@ -137,6 +144,7 @@ abstract class ZiplineCompileTask : DefaultTask() {
mainModuleId = mainModuleId,
manifestSigner = manifestSigner,
version = version,
metadata = metadata,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ internal object ZiplineCompiler {
mainModuleId: String?,
manifestSigner: ManifestSigner?,
version: String?,
metadata: Map<String, String>,
) {
val jsFiles = getJsFiles(inputDir.listFiles()!!.asList())
val modules = compileFilesInParallel(jsFiles, outputDir)
Expand All @@ -56,6 +57,7 @@ internal object ZiplineCompiler {
manifestSigner = manifestSigner,
modules = modules,
version = version,
metadata = metadata,
)
}

Expand All @@ -68,6 +70,7 @@ internal object ZiplineCompiler {
mainModuleId: String?,
manifestSigner: ManifestSigner?,
version: String?,
metadata: Map<String, String>,
) {
val modifiedFileNames = getJsFiles(modifiedFiles).map { it.name }.toSet()
val removedFileNames = getJsFiles(removedFiles).map { it.name }.toSet()
Expand Down Expand Up @@ -95,6 +98,7 @@ internal object ZiplineCompiler {
manifestSigner = manifestSigner,
modules = unchangedModules + compiledModules,
version = version,
metadata = metadata,
)
}

Expand Down Expand Up @@ -150,17 +154,19 @@ internal object ZiplineCompiler {

private fun writeManifest(
outputDir: File,
mainFunction: String? = null,
mainModuleId: String? = null,
manifestSigner: ManifestSigner? = null,
mainFunction: String?,
mainModuleId: String?,
manifestSigner: ManifestSigner?,
modules: Map<String, ZiplineManifest.Module>,
version: String? = null,
version: String?,
metadata: Map<String, String>,
) {
val unsignedManifest = ZiplineManifest.create(
modules = modules,
mainFunction = mainFunction,
mainModuleId = mainModuleId,
version = version,
metadata = metadata,
)

val manifest = manifestSigner?.sign(unsignedManifest) ?: unsignedManifest
Expand Down
18 changes: 13 additions & 5 deletions zipline/api/android/zipline.api
Original file line number Diff line number Diff line change
Expand Up @@ -198,23 +198,29 @@ public abstract interface class app/cash/zipline/ZiplineFunction {

public final class app/cash/zipline/ZiplineManifest {
public static final field Companion Lapp/cash/zipline/ZiplineManifest$Companion;
public synthetic fun <init> (ILapp/cash/zipline/ZiplineManifest$Unsigned;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
public synthetic fun <init> (Lapp/cash/zipline/ZiplineManifest$Unsigned;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (ILapp/cash/zipline/ZiplineManifest$Unsigned;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
public synthetic fun <init> (Lapp/cash/zipline/ZiplineManifest$Unsigned;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Lapp/cash/zipline/ZiplineManifest$Unsigned;
public final fun component2 ()Ljava/util/Map;
public final fun component3 ()Ljava/lang/String;
public final fun component4 ()Ljava/lang/String;
public final fun component5 ()Ljava/lang/String;
public final fun copy (Lapp/cash/zipline/ZiplineManifest$Unsigned;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lapp/cash/zipline/ZiplineManifest;
public final fun copy (Ljava/util/Map;Ljava/lang/Long;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lapp/cash/zipline/ZiplineManifest;
public final fun component6 ()Ljava/util/Map;
public final synthetic fun copy (Lapp/cash/zipline/ZiplineManifest$Unsigned;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lapp/cash/zipline/ZiplineManifest;
public final fun copy (Lapp/cash/zipline/ZiplineManifest$Unsigned;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;)Lapp/cash/zipline/ZiplineManifest;
public final synthetic fun copy (Ljava/util/Map;Ljava/lang/Long;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lapp/cash/zipline/ZiplineManifest;
public final fun copy (Ljava/util/Map;Ljava/lang/Long;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;)Lapp/cash/zipline/ZiplineManifest;
public static synthetic fun copy$default (Lapp/cash/zipline/ZiplineManifest;Lapp/cash/zipline/ZiplineManifest$Unsigned;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lapp/cash/zipline/ZiplineManifest;
public static synthetic fun copy$default (Lapp/cash/zipline/ZiplineManifest;Lapp/cash/zipline/ZiplineManifest$Unsigned;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ILjava/lang/Object;)Lapp/cash/zipline/ZiplineManifest;
public static synthetic fun copy$default (Lapp/cash/zipline/ZiplineManifest;Ljava/util/Map;Ljava/lang/Long;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lapp/cash/zipline/ZiplineManifest;
public static synthetic fun copy$default (Lapp/cash/zipline/ZiplineManifest;Ljava/util/Map;Ljava/lang/Long;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ILjava/lang/Object;)Lapp/cash/zipline/ZiplineManifest;
public final fun encodeJson ()Ljava/lang/String;
public fun equals (Ljava/lang/Object;)Z
public final fun getBaseUrl ()Ljava/lang/String;
public final fun getFreshAtEpochMs ()Ljava/lang/Long;
public final fun getMainFunction ()Ljava/lang/String;
public final fun getMainModuleId ()Ljava/lang/String;
public final fun getMetadata ()Ljava/util/Map;
public final fun getModules ()Ljava/util/Map;
public final fun getSignaturePayload ()Lokio/ByteString;
public final fun getSignatures ()Ljava/util/Map;
Expand All @@ -237,8 +243,10 @@ public final class app/cash/zipline/ZiplineManifest$$serializer : kotlinx/serial
}

public final class app/cash/zipline/ZiplineManifest$Companion {
public final fun create (Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;Ljava/lang/String;)Lapp/cash/zipline/ZiplineManifest;
public final synthetic fun create (Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;Ljava/lang/String;)Lapp/cash/zipline/ZiplineManifest;
public final fun create (Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;Ljava/lang/String;Ljava/util/Map;)Lapp/cash/zipline/ZiplineManifest;
public static synthetic fun create$default (Lapp/cash/zipline/ZiplineManifest$Companion;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;Ljava/lang/String;ILjava/lang/Object;)Lapp/cash/zipline/ZiplineManifest;
public static synthetic fun create$default (Lapp/cash/zipline/ZiplineManifest$Companion;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;Ljava/lang/String;Ljava/util/Map;ILjava/lang/Object;)Lapp/cash/zipline/ZiplineManifest;
public final fun decodeJson (Ljava/lang/String;)Lapp/cash/zipline/ZiplineManifest;
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}
Expand Down
18 changes: 13 additions & 5 deletions zipline/api/jvm/zipline.api
Original file line number Diff line number Diff line change
Expand Up @@ -198,23 +198,29 @@ public abstract interface class app/cash/zipline/ZiplineFunction {

public final class app/cash/zipline/ZiplineManifest {
public static final field Companion Lapp/cash/zipline/ZiplineManifest$Companion;
public synthetic fun <init> (ILapp/cash/zipline/ZiplineManifest$Unsigned;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
public synthetic fun <init> (Lapp/cash/zipline/ZiplineManifest$Unsigned;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (ILapp/cash/zipline/ZiplineManifest$Unsigned;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
public synthetic fun <init> (Lapp/cash/zipline/ZiplineManifest$Unsigned;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Lapp/cash/zipline/ZiplineManifest$Unsigned;
public final fun component2 ()Ljava/util/Map;
public final fun component3 ()Ljava/lang/String;
public final fun component4 ()Ljava/lang/String;
public final fun component5 ()Ljava/lang/String;
public final fun copy (Lapp/cash/zipline/ZiplineManifest$Unsigned;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lapp/cash/zipline/ZiplineManifest;
public final fun copy (Ljava/util/Map;Ljava/lang/Long;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lapp/cash/zipline/ZiplineManifest;
public final fun component6 ()Ljava/util/Map;
public final synthetic fun copy (Lapp/cash/zipline/ZiplineManifest$Unsigned;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lapp/cash/zipline/ZiplineManifest;
public final fun copy (Lapp/cash/zipline/ZiplineManifest$Unsigned;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;)Lapp/cash/zipline/ZiplineManifest;
public final synthetic fun copy (Ljava/util/Map;Ljava/lang/Long;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lapp/cash/zipline/ZiplineManifest;
public final fun copy (Ljava/util/Map;Ljava/lang/Long;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;)Lapp/cash/zipline/ZiplineManifest;
public static synthetic fun copy$default (Lapp/cash/zipline/ZiplineManifest;Lapp/cash/zipline/ZiplineManifest$Unsigned;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lapp/cash/zipline/ZiplineManifest;
public static synthetic fun copy$default (Lapp/cash/zipline/ZiplineManifest;Lapp/cash/zipline/ZiplineManifest$Unsigned;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ILjava/lang/Object;)Lapp/cash/zipline/ZiplineManifest;
public static synthetic fun copy$default (Lapp/cash/zipline/ZiplineManifest;Ljava/util/Map;Ljava/lang/Long;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lapp/cash/zipline/ZiplineManifest;
public static synthetic fun copy$default (Lapp/cash/zipline/ZiplineManifest;Ljava/util/Map;Ljava/lang/Long;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ILjava/lang/Object;)Lapp/cash/zipline/ZiplineManifest;
public final fun encodeJson ()Ljava/lang/String;
public fun equals (Ljava/lang/Object;)Z
public final fun getBaseUrl ()Ljava/lang/String;
public final fun getFreshAtEpochMs ()Ljava/lang/Long;
public final fun getMainFunction ()Ljava/lang/String;
public final fun getMainModuleId ()Ljava/lang/String;
public final fun getMetadata ()Ljava/util/Map;
public final fun getModules ()Ljava/util/Map;
public final fun getSignaturePayload ()Lokio/ByteString;
public final fun getSignatures ()Ljava/util/Map;
Expand All @@ -237,8 +243,10 @@ public final class app/cash/zipline/ZiplineManifest$$serializer : kotlinx/serial
}

public final class app/cash/zipline/ZiplineManifest$Companion {
public final fun create (Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;Ljava/lang/String;)Lapp/cash/zipline/ZiplineManifest;
public final synthetic fun create (Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;Ljava/lang/String;)Lapp/cash/zipline/ZiplineManifest;
public final fun create (Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;Ljava/lang/String;Ljava/util/Map;)Lapp/cash/zipline/ZiplineManifest;
public static synthetic fun create$default (Lapp/cash/zipline/ZiplineManifest$Companion;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;Ljava/lang/String;ILjava/lang/Object;)Lapp/cash/zipline/ZiplineManifest;
public static synthetic fun create$default (Lapp/cash/zipline/ZiplineManifest$Companion;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;Ljava/lang/String;Ljava/util/Map;ILjava/lang/Object;)Lapp/cash/zipline/ZiplineManifest;
public final fun decodeJson (Ljava/lang/String;)Lapp/cash/zipline/ZiplineManifest;
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}
Expand Down
82 changes: 80 additions & 2 deletions zipline/src/hostMain/kotlin/app/cash/zipline/ZiplineManifest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import app.cash.zipline.internal.jsonForManifest
import app.cash.zipline.internal.signaturePayload
import app.cash.zipline.internal.topologicalSort
import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import okio.ByteString
import okio.ByteString.Companion.encodeUtf8
Expand Down Expand Up @@ -51,6 +50,12 @@ data class ZiplineManifest private constructor(

/** Version to represent the code as defined in this manifest, by default it will be Git commit SHA. */
val version: String? = null,

/**
* Arbitrary application-layer metadata about this release. Use this to embed build or diagnostic
* metadata, such as the timestamp that this application was built.
*/
val metadata: Map<String, String> = mapOf(),
) {
init {
require(modules.keys.toList().isTopologicallySorted { id -> modules[id]!!.dependsOnIds }) {
Expand Down Expand Up @@ -108,6 +113,50 @@ data class ZiplineManifest private constructor(
val baseUrl: String?
get() = unsigned.baseUrl

@Deprecated(
message = "This is here for binary-compatibility only",
level = DeprecationLevel.HIDDEN,
)
fun copy(
signatures: Map<String, String> = this.signatures,
freshAtEpochMs: Long? = this.freshAtEpochMs,
baseUrl: String? = this.baseUrl,
modules: Map<String, Module> = this.modules,
mainModuleId: String = this.mainModuleId,
mainFunction: String? = this.mainFunction,
version: String? = this.version,
): ZiplineManifest = copy(
unsigned = unsigned.copy(
freshAtEpochMs = freshAtEpochMs,
signatures = signatures,
baseUrl = baseUrl,
),
modules = modules,
mainModuleId = mainModuleId,
mainFunction = mainFunction,
version = version,
metadata = this.metadata,
)

@Deprecated(
message = "This is here for binary-compatibility only",
level = DeprecationLevel.HIDDEN,
)
fun copy(
unsigned: Unsigned = this.unsigned,
modules: Map<String, Module> = this.modules,
mainModuleId: String = this.mainModuleId,
mainFunction: String? = this.mainFunction,
version: String? = this.version,
): ZiplineManifest = copy(
unsigned = unsigned,
modules = modules,
mainModuleId = mainModuleId,
mainFunction = mainFunction,
version = version,
metadata = this.metadata,
)

fun copy(
signatures: Map<String, String> = this.signatures,
freshAtEpochMs: Long? = this.freshAtEpochMs,
Expand All @@ -116,7 +165,8 @@ data class ZiplineManifest private constructor(
mainModuleId: String = this.mainModuleId,
mainFunction: String? = this.mainFunction,
version: String? = this.version,
) = copy(
metadata: Map<String, String> = this.metadata,
): ZiplineManifest = copy(
unsigned = unsigned.copy(
freshAtEpochMs = freshAtEpochMs,
signatures = signatures,
Expand All @@ -126,6 +176,8 @@ data class ZiplineManifest private constructor(
mainModuleId = mainModuleId,
mainFunction = mainFunction,
version = version,
// Defensive copy!
metadata = metadata.toMap(),
)

/**
Expand All @@ -151,13 +203,37 @@ data class ZiplineManifest private constructor(
}

companion object {
@Deprecated(
message = "This is here for binary-compatibility only",
level = DeprecationLevel.HIDDEN,
)
fun create(
modules: Map<String, Module>,
mainFunction: String? = null,
mainModuleId: String? = null,
version: String? = null,
builtAtEpochMs: Long? = null,
baseUrl: String? = null,
): ZiplineManifest {
return create(
modules = modules,
mainFunction = mainFunction,
mainModuleId = mainModuleId,
version = version,
builtAtEpochMs = builtAtEpochMs,
baseUrl = baseUrl,
metadata = mapOf(),
)
}

fun create(
modules: Map<String, Module>,
mainFunction: String? = null,
mainModuleId: String? = null,
version: String? = null,
builtAtEpochMs: Long? = null,
baseUrl: String? = null,
metadata: Map<String, String> = mapOf(),
): ZiplineManifest {
val sortedModuleIds = modules.keys
.toList()
Expand All @@ -178,6 +254,8 @@ data class ZiplineManifest private constructor(
mainModuleId = mainModuleId ?: sortedModuleIds.last(),
mainFunction = mainFunction,
version = version,
// Defensive copy!
metadata = metadata.toMap(),
)
}

Expand Down
Loading
Loading