Skip to content

Commit 87e46ae

Browse files
authored
Merge pull request #11 from topheman/release-branch-pluginlab@0.5.0
Add plugin-tee and introduce breaking WIT changes for enhanced plugin capabilities
2 parents 32d6758 + 1ce3c75 commit 87e46ae

26 files changed

+463
-68
lines changed

.cursor/rules/git-commands.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Git Commands
2+
3+
Always use `--no-abbrev-commit` and proper formatting flags for all git terminal commands to avoid shell parsing issues.
4+
5+
## Specific Commands to Use:
6+
7+
**Instead of:**
8+
```bash
9+
git log --oneline
10+
git show --stat HEAD
11+
git branch -v
12+
```
13+
14+
**Use:**
15+
```bash
16+
git log --pretty=format:"%h %s" --no-abbrev-commit
17+
git show --stat --no-abbrev-commit HEAD
18+
git branch --show-current
19+
```
20+
21+
## Key Flags:
22+
- `--no-abbrev-commit` - Prevents abbreviated commit hashes
23+
- `--pretty=format:"..."` - Use explicit formatting
24+
- `--porcelain` - For cleaner output when available
25+
- `--no-color` - Remove ANSI color codes
26+
- `--show-current` - For branch operations
27+
28+
## Common Patterns:
29+
- `git log master..HEAD``git log --pretty=format:"%h %s" --no-abbrev-commit master..HEAD`
30+
- `git status``git status --porcelain`
31+
- `git diff --name-only master``git diff --name-only master`

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ members = [
77
"crates/plugin-ls",
88
"crates/plugin-cat",
99
"crates/plugin-weather",
10+
"crates/plugin-tee",
1011
"crates/repl-logic-guest",
1112
]
1213

README.md

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ pluginlab\
8282
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_echo.wasm\
8383
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_weather.wasm\
8484
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_cat.wasm\
85+
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_tee.wasm\
8586
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin-echo-c.wasm\
8687
--allow-all
8788
```
@@ -106,6 +107,7 @@ pluginlab\
106107
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_echo.wasm\
107108
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_weather.wasm\
108109
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_cat.wasm\
110+
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_tee.wasm\
109111
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin-echo-c.wasm\
110112
--allow-all
111113
[Host] Starting REPL host...
@@ -115,6 +117,8 @@ pluginlab\
115117
[Host] Loading plugin: https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_echo.wasm
116118
[Host] Loading plugin: https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_weather.wasm
117119
[Host] Loading plugin: https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_cat.wasm
120+
[Host] Loading plugin: https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_tee.wasm
121+
[Host] Loading plugin: https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin-echo-c.wasm
118122
repl(0)> echo foo
119123
foo
120124
repl(0)> echo $ROOT/$USER
@@ -220,6 +224,7 @@ This will (see [justfile](./justfile)):
220224
--plugins ./target/wasm32-wasip1/debug/plugin_echo.wasm\
221225
--plugins ./target/wasm32-wasip1/debug/plugin_weather.wasm\
222226
--plugins ./target/wasm32-wasip1/debug/plugin_cat.wasm\
227+
--plugins ./target/wasm32-wasip1/debug/plugin_tee.wasm\
223228
--plugins ./c_modules/plugin-echo/plugin-echo-c.wasm\
224229
--allow-all
225230
```
@@ -378,13 +383,14 @@ When a git tag is pushed, a pre-release is prepared on github, linked to the tag
378383

379384
```sh
380385
pluginlab\
381-
--repl-logic https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.4.1/repl_logic_guest.wasm\
382-
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.4.1/plugin_greet.wasm\
383-
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.4.1/plugin_ls.wasm\
384-
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.4.1/plugin_echo.wasm\
385-
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.4.1/plugin_weather.wasm\
386-
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.4.1/plugin_cat.wasm\
387-
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.4.1/plugin-echo-c.wasm\
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\
388394
--allow-all
389395
```
390396

crates/plugin-tee/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
src/bindings.rs

crates/plugin-tee/Cargo.toml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[package]
2+
name = "plugin-tee"
3+
version = "0.1.0"
4+
edition = { workspace = true }
5+
publish = false
6+
description = "Example tee plugin for REPL based on WebAssembly Component Model - demonstrates file system access and modification"
7+
8+
[dependencies]
9+
wit-bindgen-rt = { workspace = true, features = ["bitflags"] }
10+
11+
[lib]
12+
crate-type = ["cdylib"]
13+
14+
[package.metadata.component]
15+
package = "repl:api"
16+
target = { path = "../pluginlab/wit", world = "plugin-api" }
17+
18+
[package.metadata.component.dependencies]

crates/plugin-tee/README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# plugin-tee
2+
3+
Basic plugin for this REPL. Behaves like the `tee` command.
4+
5+
## Notes
6+
7+
This crate was initialized with `cargo component new`.
8+
9+
The building process is handled by the [`justfile`](../../justfile) in the root of the project.
10+
11+
The `cargo component build` command is used to build the plugin.
12+
13+
- It generates the `src/bindings.rs` file, based on the `package.metadata.component` section in the `Cargo.toml` file that describes where to find the component definition (wit files).
14+
- It then compiles the plugin to WebAssembly.

crates/plugin-tee/src/lib.rs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#[allow(warnings)]
2+
mod bindings;
3+
4+
use std::io::Write;
5+
6+
use crate::bindings::exports::repl::api::plugin::Guest;
7+
use crate::bindings::repl::api::host_state_plugin;
8+
use crate::bindings::repl::api::transport;
9+
10+
struct Component;
11+
12+
impl Guest for Component {
13+
fn name() -> String {
14+
"tee".to_string()
15+
}
16+
17+
fn man() -> String {
18+
r#"
19+
NAME
20+
tee - Copy $0 content to a file (built with Rust🦀)
21+
22+
USAGE
23+
tee <file>
24+
tee -a <file>
25+
26+
OPTIONS
27+
-a, --append Append to the file instead of overwriting it
28+
29+
DESCRIPTION
30+
Copy $0 content to a file.
31+
32+
"#
33+
.to_string()
34+
}
35+
36+
fn run(payload: String) -> Result<transport::PluginResponse, ()> {
37+
match run_inner(payload) {
38+
Ok(content) => Ok(transport::PluginResponse {
39+
status: transport::ReplStatus::Success,
40+
stdout: Some(format!("{}", content)),
41+
stderr: None,
42+
}),
43+
Err(e) => {
44+
// e.kind() - verify if the error is a permission error
45+
return Ok(transport::PluginResponse {
46+
status: transport::ReplStatus::Error,
47+
stdout: None,
48+
stderr: Some(format!("{}", e)),
49+
});
50+
}
51+
}
52+
}
53+
}
54+
55+
fn run_inner(payload: String) -> Result<String, String> {
56+
let is_append = payload.starts_with("-a") || payload.starts_with("--append");
57+
let filepath = if is_append {
58+
let Some((_, filepath)) = payload.split_once(" ") else {
59+
return Err("Invalid arguments. Usage: tee <file> or tee -a <file>".to_string());
60+
};
61+
filepath.to_string()
62+
} else {
63+
payload
64+
};
65+
66+
let content = host_state_plugin::get_repl_var("0").unwrap_or("".to_string());
67+
let content_as_bytes = content.as_bytes();
68+
69+
if !is_append {
70+
let mut file = std::fs::File::create(&filepath)
71+
.map_err(|e| enhanced_error(e, format!("Failed to create file '{}'", filepath)))?;
72+
file.write_all(content_as_bytes)
73+
.map_err(|e| enhanced_error(e, format!("Failed to write to file '{}'", filepath)))?;
74+
return Ok(content);
75+
} else {
76+
let mut file = std::fs::File::options()
77+
.append(true)
78+
.open(&filepath)
79+
.map_err(|e| {
80+
enhanced_error(
81+
e,
82+
format!("Failed to open file in append mode '{}'", filepath),
83+
)
84+
})?;
85+
// Add a newline before the content in append mode
86+
file.write_all(b"\n").map_err(|e| {
87+
enhanced_error(e, format!("Failed to write newline to file '{}'", filepath))
88+
})?;
89+
file.write_all(content_as_bytes)
90+
.map_err(|e| enhanced_error(e, format!("Failed to write to file '{}'", filepath)))?;
91+
return Ok(content);
92+
}
93+
}
94+
95+
fn enhanced_error(e: std::io::Error, more_info: String) -> String {
96+
format!("{} - {} - {}", e.kind(), more_info, e.to_string())
97+
}
98+
99+
bindings::export!(Component with_types_in bindings);

crates/pluginlab/README.md

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ pluginlab\
6161
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_echo.wasm\
6262
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_weather.wasm\
6363
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_cat.wasm\
64+
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_tee.wasm\
6465
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin-echo-c.wasm\
6566
--allow-all
6667
```
@@ -85,6 +86,7 @@ pluginlab\
8586
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_echo.wasm\
8687
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_weather.wasm\
8788
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_cat.wasm\
89+
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin_tee.wasm\
8890
--plugins https://topheman.github.io/webassembly-component-model-experiments/plugins/plugin-echo-c.wasm\
8991
--allow-all
9092
[Host] Starting REPL host...
@@ -133,13 +135,14 @@ The plugins are also versioned in [github releases](https://github.com/topheman/
133135
<summary>Example of running the CLI host with old versions of the plugins (if you have an old version of <code>pluginlab</code></summary>
134136
<pre>
135137
pluginlab\
136-
--repl-logic https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.4.1/repl_logic_guest.wasm\
137-
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.4.1/plugin_greet.wasm\
138-
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.4.1/plugin_ls.wasm\
139-
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.4.1/plugin_echo.wasm\
140-
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.4.1/plugin_weather.wasm\
141-
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.4.1/plugin_cat.wasm\
142-
--plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.4.1/plugin-echo-c.wasm\
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\
143146
--allow-all
144147
</pre>
145148
</summary>
@@ -163,7 +166,7 @@ pluginlab\
163166
[Host] You are most likely trying to use a plugin not compatible with pluginlab@0.4.1
164167
[Host]
165168
[Host] Try using a compatible version of the plugin by passing the following flag:
166-
[Host] --plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.4.1/plugin_echo.wasm
169+
[Host] --plugins https://github.com/topheman/webassembly-component-model-experiments/releases/download/pluginlab@0.5.0/plugin_echo.wasm
167170
[Host]
168171
[Host] If it doesn't work, make sure to use the latest version of pluginlab: `cargo install pluginlab`
169172
[Host]

crates/pluginlab/src/engine.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::cli::Cli;
22
use crate::permissions::NetworkPermissions;
33
use anyhow::Result;
4-
use std::collections::HashMap;
4+
55
use std::path::Path;
66
use wasmtime::component::{Component, Linker as ComponentLinker, ResourceTable};
77
use wasmtime::{Config, Engine, Store};
@@ -120,15 +120,19 @@ impl WasmEngine {
120120

121121
/// Create a new store with WASI context
122122
pub fn create_store(&self, wasi_ctx: WasiCtx, cli: &Cli) -> Store<WasiState> {
123+
let repl_vars =
124+
std::sync::Arc::new(std::sync::Mutex::new(std::collections::HashMap::new()));
125+
123126
Store::new(
124127
&self.engine,
125128
WasiState {
126129
ctx: wasi_ctx,
127130
table: ResourceTable::new(),
128131
plugin_host: PluginHost {
129132
network_permissions: NetworkPermissions::from(cli),
133+
repl_vars: repl_vars.clone(),
130134
},
131-
repl_vars: HashMap::new(),
135+
repl_vars,
132136
plugins_names: Vec::new(),
133137
},
134138
)

0 commit comments

Comments
 (0)