From 4a8389a2599c8e479593b02c9e3fbd7d6163d57d Mon Sep 17 00:00:00 2001 From: Scott Andrews Date: Thu, 15 Oct 2026 08:55:07 -0400 Subject: [PATCH] to-stderr Use wac to rename the to-stdout component redirecting stdout to stderr. Signed-off-by: Scott Andrews --- README.md | 3 +- components/to-stderr/README.md | 9 ++++++ components/to-stderr/to-stderr.wac | 11 +++++++ make/components.mk | 17 +++++++---- scripts/wac-deps.sh | 46 ++++++++++++++++++++++++++++++ tools/Cargo.toml | 2 ++ 6 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 components/to-stderr/README.md create mode 100644 components/to-stderr/to-stderr.wac create mode 100755 scripts/wac-deps.sh diff --git a/README.md b/README.md index c048e2e..c1cb188 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ A collection of utility components that remix wasi:logging types and interfaces. ## Components - [`levels`](./components/levels/) +- [`to-stderr`](./components/to-stderr/) - [`to-stdout`](./components/to-stdout/) ## Build @@ -31,7 +32,7 @@ make components The build creates each component in [`components`](./components) into `target/components`, e.g. the levels component at `target/components/levels/levels.wasm`, along with `target/components/interface.wasm`, the `componentized:logging` WIT package. Each component is also built with debug info, e.g. `target/components/levels/levels.debug.wasm`. -The cli tools the build uses, [`wasm-tools`](https://github.com/bytecodealliance/wasm-tools) and [`wkg`](https://github.com/bytecodealliance/wasm-pkg-tools), are pinned in [`tools/Cargo.toml`](./tools/Cargo.toml) and installed into `target/tools/`, e.g. `target/tools/aarch64-apple-darwin`, as needed, or ahead of time with `make tools`. Dependabot bumps the pinned versions. +The cli tools the build uses, [`wac`](https://github.com/bytecodealliance/wac), [`wasm-tools`](https://github.com/bytecodealliance/wasm-tools) and [`wkg`](https://github.com/bytecodealliance/wasm-pkg-tools), are pinned in [`tools/Cargo.toml`](./tools/Cargo.toml) and installed into `target/tools/`, e.g. `target/tools/aarch64-apple-darwin`, as needed, or ahead of time with `make tools`. Dependabot bumps the pinned versions. ## Community diff --git a/components/to-stderr/README.md b/components/to-stderr/README.md new file mode 100644 index 0000000..01996d5 --- /dev/null +++ b/components/to-stderr/README.md @@ -0,0 +1,9 @@ +# `to-stderr` + +Implements wasi:logging/logging@0.1.0-draft writing log statements to stderr via wasi:cli/stderr@0.3.0. A composition of [`to-stdout`](../to-stdout/) with its wasi:cli/stdout@0.3.0 import satisfied by wasi:cli/stderr@0.3.0. + +Log output takes the form: + +``` +2025-02-10 18:04:35.925Z LEVEL [component]: message +``` diff --git a/components/to-stderr/to-stderr.wac b/components/to-stderr/to-stderr.wac new file mode 100644 index 0000000..a6f94d2 --- /dev/null +++ b/components/to-stderr/to-stderr.wac @@ -0,0 +1,11 @@ +package componentized:logging; + +import stderr: wasi:cli/stderr@0.3.0; + +let to-stdout = new local:to-stdout { + // write log statements to stderr instead of stdout + "wasi:cli/stdout@0.3.0": stderr, + ... +}; + +export to-stdout["wasi:logging/logging@0.1.0-draft"]; diff --git a/make/components.mk b/make/components.mk index 012e5b8..6f27ff8 100644 --- a/make/components.mk +++ b/make/components.mk @@ -1,10 +1,14 @@ COMPONENTS_DIR := target/components +# the WIT packages of components/wit/deps, encoded where `wac compose` looks for a package a +# composition names without instantiating it, e.g. `import stderr: wasi:cli/stderr@0.3.0;` +WAC_DEPS_DIR := target/wac-deps + COMPONENTS = $(sort $(foreach file,$(wildcard $(addprefix components/*/,wit/*.constants.wit *.properties *.wac *.wkg Cargo.toml)),$(word 2,$(subst /, ,$(file))))) .PHONY: clean-components clean-components: clean-wit - rm -rf ${COMPONENTS_DIR} + rm -rf ${COMPONENTS_DIR} ${WAC_DEPS_DIR} .PHONY: components components: ${COMPONENTS_DIR}/interface.wasm $(foreach component,$(COMPONENTS),${COMPONENTS_DIR}/$(component)/$(component).wasm ${COMPONENTS_DIR}/$(component)/$(component).debug.wasm) @@ -35,11 +39,11 @@ else ifneq ($(wildcard components/$1/$1.wac),) # the local packages the composition instantiates, e.g. `new local:latch-n2 { ... }` WAC_DEPS_$1 := $$(shell grep -v '^\s*//' components/$1/$1.wac | grep -oE 'local:[a-z0-9-]+' | sed 's/^local://' | sort -u) -${COMPONENTS_DIR}/$1/$1.wasm: components/$1/$1.wac $$(foreach component,$$(WAC_DEPS_$1),$${COMPONENTS_DIR}/$$(component)/$$(component).wasm) ${COMPONENTS_DIR}/$1/README.md | $(call tool,wac-cli) - $(WAC) compose $$(foreach component,$$(WAC_DEPS_$1),-d local:$$(component)=$${COMPONENTS_DIR}/$$(component)/$$(component).wasm) -o ${COMPONENTS_DIR}/$1/$1.wasm components/$1/$1.wac +${COMPONENTS_DIR}/$1/$1.wasm: components/$1/$1.wac $$(foreach component,$$(WAC_DEPS_$1),$${COMPONENTS_DIR}/$$(component)/$$(component).wasm) ${COMPONENTS_DIR}/$1/README.md ${WAC_DEPS_DIR} | $(call tool,wac-cli) + $(WAC) compose --deps-dir ${WAC_DEPS_DIR} $$(foreach component,$$(WAC_DEPS_$1),-d local:$$(component)=$${COMPONENTS_DIR}/$$(component)/$$(component).wasm) -o ${COMPONENTS_DIR}/$1/$1.wasm components/$1/$1.wac -${COMPONENTS_DIR}/$1/$1.debug.wasm: components/$1/$1.wac $$(foreach component,$$(WAC_DEPS_$1),$${COMPONENTS_DIR}/$$(component)/$$(component).debug.wasm) ${COMPONENTS_DIR}/$1/README.md | $(call tool,wac-cli) - $(WAC) compose $$(foreach component,$$(WAC_DEPS_$1),-d local:$$(component)=$${COMPONENTS_DIR}/$$(component)/$$(component).debug.wasm) -o ${COMPONENTS_DIR}/$1/$1.debug.wasm components/$1/$1.wac +${COMPONENTS_DIR}/$1/$1.debug.wasm: components/$1/$1.wac $$(foreach component,$$(WAC_DEPS_$1),$${COMPONENTS_DIR}/$$(component)/$$(component).debug.wasm) ${COMPONENTS_DIR}/$1/README.md ${WAC_DEPS_DIR} | $(call tool,wac-cli) + $(WAC) compose --deps-dir ${WAC_DEPS_DIR} $$(foreach component,$$(WAC_DEPS_$1),-d local:$$(component)=$${COMPONENTS_DIR}/$$(component)/$$(component).debug.wasm) -o ${COMPONENTS_DIR}/$1/$1.debug.wasm components/$1/$1.wac else ifneq ($(wildcard components/$1/$1.wkg),) @@ -70,6 +74,9 @@ endef $(foreach component,$(COMPONENTS),$(eval $(call BUILD_COMPONENT,$(component)))) +${WAC_DEPS_DIR}: components/wit/deps scripts/wac-deps.sh | $(call tool,wasm-tools) + WASM_TOOLS=$(WASM_TOOLS) scripts/wac-deps.sh components/wit/deps ${WAC_DEPS_DIR} + ${COMPONENTS_DIR}/interface.wasm: wit/deps README.md | $(call tool,wkg) @mkdir -p ${COMPONENTS_DIR} $(WKG) build -o ${COMPONENTS_DIR}/interface.wasm diff --git a/scripts/wac-deps.sh b/scripts/wac-deps.sh new file mode 100755 index 0000000..7e10af8 --- /dev/null +++ b/scripts/wac-deps.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash + +# Encode each WIT package of a wit/deps directory where `wac compose --deps-dir` looks for it, so a +# composition can name the interfaces of a package it does not instantiate, e.g. +# `import stderr: wasi:cli/stderr@0.3.0;`. +# +# WASM_TOOLS= scripts/wac-deps.sh +# +# wac looks for a versioned package at `//.wasm`, e.g. +# +# wit/deps/wasi-cli-0.3.0 -> /wasi/cli/0.3.0.wasm +# +# Each package is encoded with the other packages as its dependencies. + +set -euo pipefail + +deps=$1 +out=$2 +wasm_tools=${WASM_TOOLS:-wasm-tools} + +work=$(mktemp -d) +trap 'rm -rf "$work"' EXIT + +rm -rf "$out" +mkdir -p "$out" + +for package in "$deps"/*/; do + package=${package%/} + rm -rf "$work/package" + mkdir -p "$work/package/deps" + cp "$package"/*.wit "$work/package/" + for dep in "$deps"/*/; do + dep=${dep%/} + [[ "$dep" == "$package" ]] || cp -R "$dep" "$work/package/deps/" + done + "$wasm_tools" component wit "$work/package" --wasm -o "$work/package.wasm" + + # e.g. `package wasi:cli@0.3.0;` + id=$("$wasm_tools" component wit "$work/package.wasm" | sed -n 's/^package \(.*\);$/\1/p' | head -n 1) + namespace=${id%%:*} + name=${id#*:} + name=${name%%@*} + version=${id#*@} + mkdir -p "$out/$namespace/$name" + cp "$work/package.wasm" "$out/$namespace/$name/$version.wasm" +done diff --git a/tools/Cargo.toml b/tools/Cargo.toml index f5cb4f1..6e46084 100644 --- a/tools/Cargo.toml +++ b/tools/Cargo.toml @@ -15,10 +15,12 @@ path = "lib.rs" # the binaries each tool installs, the Makefile runs each by path from a variable named after it, # e.g. `$(WASM_TOOLS)` for `wasm-tools` [package.metadata.bins] +wac-cli = ["wac"] wasm-tools = ["wasm-tools"] wkg = ["wkg"] [dependencies] +wac-cli = "=0.12.0" wasm-tools = "=1.261.0" wkg = "=0.16.1"