Skip to content

Commit 6e6e942

Browse files
authored
Merge pull request #16 from topheman/feat/add-go-support
Add Go Language Support for WebAssembly Component Model Plugins
2 parents bd811bd + f199ffb commit 6e6e942

File tree

23 files changed

+536
-21
lines changed

23 files changed

+536
-21
lines changed

.github/workflows/rust-host.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,24 @@ jobs:
2727
override: true
2828
- uses: cargo-bins/cargo-binstall@main
2929
- uses: extractions/setup-just@v3
30+
- uses: actions/setup-go@v5
31+
with:
32+
go-version: '1.25'
33+
- name: Install TinyGo Compiler
34+
run: |
35+
if [ "${{ runner.arch }}" = "X64" ]; then
36+
wget https://github.com/tinygo-org/tinygo/releases/download/v0.39.0/tinygo_0.39.0_amd64.deb
37+
sudo dpkg -i tinygo_0.39.0_amd64.deb
38+
else
39+
wget https://github.com/tinygo-org/tinygo/releases/download/v0.39.0/tinygo_0.39.0_armhf.deb
40+
sudo dpkg -i tinygo_0.39.0_armhf.deb
41+
fi
42+
export PATH=$PATH:/usr/local/bin
43+
- name: Check TinyGo Compiler
44+
run: tinygo version
45+
- name: Install wkg
46+
run: cargo binstall wkg
47+
3048
- name: Install cargo-component
3149
run: cargo binstall cargo-component@0.21.1
3250
- name: Install wasm-tools

.github/workflows/web-host.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,23 @@ jobs:
3030
node-version-file: .nvmrc
3131
- uses: cargo-bins/cargo-binstall@main
3232
- uses: extractions/setup-just@v3
33+
- uses: actions/setup-go@v5
34+
with:
35+
go-version: '1.25'
36+
- name: Install TinyGo Compiler
37+
run: |
38+
if [ "${{ runner.arch }}" = "X64" ]; then
39+
wget https://github.com/tinygo-org/tinygo/releases/download/v0.39.0/tinygo_0.39.0_amd64.deb
40+
sudo dpkg -i tinygo_0.39.0_amd64.deb
41+
else
42+
wget https://github.com/tinygo-org/tinygo/releases/download/v0.39.0/tinygo_0.39.0_armhf.deb
43+
sudo dpkg -i tinygo_0.39.0_armhf.deb
44+
fi
45+
export PATH=$PATH:/usr/local/bin
46+
- name: Check TinyGo Compiler
47+
run: tinygo version
48+
- name: Install wkg
49+
run: cargo binstall wkg
3350
- name: Install cargo-component
3451
run: cargo binstall cargo-component@0.21.1
3552
- name: Install wasm-tools

README.md

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ There are two kinds of hosts:
2323
Those hosts then run the same codebase which is compiled to WebAssembly:
2424

2525
- the REPL logic
26-
- the plugins (made a few in rust, C and TypeScript)
26+
- the plugins (made a few in rust, C, Go, and TypeScript)
2727

2828
Security model: the REPL cli implements a security model inspired by [deno](https://docs.deno.com/runtime/fundamentals/security/#permissions):
2929

@@ -84,6 +84,7 @@ pluginlab\
8484
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_cat.wasm\
8585
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_tee.wasm\
8686
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin-echo-c.wasm\
87+
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin-echo-go.wasm\
8788
--allow-all
8889
```
8990

@@ -109,6 +110,7 @@ pluginlab\
109110
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_cat.wasm\
110111
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_tee.wasm\
111112
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin-echo-c.wasm\
113+
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin-echo-go.wasm\
112114
--allow-all
113115
[Host] Starting REPL host...
114116
[Host] Loading REPL logic from: https://topheman.github.io/webassembly-component-model-experiments/plugins/repl_logic_guest.wasm
@@ -119,6 +121,7 @@ pluginlab\
119121
[Host] Loading plugin: https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_cat.wasm
120122
[Host] Loading plugin: https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_tee.wasm
121123
[Host] Loading plugin: https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin-echo-c.wasm
124+
[Host] Loading plugin: https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin-echo-go.wasm
122125
repl(0)> echo foo
123126
foo
124127
repl(0)> echo $ROOT/$USER
@@ -159,6 +162,7 @@ Go check [topheman.github.io/webassembly-component-model-experiments](https://to
159162

160163
- Rust 1.87+
161164
- Node.js 22.6.0+ (needs `--experimental-strip-types` flag)
165+
- Go 1.25+
162166
- [just](https://github.com/casey/just?tab=readme-ov-file#installation)
163167

164168
### Setup
@@ -199,6 +203,17 @@ cargo binstall wasm-tools@1.235.0
199203
just dl-wasi-sdk
200204
```
201205

206+
#### Go tooling
207+
208+
[From the WebAssembly Component Model section for Go tooling](https://component-model.bytecodealliance.org/language-support/go.html)
209+
210+
- Install [TinyGo](https://tinygo.org/getting-started/install/)
211+
- Install [wasm-tools](https://github.com/bytecodealliance/wasm-tools) - same as C
212+
- Install [wkg](https://github.com/bytecodealliance/wasm-pkg-tools)
213+
```bash
214+
cargo binstall wkg
215+
```
216+
202217
### pluginlab (rust) - REPL cli host
203218

204219
#### Build
@@ -226,13 +241,14 @@ This will (see [justfile](./justfile)):
226241
--plugins ./target/wasm32-wasip1/debug/plugin_cat.wasm\
227242
--plugins ./target/wasm32-wasip1/debug/plugin_tee.wasm\
228243
--plugins ./c_modules/plugin-echo/plugin-echo-c.wasm\
244+
--plugins ./go_modules/plugin-echo-go/plugin-echo-go.wasm\
229245
--allow-all
230246
```
231247

232248
This will run the `pluginlab` binary which will itself:
233249

234250
- load and compile the `repl_logic_guest.wasm` file inside the embedded `wasmtime` engine injecting the [`host-api`](./crates/pluginlab/wit/host-api.wit) interface
235-
- load and compile the `plugin_*.wasm` files into the engine, injecting the [`plugin-api`](./crates/pluginlab/wit/plugin-api.wit) interface
251+
- load and compile the `plugin*.wasm` files passed via `--plugins` into the engine, injecting the [`plugin-api`](./crates/pluginlab/wit/plugin-api.wit) interface
236252
- launch the REPL loop executing the code from the `repl_logic_guest.wasm` file which will:
237253
- readline from the user
238254
- parse the command
@@ -336,7 +352,7 @@ To be sure that the preview server is up and running before running the tests, w
336352

337353
### plugins
338354

339-
There are currently plugins implemented in 3 languages (most of them are in rust):
355+
There are currently plugins implemented in 3 languages (most of them are in rust), their toolchain is already setup in the project, you just have to write the plugin code and run `just build`.
340356

341357
#### Rust
342358

@@ -346,6 +362,10 @@ You can write plugins in rust in [`crates/plugin-*`](./crates).
346362

347363
You can write plugins in C in [`c_modules/plugin-*`](./c_modules), thanks to `wit-bindgen` (based on [wit-bindgen](https://github.com/bytecodealliance/wit-bindgen)).
348364

365+
#### Go
366+
367+
You can write plugins in Go in [`go_modules/plugin-*`](./go_modules), thanks to [TinyGo Compiler](https://tinygo.org/getting-started/install/).
368+
349369
#### TypeScript
350370

351371
You can also write plugins in TypeScript in [`packages/plugin-*`](./packages), thanks to `jco componentize` (based on [componentize-js](https://github.com/bytecodealliance/componentize-js)).
@@ -383,14 +403,15 @@ When a git tag is pushed, a pre-release is prepared on github, linked to the tag
383403

384404
```sh
385405
pluginlab\
386-
--repl-logic https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.0/repl_logic_guest.wasm\
387-
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.0/plugin_greet.wasm\
388-
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.0/plugin_ls.wasm\
389-
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.0/plugin_echo.wasm\
390-
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.0/plugin_weather.wasm\
391-
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.0/plugin_cat.wasm\
392-
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.0/plugin_tee.wasm\
393-
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.0/plugin-echo-c.wasm\
406+
--repl-logic https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.2/repl_logic_guest.wasm\
407+
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.2/plugin_greet.wasm\
408+
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.2/plugin_ls.wasm\
409+
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.2/plugin_echo.wasm\
410+
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.2/plugin_weather.wasm\
411+
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.2/plugin_cat.wasm\
412+
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.2/plugin_tee.wasm\
413+
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.2/plugin-echo-c.wasm\
414+
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.2/plugin-echo-go.wasm\
394415
--allow-all
395416
```
396417

@@ -444,3 +465,10 @@ cargo binstall cargo-component@0.21.1 wasm-tools@1.235.0 wasm-opt@116
444465
- [From the WebAssembly Component Model section for C tooling](https://component-model.bytecodealliance.org/language-support/c.html)
445466
- [WASI SDK](https://github.com/WebAssembly/wasi-sdk)
446467
- [WIT Bindgen](https://github.com/bytecodealliance/wit-bindgen)
468+
469+
### Go tooling
470+
471+
- [From the WebAssembly Component Model section for Go tooling](https://component-model.bytecodealliance.org/language-support/go.html)
472+
- [TinyGo Compiler](https://tinygo.org/getting-started/install/)
473+
- [wasm-tools](https://github.com/bytecodealliance/wasm-tools)
474+
- [wkg](https://github.com/bytecodealliance/wasm-pkg-tools)

crates/pluginlab/README.md

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ There are two kinds of hosts:
1818
Those hosts then run the same codebase which is compiled to WebAssembly:
1919

2020
- the REPL logic
21-
- the plugins (made a few in rust, C and TypeScript)
21+
- the plugins (made a few in rust, C, Go, and TypeScript)
2222

2323
Security model: the REPL cli implements a security model inspired by [deno](https://docs.deno.com/runtime/fundamentals/security/#permissions):
2424

@@ -63,6 +63,7 @@ pluginlab\
6363
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_cat.wasm\
6464
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_tee.wasm\
6565
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin-echo-c.wasm\
66+
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin-echo-go.wasm\
6667
--allow-all
6768
```
6869

@@ -88,6 +89,7 @@ pluginlab\
8889
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_cat.wasm\
8990
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_tee.wasm\
9091
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin-echo-c.wasm\
92+
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin-echo-go.wasm\
9193
--allow-all
9294
[Host] Starting REPL host...
9395
[Host] Loading REPL logic from: https://topheman.github.io/webassembly-component-model-experiments/plugins/repl_logic_guest.wasm
@@ -96,6 +98,9 @@ pluginlab\
9698
[Host] Loading plugin: https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_echo.wasm
9799
[Host] Loading plugin: https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_weather.wasm
98100
[Host] Loading plugin: https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_cat.wasm
101+
[Host] Loading plugin: https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_tee.wasm
102+
[Host] Loading plugin: https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin-echo-c.wasm
103+
[Host] Loading plugin: https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin-echo-go.wasm
99104
repl(0)> echo foo
100105
foo
101106
repl(0)> echo $ROOT/$USER
@@ -135,14 +140,15 @@ The plugins are also versioned in [github releases](https://github.com/topheman/
135140
<summary>Example of running the CLI host with old versions of the plugins (if you have an old version of <code>pluginlab</code></summary>
136141
<pre>
137142
pluginlab\
138-
--repl-logic https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.0/repl_logic_guest.wasm\
139-
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.0/plugin_greet.wasm\
140-
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.0/plugin_ls.wasm\
141-
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.0/plugin_echo.wasm\
142-
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.0/plugin_weather.wasm\
143-
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.0/plugin_cat.wasm\
144-
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.0/plugin_tee.wasm\
145-
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.0/plugin-echo-c.wasm\
143+
--repl-logic https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.2/repl_logic_guest.wasm\
144+
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.2/plugin_greet.wasm\
145+
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.2/plugin_ls.wasm\
146+
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.2/plugin_echo.wasm\
147+
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.2/plugin_weather.wasm\
148+
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.2/plugin_cat.wasm\
149+
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.2/plugin_tee.wasm\
150+
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.2/plugin-echo-c.wasm\
151+
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.2/plugin-echo-go.wasm\
146152
--allow-all
147153
</pre>
148154
</summary>
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
mod utils;
2+
3+
#[cfg(test)]
4+
mod e2e_go_plugins {
5+
6+
use crate::utils::*;
7+
8+
use rexpect::spawn;
9+
10+
const TEST_TIMEOUT: u64 = 10000;
11+
12+
/**
13+
* Lets us change the target directory for the plugins and repl logic.
14+
*
15+
* See the justfile for examples where we switch to testing both plugins from the filesystem and from the HTTP server.
16+
*/
17+
fn build_command(plugin_files: &[&str], repl_logic_file: &str) -> String {
18+
let prefix =
19+
std::env::var("WASM_TARGET_DIR").unwrap_or("target/wasm32-wasip1/debug".to_string());
20+
let mut command = String::from("target/debug/pluginlab");
21+
command.push_str(format!(" --repl-logic {}/{}", prefix, repl_logic_file).as_str());
22+
plugin_files.iter().for_each(|file| {
23+
command.push_str(format!(" --plugins {}", file).as_str());
24+
});
25+
println!("Running command: {}", command);
26+
command
27+
}
28+
29+
#[test]
30+
fn test_echo_plugin() {
31+
let project_root = find_project_root();
32+
println!("Setting current directory to: {:?}", project_root);
33+
std::env::set_current_dir(&project_root).unwrap();
34+
let mut session = spawn(
35+
&format!(
36+
"{} --dir tmp/filesystem --allow-read",
37+
&build_command(
38+
&["go_modules/plugin-echo/plugin-echo-go.wasm"],
39+
"repl_logic_guest.wasm"
40+
)
41+
),
42+
Some(TEST_TIMEOUT),
43+
)
44+
.expect("Can't launch pluginlab with plugin greet");
45+
46+
session
47+
.exp_string("[Host] Starting REPL host...")
48+
.expect("Didn't see startup message");
49+
session
50+
.exp_string("[Host] Loading plugin:")
51+
.expect("Didn't see plugin loading message");
52+
session
53+
.exp_string("repl(0)>")
54+
.expect("Didn't see REPL prompt");
55+
session
56+
.send_line("echogo hello")
57+
.expect("Failed to send command");
58+
session
59+
.exp_string("hello\r\nrepl(0)>")
60+
.expect("Didn't get expected output from echogo plugin");
61+
}
62+
}

crates/pluginlab/wit/plugin-api.wit

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ interface host-state-plugin {
2828
}
2929

3030
world plugin-api {
31+
// The wasip2 target of TinyGo assumes that the component is targeting wasi:cli/command@0.2.0 world (part of wasi:cli),
32+
// so it needs to include the imports from that world.
33+
// It's only included for the versions of the wit files destined for TinyGo.
34+
// include wasi:cli/imports@0.2.0; // SPECIFIC TinyGo - DO NOT CHANGE THIS LINE
3135
import http-client;
3236
import host-state-plugin;
3337
export plugin;

go_modules/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.wasm

go_modules/plugin-echo/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
internal
2+
*.wasm

go_modules/plugin-echo/go.mod

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
module webassembly-repl/plugin-echo
2+
3+
go 1.24
4+
5+
tool go.bytecodealliance.org/cmd/wit-bindgen-go
6+
7+
require (
8+
github.com/coreos/go-semver v0.3.1 // indirect
9+
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect
10+
github.com/klauspost/compress v1.18.0 // indirect
11+
github.com/opencontainers/go-digest v1.0.0 // indirect
12+
github.com/regclient/regclient v0.8.3 // indirect
13+
github.com/sirupsen/logrus v1.9.3 // indirect
14+
github.com/tetratelabs/wazero v1.9.0 // indirect
15+
github.com/ulikunitz/xz v0.5.12 // indirect
16+
github.com/urfave/cli/v3 v3.3.3 // indirect
17+
go.bytecodealliance.org v0.7.0 // indirect
18+
go.bytecodealliance.org/cm v0.3.0 // indirect
19+
golang.org/x/mod v0.24.0 // indirect
20+
golang.org/x/sys v0.33.0 // indirect
21+
)

0 commit comments

Comments
 (0)