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
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- CLI: `wit-bindgen-go wit` now accepts a `--world` argument in the form of `imports`, `wasi:clocks/imports`, or `wasi:clocks/imports@0.2.0`. This filters the serialized WIT to a specific world and interfaces it references. This can be used to generate focused WIT for a specific world with a minimal set of dependencies.
- `wit.(*Resolve).WIT()` and `wit.(*Package).WIT()` now accept a `*wit.World` as context to filter serialized WIT to a specific world.

### Changed

- Method `wit.(*Package).WIT()` now interprets the non-empty string `name` argument as signal to render in single-file, multi-package braced form.

## [v0.2.4] — 2024-10-06

### Added
Expand Down
34 changes: 31 additions & 3 deletions cmd/wit-bindgen-go/cmd/wit/wit.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,24 @@ import (
"fmt"

"github.com/bytecodealliance/wasm-tools-go/internal/witcli"
"github.com/bytecodealliance/wasm-tools-go/wit"
"github.com/urfave/cli/v3"
)

// Command is the CLI command for wit.
var Command = &cli.Command{
Name: "wit",
Usage: "reverses a WIT JSON file into WIT syntax",
Name: "wit",
Usage: "reverses a WIT JSON file into WIT syntax",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "world",
Aliases: []string{"w"},
Value: "",
OnlyOnce: true,
Config: cli.StringConfig{TrimSpace: true},
Usage: "WIT world to generate, otherwise generate all worlds",
},
},
Action: action,
}

Expand All @@ -24,6 +35,23 @@ func action(ctx context.Context, cmd *cli.Command) error {
if err != nil {
return err
}
fmt.Println(res.WIT(nil, ""))
var w *wit.World
world := cmd.String("world")
if world != "" {
w = findWorld(res, world)
if w == nil {
return fmt.Errorf("world %s not found", world)
}
}
fmt.Print(res.WIT(w, ""))
return nil
}

func findWorld(r *wit.Resolve, pattern string) *wit.World {
for _, w := range r.Worlds {
if w.Match(pattern) {
return w
}
}
return nil
}
3 changes: 1 addition & 2 deletions testdata/wasi/cli.wit.json.golden.wit
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,6 @@ world command {
export run;
}


package wasi:clocks@0.2.0 {
/// WASI Monotonic Clock is a clock API intended to let users measure elapsed
/// time.
Expand Down Expand Up @@ -2168,4 +2167,4 @@ package wasi:sockets@0.2.0 {
import tcp-create-socket;
import ip-name-lookup;
}
}
}
134 changes: 134 additions & 0 deletions testdata/wasi/clocks-imports.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package wasi:cli@0.2.0;

package wasi:clocks@0.2.0 {
/// WASI Monotonic Clock is a clock API intended to let users measure elapsed
/// time.
///
/// It is intended to be portable at least between Unix-family platforms and
/// Windows.
///
/// A monotonic clock is a clock which has an unspecified initial value, and
/// successive reads of the clock will produce non-decreasing values.
///
/// It is intended for measuring elapsed time.
interface monotonic-clock {
use wasi:io/poll@0.2.0.{pollable};

/// An instant in time, in nanoseconds. An instant is relative to an
/// unspecified initial value, and can only be compared to instances from
/// the same monotonic-clock.
type instant = u64;

/// A duration of time, in nanoseconds.
type duration = u64;

/// Read the current value of the clock.
///
/// The clock is monotonic, therefore calling this function repeatedly will
/// produce a sequence of non-decreasing values.
now: func() -> instant;

/// Query the resolution of the clock. Returns the duration of time
/// corresponding to a clock tick.
resolution: func() -> duration;

/// Create a `pollable` which will resolve once the specified instant
/// occured.
subscribe-instant: func(when: instant) -> pollable;

/// Create a `pollable` which will resolve once the given duration has
/// elapsed, starting at the time at which this function was called.
/// occured.
subscribe-duration: func(when: duration) -> pollable;
}

/// WASI Wall Clock is a clock API intended to let users query the current
/// time. The name "wall" makes an analogy to a "clock on the wall", which
/// is not necessarily monotonic as it may be reset.
///
/// It is intended to be portable at least between Unix-family platforms and
/// Windows.
///
/// A wall clock is a clock which measures the date and time according to
/// some external reference.
///
/// External references may be reset, so this clock is not necessarily
/// monotonic, making it unsuitable for measuring elapsed time.
///
/// It is intended for reporting the current date and time for humans.
interface wall-clock {
/// A time and date in seconds plus nanoseconds.
record datetime {
seconds: u64,
nanoseconds: u32,
}

/// Read the current value of the clock.
///
/// This clock is not monotonic, therefore calling this function repeatedly
/// will not necessarily produce a sequence of non-decreasing values.
///
/// The returned timestamps represent the number of seconds since
/// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch],
/// also known as [Unix Time].
///
/// The nanoseconds field of the output is always less than 1000000000.
///
/// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16
/// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time
now: func() -> datetime;

/// Query the resolution of the clock.
///
/// The nanoseconds field of the output is always less than 1000000000.
resolution: func() -> datetime;
}

world imports {
import wasi:io/poll@0.2.0;
import monotonic-clock;
import wall-clock;
}
}

package wasi:io@0.2.0 {
/// A poll API intended to let users wait for I/O events on multiple handles
/// at once.
interface poll {
/// `pollable` represents a single I/O event which may be ready, or not.
resource pollable {

/// `block` returns immediately if the pollable is ready, and otherwise
/// blocks until ready.
///
/// This function is equivalent to calling `poll.poll` on a list
/// containing only this pollable.
block: func();

/// Return the readiness of a pollable. This function never blocks.
///
/// Returns `true` when the pollable is ready, and `false` otherwise.
ready: func() -> bool;
}

/// Poll for completion on a set of pollables.
///
/// This function takes a list of pollables, which identify I/O sources of
/// interest, and waits until one or more of the events is ready for I/O.
///
/// The result `list<u32>` contains one or more indices of handles in the
/// argument list that is ready for I/O.
///
/// If the list contains more elements than can be indexed with a `u32`
/// value, this function traps.
///
/// A timeout can be implemented by adding a pollable from the
/// wasi-clocks API to the list.
///
/// This function does not return a `result`; polling in itself does not
/// do any I/O so it doesn't fail. If any of the I/O sources identified by
/// the pollables has an error, it is indicated by marking the source as
/// being reaedy for I/O.
poll: func(in: list<borrow<pollable>>) -> list<u32>;
}
}
Loading