From 6d71c1f36111efe1942e522c8ac6b315c78d81ab Mon Sep 17 00:00:00 2001 From: Connor Smith Date: Fri, 1 Sep 2023 21:29:59 -0600 Subject: [PATCH] fix: unify rust and tinygo component target logic Signed-off-by: Connor Smith --- crates/wash-lib/src/build.rs | 26 ++--- crates/wash-lib/src/parser/mod.rs | 97 +++++++------------ ...actor.toml => tinygo_actor_component.toml} | 2 +- .../parser/files/tinygo_actor_module.toml | 16 +++ crates/wash-lib/tests/parser/main.rs | 49 +++++++--- 5 files changed, 105 insertions(+), 85 deletions(-) rename crates/wash-lib/tests/parser/files/{tinygo_actor.toml => tinygo_actor_component.toml} (87%) create mode 100644 crates/wash-lib/tests/parser/files/tinygo_actor_module.toml diff --git a/crates/wash-lib/src/build.rs b/crates/wash-lib/src/build.rs index 7d77ae21..87b4f3e4 100644 --- a/crates/wash-lib/src/build.rs +++ b/crates/wash-lib/src/build.rs @@ -18,7 +18,7 @@ use crate::{ }, parser::{ ActorConfig, CommonConfig, InterfaceConfig, LanguageConfig, ProjectConfig, ProviderConfig, - RustConfig, RustWasmTarget, TinyGoConfig, TinyGoWasmTarget, TypeConfig, + RustConfig, TinyGoConfig, TypeConfig, WasmTarget, }, }; @@ -90,11 +90,19 @@ pub fn build_actor( LanguageConfig::Rust(rust_config) => { build_rust_actor(common_config, rust_config, actor_config) } - LanguageConfig::TinyGo(tinygo_config) => build_tinygo_actor(common_config, tinygo_config), + LanguageConfig::TinyGo(tinygo_config) => { + build_tinygo_actor(common_config, tinygo_config, actor_config) + } }?; + if actor_config.wasm_target == WasmTarget::TinyGoWasiPreview1 { + // TODO: run equivalent of `wasm-tools component embed --world [world] ./wit [actor_wasm_path] -o [actor_wasm_embed_path] + } + // If the actor has been configured as WASI Preview2, adapt it - if actor_config.wasm_target == RustWasmTarget::WasiPreview2 { + if actor_config.wasm_target == WasmTarget::WasiPreview2 + || actor_config.wasm_target == WasmTarget::TinyGoWasiPreview1 + { let adapter_wasm_bytes = get_wasi_preview2_adapter_bytes(actor_config)?; // Adapt the component, using the adapter that is available locally let wasm_bytes = adapt_wasi_preview1_component(&actor_wasm_path, adapter_wasm_bytes) @@ -162,7 +170,7 @@ fn build_rust_actor( let metadata = cargo_metadata::MetadataCommand::new().exec()?; let target_path = metadata.target_directory.as_path(); - let build_target = rust_config.build_target(&actor_config.wasm_target); + let build_target = actor_config.build_target(&actor_config.wasm_target); let result = command .args(["build", "--release", "--target", build_target]) @@ -219,6 +227,7 @@ fn build_rust_actor( fn build_tinygo_actor( common_config: &CommonConfig, tinygo_config: &TinyGoConfig, + actor_config: &ActorConfig, ) -> Result { let filename = format!("build/{}.wasm", common_config.name); @@ -230,11 +239,6 @@ fn build_tinygo_actor( None => process::Command::new("tinygo"), }; - let build_target = match &tinygo_config.wasm_target { - Some(t) => t.to_string(), - None => TinyGoWasmTarget::CoreModule.to_string(), - }; - if let Some(p) = PathBuf::from(&filename).parent() { fs::create_dir_all(p)?; } @@ -245,7 +249,7 @@ fn build_tinygo_actor( "-o", filename.as_str(), "-target", - build_target.as_str(), + actor_config.build_target(&actor_config.wasm_target), "-scheduler", "none", "-no-debug", @@ -315,7 +319,7 @@ fn adapt_wasi_preview1_component( /// if required by project configuration pub(crate) fn get_wasi_preview2_adapter_bytes(config: &ActorConfig) -> Result> { if let ActorConfig { - wasm_target: RustWasmTarget::WasiPreview2, + wasm_target: WasmTarget::WasiPreview2 | WasmTarget::TinyGoWasiPreview1, wasi_preview2_adapter_path: Some(path), .. } = config diff --git a/crates/wash-lib/src/parser/mod.rs b/crates/wash-lib/src/parser/mod.rs index e4cf9c47..7b195b23 100644 --- a/crates/wash-lib/src/parser/mod.rs +++ b/crates/wash-lib/src/parser/mod.rs @@ -49,13 +49,26 @@ pub struct ActorConfig { /// The filename of the signed wasm actor. pub filename: Option, /// The target wasm target to build for. Defaults to "wasm32-unknown-unknown". - pub wasm_target: RustWasmTarget, + pub wasm_target: WasmTarget, /// Path to a wasm adapter that can be used for preview2 pub wasi_preview2_adapter_path: Option, /// The call alias of the actor. pub call_alias: Option, } +impl ActorConfig { + pub fn build_target(&self, wasm_target: &WasmTarget) -> &'static str { + match wasm_target { + WasmTarget::CoreModule => "wasm32-unknown-unknown", + // NOTE: eventually "wasm32-wasi" will be renamed to "wasm32-wasi-preview1" + // https://github.com/rust-lang/compiler-team/issues/607 + WasmTarget::WasiPreview1 | WasmTarget::WasiPreview2 => "wasm32-wasi", + WasmTarget::TinyGoCoreModule => "wasm", + WasmTarget::TinyGoWasiPreview1 => "wasi", + } + } +} + #[derive(Deserialize, Debug, PartialEq)] struct RawActorConfig { /// The list of provider claims that this actor requires. eg. ["wasmcloud:httpserver", "wasmcloud:blobstore"] @@ -90,7 +103,7 @@ impl TryFrom for ActorConfig { filename: raw_config.filename, wasm_target: raw_config .wasm_target - .map(RustWasmTarget::from) + .map(WasmTarget::from) .unwrap_or_default(), wasi_preview2_adapter_path: raw_config.wasi_preview2_adapter_path, call_alias: raw_config.call_alias, @@ -162,17 +175,6 @@ pub struct RustConfig { pub target_path: Option, } -impl RustConfig { - pub fn build_target(&self, wasm_target: &RustWasmTarget) -> &'static str { - match wasm_target { - RustWasmTarget::CoreModule => "wasm32-unknown-unknown", - // NOTE: eventually "wasm32-wasi" will be renamed to "wasm32-wasi-preview1" - // https://github.com/rust-lang/compiler-team/issues/607 - RustWasmTarget::WasiPreview1 | RustWasmTarget::WasiPreview2 => "wasm32-wasi", - } - } -} - #[derive(Deserialize, Debug, PartialEq, Default, Clone)] struct RawRustConfig { /// The path to the cargo binary. Optional, will default to search the user's `PATH` for `cargo` if not specified. @@ -207,7 +209,7 @@ pub struct CommonConfig { } #[derive(Debug, Deserialize, Default, Clone, Eq, PartialEq)] -pub enum RustWasmTarget { +pub enum WasmTarget { #[default] #[serde(alias = "wasm32-unknown-unknown")] CoreModule, @@ -215,64 +217,40 @@ pub enum RustWasmTarget { WasiPreview1, #[serde(alias = "wasm32-wasi-preview2")] WasiPreview2, + #[serde(alias = "wasm")] // Shame, shame, TinyGo. Shame. + TinyGoCoreModule, + #[serde(alias = "wasi", alias = "wasip1")] // Shame, shame, TinyGo. Shame. + TinyGoWasiPreview1, } -impl From<&str> for RustWasmTarget { - fn from(value: &str) -> Self { - match value { - "wasm32-wasi-preview1" => RustWasmTarget::WasiPreview1, - "wasm32-wasi" => RustWasmTarget::WasiPreview1, - "wasm32-wasi-preview2" => RustWasmTarget::WasiPreview2, - _ => RustWasmTarget::CoreModule, - } - } -} - -impl From for RustWasmTarget { - fn from(value: String) -> Self { - value.as_str().into() - } -} - -impl Display for RustWasmTarget { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(match &self { - RustWasmTarget::CoreModule => "wasm32-unknown-unknown", - RustWasmTarget::WasiPreview1 => "wasm32-wasi", - RustWasmTarget::WasiPreview2 => "wasm32-wasi-preview2", - }) - } -} - -#[derive(Debug, Deserialize, Default, Clone, Eq, PartialEq)] -pub enum TinyGoWasmTarget { - #[default] - #[serde(alias = "wasm")] - CoreModule, - #[serde(alias = "wasi", alias = "wasi")] - WasiPreview1, -} - -impl From<&str> for TinyGoWasmTarget { +impl From<&str> for WasmTarget { fn from(value: &str) -> Self { match value { - "wasi" => TinyGoWasmTarget::WasiPreview1, - _ => TinyGoWasmTarget::CoreModule, + "wasm32-wasi-preview1" => WasmTarget::WasiPreview1, + "wasm32-wasi" => WasmTarget::WasiPreview1, + "wasm32-wasi-preview2" => WasmTarget::WasiPreview2, + "wasi" => WasmTarget::TinyGoWasiPreview1, + "wasip1" => WasmTarget::TinyGoWasiPreview1, + "wasm" => WasmTarget::TinyGoCoreModule, + _ => WasmTarget::CoreModule, } } } -impl From for TinyGoWasmTarget { +impl From for WasmTarget { fn from(value: String) -> Self { value.as_str().into() } } -impl Display for TinyGoWasmTarget { +impl Display for WasmTarget { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str(match &self { - TinyGoWasmTarget::CoreModule => "wasm", - TinyGoWasmTarget::WasiPreview1 => "wasi", + WasmTarget::CoreModule => "wasm32-unknown-unknown", + WasmTarget::WasiPreview1 => "wasm32-wasi", + WasmTarget::WasiPreview2 => "wasm32-wasi-preview2", + WasmTarget::TinyGoCoreModule => "wasm", + WasmTarget::TinyGoWasiPreview1 => "wasi", }) } } @@ -300,16 +278,12 @@ struct RawProjectConfig { pub struct TinyGoConfig { /// The path to the tinygo binary. Optional, will default to `tinygo` if not specified. pub tinygo_path: Option, - /// The target wasm target to build for. Defaults to "wasm". - pub wasm_target: Option, } #[derive(Deserialize, Debug, PartialEq, Default)] struct RawTinyGoConfig { /// The path to the tinygo binary. Optional, will default to `tinygo` if not specified. pub tinygo_path: Option, - /// The target wasm target to build for. Defaults to "wasm". - pub wasm_target: Option, } impl TryFrom for TinyGoConfig { @@ -318,7 +292,6 @@ impl TryFrom for TinyGoConfig { fn try_from(raw_config: RawTinyGoConfig) -> Result { Ok(Self { tinygo_path: raw_config.tinygo_path, - wasm_target: raw_config.wasm_target, }) } } diff --git a/crates/wash-lib/tests/parser/files/tinygo_actor.toml b/crates/wash-lib/tests/parser/files/tinygo_actor_component.toml similarity index 87% rename from crates/wash-lib/tests/parser/files/tinygo_actor.toml rename to crates/wash-lib/tests/parser/files/tinygo_actor_component.toml index 15cf11fc..76456633 100644 --- a/crates/wash-lib/tests/parser/files/tinygo_actor.toml +++ b/crates/wash-lib/tests/parser/files/tinygo_actor_component.toml @@ -9,7 +9,7 @@ registry = "localhost:8080" push_insecure = false key_directory = "./keys" filename = "testactor.wasm" -wasm_target = "wasm32-unknown-unknown" +wasm_target = "wasi" call_alias = "testactor" [tinygo] diff --git a/crates/wash-lib/tests/parser/files/tinygo_actor_module.toml b/crates/wash-lib/tests/parser/files/tinygo_actor_module.toml new file mode 100644 index 00000000..0dfcb049 --- /dev/null +++ b/crates/wash-lib/tests/parser/files/tinygo_actor_module.toml @@ -0,0 +1,16 @@ +language = "tinygo" +type = "actor" +name = "testactor" +version = "0.1.0" + +[actor] +claims = ["wasmcloud:httpserver"] +registry = "localhost:8080" +push_insecure = false +key_directory = "./keys" +filename = "testactor.wasm" +wasm_target = "wasm" +call_alias = "testactor" + +[tinygo] +tinygo_path = "path/to/tinygo" \ No newline at end of file diff --git a/crates/wash-lib/tests/parser/main.rs b/crates/wash-lib/tests/parser/main.rs index 5383a61e..b0b8769a 100644 --- a/crates/wash-lib/tests/parser/main.rs +++ b/crates/wash-lib/tests/parser/main.rs @@ -3,8 +3,8 @@ use std::{fs, path::PathBuf}; use claims::{assert_err, assert_ok}; use semver::Version; use wash_lib::parser::{ - get_config, ActorConfig, CommonConfig, LanguageConfig, RustConfig, RustWasmTarget, - TinyGoConfig, TinyGoWasmTarget, TypeConfig, + get_config, ActorConfig, CommonConfig, LanguageConfig, RustConfig, TinyGoConfig, TypeConfig, + WasmTarget, }; #[test] @@ -33,7 +33,7 @@ fn rust_actor() { push_insecure: false, key_directory: PathBuf::from("./keys"), filename: Some("testactor.wasm".to_string()), - wasm_target: RustWasmTarget::CoreModule, + wasm_target: WasmTarget::CoreModule, wasi_preview2_adapter_path: None, call_alias: Some("testactor".to_string()) }) @@ -53,9 +53,11 @@ fn rust_actor() { } #[test] -fn tinygo_actor() { +fn tinygo_actor_module() { let result = get_config( - Some(PathBuf::from("./tests/parser/files/tinygo_actor.toml")), + Some(PathBuf::from( + "./tests/parser/files/tinygo_actor_module.toml", + )), None, ); @@ -65,7 +67,6 @@ fn tinygo_actor() { config.language, LanguageConfig::TinyGo(TinyGoConfig { tinygo_path: Some("path/to/tinygo".into()), - wasm_target: Some(TinyGoWasmTarget::CoreModule.into()), }) ); @@ -77,9 +78,9 @@ fn tinygo_actor() { push_insecure: false, key_directory: PathBuf::from("./keys"), filename: Some("testactor.wasm".to_string()), - call_alias: Some("testactor".to_string()), + wasm_target: WasmTarget::TinyGoCoreModule, wasi_preview2_adapter_path: None, - wasm_target: WasmTarget::CoreModule, + call_alias: Some("testactor".to_string()) }) ); @@ -96,6 +97,32 @@ fn tinygo_actor() { ); } +#[test] +fn tinygo_actor() { + let result = get_config( + Some(PathBuf::from( + "./tests/parser/files/tinygo_actor_component.toml", + )), + None, + ); + + let config = assert_ok!(result); + + assert_eq!( + config.project_type, + TypeConfig::Actor(ActorConfig { + claims: vec!["wasmcloud:httpserver".to_string()], + registry: Some("localhost:8080".to_string()), + push_insecure: false, + key_directory: PathBuf::from("./keys"), + filename: Some("testactor.wasm".to_string()), + call_alias: Some("testactor".to_string()), + wasi_preview2_adapter_path: None, + wasm_target: WasmTarget::CoreModule, + }) + ); +} + #[test] /// When given a folder, should automatically grab a wasmcloud.toml file inside it and parse it. fn folder_path() { @@ -340,7 +367,7 @@ fn minimal_rust_actor_preview2() { assert!(matches!( config.project_type, TypeConfig::Actor(ActorConfig { - wasm_target: RustWasmTarget::WasiPreview2, + wasm_target: WasmTarget::WasiPreview2, .. }) )); @@ -361,7 +388,7 @@ fn minimal_rust_actor_preview1() { assert!(matches!( config.project_type, TypeConfig::Actor(ActorConfig { - wasm_target: RustWasmTarget::WasiPreview1, + wasm_target: WasmTarget::WasiPreview1, .. }) )); @@ -382,7 +409,7 @@ fn minimal_rust_actor_core_module() { assert!(matches!( config.project_type, TypeConfig::Actor(ActorConfig { - wasm_target: RustWasmTarget::CoreModule, + wasm_target: WasmTarget::CoreModule, .. }) ));