Skip to content

Make PluginBundleSource.fromZipFile multiplatform #475

@wow-miley

Description

@wow-miley

Context

#463 shipped the Plugin bundle format with two okio-backed source factories: PluginBundleSource.fromDirectory (commonMain) and PluginBundleSource.fromZipFile (jvmMain). The split is forced by okio 3.11: FileSystem.openZip is declared in jvmMain only, so fromZipFile cannot live in commonMain today.

The practical impact is that iOS and Native consumers must unpack a ZIP bundle to a directory before importing it. This is acceptable for W0/W1 because the marketplace (W1.10) and share-sheet import (W1.11) currently target Desktop/Android first, both of which run on the JVM target. Once iOS or Native becomes a first-class import surface, the unpack step becomes user-visible friction we should remove.

Current state

File Purpose
ampere-core/src/commonMain/kotlin/link/socket/ampere/bundle/OkioPluginBundleSource.kt OkioPluginBundleSource class + PluginBundleSource.fromDirectory extension. Already commonMain — no work needed beyond the move below.
ampere-core/src/jvmMain/kotlin/link/socket/ampere/bundle/PluginBundleSource.jvm.kt PluginBundleSource.fromZipFile extension that calls FileSystem.openZip. This file is the entirety of the platform split.
ampere-core/src/jvmTest/kotlin/link/socket/ampere/bundle/OkioPluginBundleSourceTest.kt Includes ZIP fixtures built with java.util.zip.ZipOutputStream. JVM-only ZIP construction means these tests can't move to commonTest as-is.

Preconditions for picking this up

Do not start work until at least one of these is true. If none hold, the ticket is still blocked even if the schedule says it's ready.

  1. Multiplatform openZip is available. Track square/okio#1163 and the okio changelog. The trigger is a release where FileSystem.openZip is declared in commonMain (or in iosMain + jvmMain such that both targets can call it without a jvmMain shim). Verify by reading the release notes and confirming no expect/actual is needed in this project.
  2. A vetted multiplatform alternative is adopted. A KMP-friendly ZIP reader (e.g. a future kotlinx-io-zip, or a vendored minimal reader in this repo) covers JVM, Android, iOS, and Native with read-only entry enumeration and byte access. "Vetted" means: a security review of the unzip path (zip-slip, zip-bomb, deflate-bomb) has been completed and documented.
  3. A concrete iOS or Native consumer exists. The marketplace UI or share-sheet importer on iOS/Native is actively shipping and the unpack-to-directory step has been measured to be a real ergonomic or performance problem. This guards against doing the work speculatively.

If only (3) is true and (1)/(2) are not, the right next step is not this ticket — open a separate spike to evaluate ZIP-reader options first.

Tasks

  1. Move fromZipFile from jvmMain/.../bundle/PluginBundleSource.jvm.kt to commonMain/.../bundle/OkioPluginBundleSource.kt.
  2. Delete jvmMain/.../bundle/PluginBundleSource.jvm.kt.
  3. Update the implementation to use whichever multiplatform ZIP API satisfied the precondition. If switching off okio, also update OkioPluginBundleSource (or rename the file) to reflect the new backing.
  4. Update docs/ampere/plugin-bundle-format.md: the "Reading a bundle" table currently lists fromZipFile as jvmMain — make it commonMain and drop the JVM-only caveat.
  5. Move the ZIP construction helper out of OkioPluginBundleSourceTest into a commonTest fixture, OR add an iOS-side smoke test that loads a vendored .zip fixture committed under ampere-core/src/commonTest/resources/ (or platform-equivalent). Building ZIPs at test time on iOS is awkward; vendoring a small fixture is usually simpler.
  6. Add at least one iOS test that parses a ZIP bundle end-to-end via PluginBundleSource.fromZipFilePluginBundleParser.parseBundleParseResult.Ok.

Validation

  • ./gradlew jvmTest and ./gradlew iosSimulatorArm64Test (or whichever iOS test target the project is using) both pass with the moved factory.
  • No file remains under ampere-core/src/jvmMain/kotlin/link/socket/ampere/bundle/.
  • The dir-vs-ZIP entry parity assertion in OkioPluginBundleSourceTest (fromZipFile entries are keyed identically to fromDirectory) runs on both JVM and at least one non-JVM target.
  • Spec doc no longer mentions a JVM-only ZIP path.
  • No new dependencies were added without a security note in the PR description if (2) was the precondition that unblocked this work.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions