Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
57 changes: 55 additions & 2 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,59 @@ env:
WASI_SDK_RELEASE: wasi-sockets-alpha-5

jobs:
linux:
name: Populate cache
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: "recursive"

- uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install latest Rust nightly toolchain
uses: dtolnay/rust-toolchain@nightly
with:
targets: wasm32-wasip1 wasm32-unknown-unknown

- name: Install latest Rust stable toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-wasip1 wasm32-unknown-unknown
components: clippy, rustfmt

- name: Install Rust std source
shell: bash
run: rustup component add rust-src --toolchain nightly

- uses: Swatinem/rust-cache@v2
with:
shared-key: "rust-cache-${{ hashFiles('./Cargo.lock') }}"
cache-on-failure: false

- name: Install WASI-SDK
shell: bash
run: |
cd /tmp
curl -LO https://github.com/dicej/wasi-sdk/releases/download/${WASI_SDK_RELEASE}/wasi-sdk-${WASI_SDK_VERSION}-linux.tar.gz
tar xf wasi-sdk-${WASI_SDK_VERSION}-linux.tar.gz
mv wasi-sdk-${WASI_SDK_VERSION} /opt/wasi-sdk

- name: Cache CPython
id: cache-cpython-wasi
uses: actions/cache@v4
with:
path: cpython/builddir/wasi
key: cpython-wasi
enableCrossOsArchive: true

- name: Build
shell: bash
run: cargo build --release

test:
name: Test
strategy:
Expand Down Expand Up @@ -67,9 +120,9 @@ jobs:
shell: bash
run: echo "WASI_SDK_PATH=$(cygpath -m /tmp/wasi-sdk-${WASI_SDK_VERSION})" >> ${GITHUB_ENV}

- name: Cache CPython
- name: Restore CPython
id: cache-cpython-wasi
uses: actions/cache@v4
uses: actions/cache/restore@v4
with:
path: cpython/builddir/wasi
key: cpython-wasi
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "componentize-py"
version = "0.15.2"
version = "0.16.0"
edition = "2021"
exclude = ["cpython"]

Expand Down
4 changes: 2 additions & 2 deletions examples/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ run a Python-based component targetting the [wasi-cli] `command` world.
## Prerequisites

* `Wasmtime` 26.0.0 or later
* `componentize-py` 0.15.2
* `componentize-py` 0.16.0

Below, we use [Rust](https://rustup.rs/)'s `cargo` to install `Wasmtime`. If
you don't have `cargo`, you can download and install from
https://github.com/bytecodealliance/wasmtime/releases/tag/v26.0.0.

```
cargo install --version 26.0.0 wasmtime-cli
pip install componentize-py==0.15.2
pip install componentize-py==0.16.0
```

## Running the demo
Expand Down
4 changes: 2 additions & 2 deletions examples/http/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ run a Python-based component targetting the [wasi-http] `proxy` world.
## Prerequisites

* `Wasmtime` 26.0.0 or later
* `componentize-py` 0.15.2
* `componentize-py` 0.16.0

Below, we use [Rust](https://rustup.rs/)'s `cargo` to install `Wasmtime`. If
you don't have `cargo`, you can download and install from
https://github.com/bytecodealliance/wasmtime/releases/tag/v26.0.0.

```
cargo install --version 26.0.0 wasmtime-cli
pip install componentize-py==0.15.2
pip install componentize-py==0.16.0
```

## Running the demo
Expand Down
4 changes: 2 additions & 2 deletions examples/matrix-math/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ within a guest component.
## Prerequisites

* `wasmtime` 26.0.0 or later
* `componentize-py` 0.15.2
* `componentize-py` 0.16.0
* `NumPy`, built for WASI

Note that we use an unofficial build of NumPy since the upstream project does
Expand All @@ -23,7 +23,7 @@ https://github.com/bytecodealliance/wasmtime/releases/tag/v26.0.0.

```
cargo install --version 26.0.0 wasmtime-cli
pip install componentize-py==0.15.2
pip install componentize-py==0.16.0
curl -OL https://github.com/dicej/wasi-wheels/releases/download/v0.0.1/numpy-wasi.tar.gz
tar xf numpy-wasi.tar.gz
```
Expand Down
4 changes: 2 additions & 2 deletions examples/sandbox/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ sandboxed Python code snippets from within a Python app.
## Prerequisites

* `wasmtime-py` 25.0.0 or later
* `componentize-py` 0.15.2
* `componentize-py` 0.16.0

```
pip install componentize-py==0.15.2 wasmtime==25.0.0
pip install componentize-py==0.16.0 wasmtime==25.0.0
```

## Running the demo
Expand Down
4 changes: 2 additions & 2 deletions examples/tcp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ making an outbound TCP request using `wasi-sockets`.
## Prerequisites

* `Wasmtime` 26.0.0 or later
* `componentize-py` 0.15.2
* `componentize-py` 0.16.0

Below, we use [Rust](https://rustup.rs/)'s `cargo` to install `Wasmtime`. If
you don't have `cargo`, you can download and install from
https://github.com/bytecodealliance/wasmtime/releases/tag/v26.0.0.

```
cargo install --version 26.0.0 wasmtime-cli
pip install componentize-py==0.15.2
pip install componentize-py==0.16.0
```

## Running the demo
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ features = ["pyo3/extension-module"]

[project]
name = "componentize-py"
version = "0.15.2"
version = "0.16.0"
description = "Tool to package Python applications as WebAssembly components"
readme = "README.md"
license = { file = "LICENSE" }
Expand Down
50 changes: 48 additions & 2 deletions src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,24 @@ pub struct Common {
/// This enables using `@unstable` annotations in WIT files.
#[clap(long)]
all_features: bool,

/// Specify names to use for imported interfaces. May be specified more than once.
///
/// By default, the python module name generated for a given interface will be the snake-case form of the WIT
/// interface name, possibly qualified with the package name and namespace and/or version if that name would
/// otherwise clash with another interface. With this option, you may override that name with your own, unique
/// name.
#[arg(long, value_parser = parse_key_value)]
pub import_interface_name: Vec<(String, String)>,

/// Specify names to use for exported interfaces. May be specified more than once.
///
/// By default, the python module name generated for a given interface will be the snake-case form of the WIT
/// interface name, possibly qualified with the package name and namespace and/or version if that name would
/// otherwise clash with another interface. With this option, you may override that name with your own, unique
/// name.
#[arg(long, value_parser = parse_key_value)]
pub export_interface_name: Vec<(String, String)>,
}

#[derive(clap::Subcommand, Debug)]
Expand Down Expand Up @@ -82,7 +100,7 @@ pub struct Componentize {
///
/// Note that these must be specified in topological order (i.e. if a module containing WIT files depends on
/// other modules containing WIT files, it must be listed after all its dependencies).
#[arg(short = 'm', long, value_parser = parse_module_world)]
#[arg(short = 'm', long, value_parser = parse_key_value)]
pub module_worlds: Vec<(String, String)>,

/// Output file to which to write the resulting component
Expand Down Expand Up @@ -112,7 +130,7 @@ pub struct Bindings {
pub world_module: Option<String>,
}

fn parse_module_world(s: &str) -> Result<(String, String), String> {
fn parse_key_value(s: &str) -> Result<(String, String), String> {
let (k, v) = s
.split_once('=')
.ok_or_else(|| format!("expected string of form `<key>=<value>`; got `{s}`"))?;
Expand All @@ -137,6 +155,16 @@ fn generate_bindings(common: Common, bindings: Bindings) -> Result<()> {
common.all_features,
bindings.world_module.as_deref(),
&bindings.output_dir,
&common
.import_interface_name
.iter()
.map(|(a, b)| (a.as_str(), b.as_str()))
.collect(),
&common
.export_interface_name
.iter()
.map(|(a, b)| (a.as_str(), b.as_str()))
.collect(),
)
}

Expand Down Expand Up @@ -167,6 +195,16 @@ fn componentize(common: Common, componentize: Componentize) -> Result<()> {
&componentize.output,
None,
componentize.stub_wasi,
&common
.import_interface_name
.iter()
.map(|(a, b)| (a.as_str(), b.as_str()))
.collect(),
&common
.export_interface_name
.iter()
.map(|(a, b)| (a.as_str(), b.as_str()))
.collect(),
))?;

if !common.quiet {
Expand Down Expand Up @@ -300,6 +338,8 @@ mod tests {
quiet: false,
features: vec![],
all_features: false,
import_interface_name: Vec::new(),
export_interface_name: Vec::new(),
};
let bindings = Bindings {
output_dir: out_dir.path().into(),
Expand Down Expand Up @@ -328,6 +368,8 @@ mod tests {
quiet: false,
features: vec!["x".to_owned()],
all_features: false,
import_interface_name: Vec::new(),
export_interface_name: Vec::new(),
};
let bindings = Bindings {
output_dir: out_dir.path().into(),
Expand Down Expand Up @@ -356,6 +398,8 @@ mod tests {
quiet: false,
features: vec![],
all_features: true,
import_interface_name: Vec::new(),
export_interface_name: Vec::new(),
};
let bindings = Bindings {
output_dir: out_dir.path().into(),
Expand All @@ -382,6 +426,8 @@ mod tests {
quiet: false,
features: vec!["x".to_owned()],
all_features: false,
import_interface_name: Vec::new(),
export_interface_name: Vec::new(),
};
let bindings = Bindings {
output_dir: out_dir.path().into(),
Expand Down
Loading