• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 import com.vanniktech.maven.publish.JavadocJar.Empty
2 import com.vanniktech.maven.publish.KotlinMultiplatform
3 import com.vanniktech.maven.publish.MavenPublishBaseExtension
4 
<lambda>null5 plugins {
6   kotlin("multiplatform")
7   // TODO: Restore Dokka once this issue is resolved.
8   //     https://github.com/Kotlin/dokka/issues/3038
9   // id("org.jetbrains.dokka")
10   id("com.vanniktech.maven.publish.base")
11   id("build-support")
12   id("binary-compatibility-validator")
13 }
14 
<lambda>null15 kotlin {
16   configureOrCreateWasmPlatform(
17     js = false,
18     wasi = true,
19   )
20   sourceSets {
21     all {
22       languageSettings.optIn("kotlin.wasm.unsafe.UnsafeWasmMemoryApi")
23     }
24     val wasmWasiMain by getting {
25       dependencies {
26         implementation(projects.okio)
27       }
28     }
29     val wasmWasiTest by getting {
30       dependencies {
31         implementation(projects.okioTestingSupport)
32         implementation(libs.kotlin.test)
33       }
34     }
35   }
36 }
37 
<lambda>null38 configure<MavenPublishBaseExtension> {
39   // TODO: switch from 'Empty' to 'Dokka' once this issue is resolved.
40   //     https://github.com/Kotlin/dokka/issues/3038
41   configure(
42     KotlinMultiplatform(javadocJar = Empty()),
43   )
44 }
45 
46 /**
47  * Inspired by runner.mjs in kowasm, this rewrites the JavaScript bootstrap script to set up WASI.
48  *
49  * See also:
50  *  * https://github.com/kowasm/kowasm
51  *  * https://github.com/nodejs/node/blob/main/doc/api/wasi.md
52  *
53  * This task overwrites the output of `compileTestDevelopmentExecutableKotlinWasmWasi` and must run
54  * after that task. It must also run before the WASM test execution tasks that read this script.
55  *
56  * Note that this includes which file paths are exposed to the WASI sandbox.
57  */
<lambda>null58 val injectWasiInit by tasks.creating {
59   dependsOn("compileTestDevelopmentExecutableKotlinWasmWasi")
60   val moduleName = "${rootProject.name}-${project.name}-wasm-wasi-test"
61 
62   val entryPointMjs = File(
63     buildDir,
64     "compileSync/wasmWasi/test/testDevelopmentExecutable/kotlin/$moduleName.mjs"
65   )
66 
67   outputs.file(entryPointMjs)
68 
69   doLast {
70     val base = File(System.getProperty("java.io.tmpdir"), "okio-wasifilesystem-test")
71     val baseA = File(base, "a")
72     val baseB = File(base, "b")
73     base.mkdirs()
74     baseA.mkdirs()
75     baseB.mkdirs()
76 
77     entryPointMjs.writeText(
78       """
79       import { WASI } from 'wasi';
80       import { argv, env } from 'node:process';
81 
82       const wasi = new WASI({
83         version: 'preview1',
84         args: argv,
85         preopens: {
86           '/tmp': '$base',
87           '/a': '$baseA',
88           '/b': '$baseB'
89         },
90         env,
91       });
92 
93       const fs = await import('node:fs');
94       const url = await import('node:url');
95       const wasmBuffer = fs.readFileSync(url.fileURLToPath(import.meta.resolve('./okio-parent-okio-wasifilesystem-wasm-wasi-test.wasm')));
96       const wasmModule = new WebAssembly.Module(wasmBuffer);
97       const wasmInstance = new WebAssembly.Instance(wasmModule, wasi.getImportObject());
98 
99       wasi.initialize(wasmInstance);
100 
101       const exports = wasmInstance.exports
102 
103       export default new Proxy(exports, {
104           _shownError: false,
105           get(target, prop) {
106               if (!this._shownError) {
107                   this._shownError = true;
108                   throw new Error("Do not use default import. Use the corresponding named import instead.")
109               }
110           }
111       });
112       export const {
113           startUnitTests,
114           _initialize,
115           memory
116       } = exports;
117       """.trimIndent()
118     )
119   }
120 }
<lambda>null121 tasks.named("wasmWasiNodeTest").configure {
122   dependsOn(injectWasiInit)
123 }
124