Skip to content

Commit 528a3a0

Browse files
authored
optionally override module names; bump version to 0.16.0 (#128)
* optionally override module names; bump version to 0.16.0 This adds CLI and componentize-py.toml options for overriding the generated Python module names for one or more WIT interfaces. By default, the name is the snake-case version of the WIT name, qualified as necessary with the package namespace and name and/or the version in cases of ambiguity. Sometimes that's not what you want, though, so now you can override the naming on an individual basis as long as the name(s) you pick are unique. This can be especially useful for backwards compatibility when adding new versions of WIT interfaces. In that case, the generated module name may go from unqualified to qualified, but you can now force the name of the original version to be unqualified for compatibility. For example: - You release an SDK with an interface called `foo:bar/baz@1.0.0`. Since that's the only interface with the name `baz`, `componentize-py` will name the generated module `baz` also. - Later, you release a new version of the SDK with support for _both_ `foo:bar/baz@1.0.0` _and_ `foo:bar/baz@2.0.0`. In that case, `componentize-py` will name the generated modules `foo_bar_baz_1_0_0` and `foo_bar_baz_2_0_0` by default. However, you don't want to force users of your SDK to use the new name, so you pass `--import-interface-name foo:bar/baz@1.0.0=baz` to `componentize-py`, which tells it to use the original name. Signed-off-by: Joel Dice <joel.dice@fermyon.com> * build and cache CPython once in test.yaml i.e. match what we're doing in release.yaml. TODO: Factor out the "Populate cache" job into a reusable action instead of cut-and-pasting it. Signed-off-by: Joel Dice <joel.dice@fermyon.com> --------- Signed-off-by: Joel Dice <joel.dice@fermyon.com>
1 parent fc16d0c commit 528a3a0

File tree

15 files changed

+225
-31
lines changed

15 files changed

+225
-31
lines changed

.github/workflows/test.yaml

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,59 @@ env:
1414
WASI_SDK_RELEASE: wasi-sockets-alpha-5
1515

1616
jobs:
17+
linux:
18+
name: Populate cache
19+
runs-on: ubuntu-latest
20+
steps:
21+
- name: Checkout
22+
uses: actions/checkout@v4
23+
with:
24+
submodules: "recursive"
25+
26+
- uses: actions/setup-python@v5
27+
with:
28+
python-version: "3.12"
29+
30+
- name: Install latest Rust nightly toolchain
31+
uses: dtolnay/rust-toolchain@nightly
32+
with:
33+
targets: wasm32-wasip1 wasm32-unknown-unknown
34+
35+
- name: Install latest Rust stable toolchain
36+
uses: dtolnay/rust-toolchain@stable
37+
with:
38+
targets: wasm32-wasip1 wasm32-unknown-unknown
39+
components: clippy, rustfmt
40+
41+
- name: Install Rust std source
42+
shell: bash
43+
run: rustup component add rust-src --toolchain nightly
44+
45+
- uses: Swatinem/rust-cache@v2
46+
with:
47+
shared-key: "rust-cache-${{ hashFiles('./Cargo.lock') }}"
48+
cache-on-failure: false
49+
50+
- name: Install WASI-SDK
51+
shell: bash
52+
run: |
53+
cd /tmp
54+
curl -LO https://github.com/dicej/wasi-sdk/releases/download/${WASI_SDK_RELEASE}/wasi-sdk-${WASI_SDK_VERSION}-linux.tar.gz
55+
tar xf wasi-sdk-${WASI_SDK_VERSION}-linux.tar.gz
56+
mv wasi-sdk-${WASI_SDK_VERSION} /opt/wasi-sdk
57+
58+
- name: Cache CPython
59+
id: cache-cpython-wasi
60+
uses: actions/cache@v4
61+
with:
62+
path: cpython/builddir/wasi
63+
key: cpython-wasi
64+
enableCrossOsArchive: true
65+
66+
- name: Build
67+
shell: bash
68+
run: cargo build --release
69+
1770
test:
1871
name: Test
1972
strategy:
@@ -67,9 +120,9 @@ jobs:
67120
shell: bash
68121
run: echo "WASI_SDK_PATH=$(cygpath -m /tmp/wasi-sdk-${WASI_SDK_VERSION})" >> ${GITHUB_ENV}
69122

70-
- name: Cache CPython
123+
- name: Restore CPython
71124
id: cache-cpython-wasi
72-
uses: actions/cache@v4
125+
uses: actions/cache/restore@v4
73126
with:
74127
path: cpython/builddir/wasi
75128
key: cpython-wasi

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "componentize-py"
3-
version = "0.15.2"
3+
version = "0.16.0"
44
edition = "2021"
55
exclude = ["cpython"]
66

examples/cli/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ run a Python-based component targetting the [wasi-cli] `command` world.
1010
## Prerequisites
1111

1212
* `Wasmtime` 26.0.0 or later
13-
* `componentize-py` 0.15.2
13+
* `componentize-py` 0.16.0
1414

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

1919
```
2020
cargo install --version 26.0.0 wasmtime-cli
21-
pip install componentize-py==0.15.2
21+
pip install componentize-py==0.16.0
2222
```
2323

2424
## Running the demo

examples/http/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ run a Python-based component targetting the [wasi-http] `proxy` world.
1010
## Prerequisites
1111

1212
* `Wasmtime` 26.0.0 or later
13-
* `componentize-py` 0.15.2
13+
* `componentize-py` 0.16.0
1414

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

1919
```
2020
cargo install --version 26.0.0 wasmtime-cli
21-
pip install componentize-py==0.15.2
21+
pip install componentize-py==0.16.0
2222
```
2323

2424
## Running the demo

examples/matrix-math/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ within a guest component.
1111
## Prerequisites
1212

1313
* `wasmtime` 26.0.0 or later
14-
* `componentize-py` 0.15.2
14+
* `componentize-py` 0.16.0
1515
* `NumPy`, built for WASI
1616

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

2424
```
2525
cargo install --version 26.0.0 wasmtime-cli
26-
pip install componentize-py==0.15.2
26+
pip install componentize-py==0.16.0
2727
curl -OL https://github.com/dicej/wasi-wheels/releases/download/v0.0.1/numpy-wasi.tar.gz
2828
tar xf numpy-wasi.tar.gz
2929
```

examples/sandbox/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ sandboxed Python code snippets from within a Python app.
88
## Prerequisites
99

1010
* `wasmtime-py` 25.0.0 or later
11-
* `componentize-py` 0.15.2
11+
* `componentize-py` 0.16.0
1212

1313
```
14-
pip install componentize-py==0.15.2 wasmtime==25.0.0
14+
pip install componentize-py==0.16.0 wasmtime==25.0.0
1515
```
1616

1717
## Running the demo

examples/tcp/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ making an outbound TCP request using `wasi-sockets`.
1111
## Prerequisites
1212

1313
* `Wasmtime` 26.0.0 or later
14-
* `componentize-py` 0.15.2
14+
* `componentize-py` 0.16.0
1515

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

2020
```
2121
cargo install --version 26.0.0 wasmtime-cli
22-
pip install componentize-py==0.15.2
22+
pip install componentize-py==0.16.0
2323
```
2424

2525
## Running the demo

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ features = ["pyo3/extension-module"]
77

88
[project]
99
name = "componentize-py"
10-
version = "0.15.2"
10+
version = "0.16.0"
1111
description = "Tool to package Python applications as WebAssembly components"
1212
readme = "README.md"
1313
license = { file = "LICENSE" }

src/command.rs

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,24 @@ pub struct Common {
4848
/// This enables using `@unstable` annotations in WIT files.
4949
#[clap(long)]
5050
all_features: bool,
51+
52+
/// Specify names to use for imported interfaces. May be specified more than once.
53+
///
54+
/// By default, the python module name generated for a given interface will be the snake-case form of the WIT
55+
/// interface name, possibly qualified with the package name and namespace and/or version if that name would
56+
/// otherwise clash with another interface. With this option, you may override that name with your own, unique
57+
/// name.
58+
#[arg(long, value_parser = parse_key_value)]
59+
pub import_interface_name: Vec<(String, String)>,
60+
61+
/// Specify names to use for exported interfaces. May be specified more than once.
62+
///
63+
/// By default, the python module name generated for a given interface will be the snake-case form of the WIT
64+
/// interface name, possibly qualified with the package name and namespace and/or version if that name would
65+
/// otherwise clash with another interface. With this option, you may override that name with your own, unique
66+
/// name.
67+
#[arg(long, value_parser = parse_key_value)]
68+
pub export_interface_name: Vec<(String, String)>,
5169
}
5270

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

88106
/// Output file to which to write the resulting component
@@ -112,7 +130,7 @@ pub struct Bindings {
112130
pub world_module: Option<String>,
113131
}
114132

115-
fn parse_module_world(s: &str) -> Result<(String, String), String> {
133+
fn parse_key_value(s: &str) -> Result<(String, String), String> {
116134
let (k, v) = s
117135
.split_once('=')
118136
.ok_or_else(|| format!("expected string of form `<key>=<value>`; got `{s}`"))?;
@@ -137,6 +155,16 @@ fn generate_bindings(common: Common, bindings: Bindings) -> Result<()> {
137155
common.all_features,
138156
bindings.world_module.as_deref(),
139157
&bindings.output_dir,
158+
&common
159+
.import_interface_name
160+
.iter()
161+
.map(|(a, b)| (a.as_str(), b.as_str()))
162+
.collect(),
163+
&common
164+
.export_interface_name
165+
.iter()
166+
.map(|(a, b)| (a.as_str(), b.as_str()))
167+
.collect(),
140168
)
141169
}
142170

@@ -167,6 +195,16 @@ fn componentize(common: Common, componentize: Componentize) -> Result<()> {
167195
&componentize.output,
168196
None,
169197
componentize.stub_wasi,
198+
&common
199+
.import_interface_name
200+
.iter()
201+
.map(|(a, b)| (a.as_str(), b.as_str()))
202+
.collect(),
203+
&common
204+
.export_interface_name
205+
.iter()
206+
.map(|(a, b)| (a.as_str(), b.as_str()))
207+
.collect(),
170208
))?;
171209

172210
if !common.quiet {
@@ -300,6 +338,8 @@ mod tests {
300338
quiet: false,
301339
features: vec![],
302340
all_features: false,
341+
import_interface_name: Vec::new(),
342+
export_interface_name: Vec::new(),
303343
};
304344
let bindings = Bindings {
305345
output_dir: out_dir.path().into(),
@@ -328,6 +368,8 @@ mod tests {
328368
quiet: false,
329369
features: vec!["x".to_owned()],
330370
all_features: false,
371+
import_interface_name: Vec::new(),
372+
export_interface_name: Vec::new(),
331373
};
332374
let bindings = Bindings {
333375
output_dir: out_dir.path().into(),
@@ -356,6 +398,8 @@ mod tests {
356398
quiet: false,
357399
features: vec![],
358400
all_features: true,
401+
import_interface_name: Vec::new(),
402+
export_interface_name: Vec::new(),
359403
};
360404
let bindings = Bindings {
361405
output_dir: out_dir.path().into(),
@@ -382,6 +426,8 @@ mod tests {
382426
quiet: false,
383427
features: vec!["x".to_owned()],
384428
all_features: false,
429+
import_interface_name: Vec::new(),
430+
export_interface_name: Vec::new(),
385431
};
386432
let bindings = Bindings {
387433
output_dir: out_dir.path().into(),

0 commit comments

Comments
 (0)