diff --git a/crates/go/README.md b/crates/go/README.md index be1dc3ef2..c88eaab9b 100644 --- a/crates/go/README.md +++ b/crates/go/README.md @@ -43,11 +43,10 @@ The generated files will reference the following files in the [bytecodealliance/ - defines an `Option` type as required by the WIT world - defines a `Result` type as required by the WIT world - defines a `Unit` type as required by the WIT world - - defines a `StreamReader` and `StreamWriter` types as required by the WIT world - - defines a `FutureReader` and `FutureWriter` types as required by the WIT world + - defines `StreamReader` and `StreamWriter` types as required by the WIT world + - defines `FutureReader` and `FutureWriter` types as required by the WIT world - `go.bytecodealliance.org/pkg/wit/async` (if needed): defines low-level functions for integrating the Go scheduler with the component model async ABI - Note that async support currently requires [a patched version of Go](https://github.com/dicej/go/releases/tag/go1.25.5-wasi-on-idle). Code generated for worlds that don't use any async features can be compiled using a diff --git a/crates/go/src/lib.rs b/crates/go/src/lib.rs index 1550c0c9a..cfad979b4 100644 --- a/crates/go/src/lib.rs +++ b/crates/go/src/lib.rs @@ -116,6 +116,15 @@ pub struct Opts { #[cfg_attr(feature = "clap", clap(long))] pub pkg_name: Option, + /// When `--pkg-name` is specified, optionally specify a different package + /// for exports. + /// + /// This allows you to put the exports and imports in separate packages when + /// building a library. If only `--pkg-name` is specified, this will + /// default to that value. + #[cfg_attr(feature = "clap", clap(long, requires = "pkg_name"))] + pub export_pkg_name: Option, + /// Print the version of the remote package being used for the shared WIT types. /// /// Must be specified in addition to the `pkg-name` flag. @@ -210,8 +219,12 @@ struct Go { impl Go { /// Adds the bindings module prefix to a package name. - fn mod_pkg(&self, name: &str) -> String { - let prefix = self.opts.pkg_name.as_deref().unwrap_or("wit_component"); + fn mod_pkg(&self, for_export: bool, name: &str) -> String { + let prefix = for_export + .then_some(()) + .and(self.opts.export_pkg_name.as_deref()) + .or(self.opts.pkg_name.as_deref()) + .unwrap_or("wit_component"); format!(r#""{prefix}/{name}""#) } @@ -236,7 +249,7 @@ impl Go { package }; let prefix = format!("{package}."); - imports.insert(self.mod_pkg(&package)); + imports.insert(self.mod_pkg(exported, &package)); prefix } } @@ -883,16 +896,14 @@ impl WorldGenerator for Go { files.push( "go.mod", format!( - r#"module {} + r#"module wit_component go 1.25 require ( - go.bytecodealliance.org/pkg {} + go.bytecodealliance.org/pkg {REMOTE_PKG_VERSION} ) "#, - self.opts.pkg_name.as_deref().unwrap_or("wit_component"), - REMOTE_PKG_VERSION, ) .as_bytes(), ); @@ -1778,7 +1789,7 @@ for index := 0; index < int({length}); index++ {{ FunctionKind::Freestanding | FunctionKind::AsyncFreestanding => { let args = operands.join(", "); let call = format!("{package}.{name}({args})"); - self.imports.insert(self.generator.mod_pkg(&package)); + self.imports.insert(self.generator.mod_pkg(true, &package)); call } FunctionKind::Constructor(ty) => { @@ -1789,7 +1800,7 @@ for index := 0; index < int({length}); index++ {{ .unwrap() .to_upper_camel_case(); let call = format!("{package}.Make{ty}({args})"); - self.imports.insert(self.generator.mod_pkg(&package)); + self.imports.insert(self.generator.mod_pkg(true, &package)); call } FunctionKind::Method(_) | FunctionKind::AsyncMethod(_) => {