Skip to content
This repository has been archived by the owner on Oct 31, 2023. It is now read-only.

Commit

Permalink
fix: unify rust and tinygo component target logic
Browse files Browse the repository at this point in the history
Signed-off-by: Connor Smith <connor.smith.256@gmail.com>
  • Loading branch information
connorsmith256 committed Oct 5, 2023
1 parent 3d5517c commit 6d71c1f
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 85 deletions.
26 changes: 15 additions & 11 deletions crates/wash-lib/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::{
},
parser::{
ActorConfig, CommonConfig, InterfaceConfig, LanguageConfig, ProjectConfig, ProviderConfig,
RustConfig, RustWasmTarget, TinyGoConfig, TinyGoWasmTarget, TypeConfig,
RustConfig, TinyGoConfig, TypeConfig, WasmTarget,
},
};

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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])
Expand Down Expand Up @@ -219,6 +227,7 @@ fn build_rust_actor(
fn build_tinygo_actor(
common_config: &CommonConfig,
tinygo_config: &TinyGoConfig,
actor_config: &ActorConfig,
) -> Result<PathBuf> {
let filename = format!("build/{}.wasm", common_config.name);

Expand All @@ -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)?;
}
Expand All @@ -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",
Expand Down Expand Up @@ -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<Vec<u8>> {
if let ActorConfig {
wasm_target: RustWasmTarget::WasiPreview2,
wasm_target: WasmTarget::WasiPreview2 | WasmTarget::TinyGoWasiPreview1,
wasi_preview2_adapter_path: Some(path),
..
} = config
Expand Down
97 changes: 35 additions & 62 deletions crates/wash-lib/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,26 @@ pub struct ActorConfig {
/// The filename of the signed wasm actor.
pub filename: Option<String>,
/// 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<PathBuf>,
/// The call alias of the actor.
pub call_alias: Option<String>,
}

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"]
Expand Down Expand Up @@ -90,7 +103,7 @@ impl TryFrom<RawActorConfig> 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,
Expand Down Expand Up @@ -162,17 +175,6 @@ pub struct RustConfig {
pub target_path: Option<PathBuf>,
}

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.
Expand Down Expand Up @@ -207,72 +209,48 @@ pub struct CommonConfig {
}

#[derive(Debug, Deserialize, Default, Clone, Eq, PartialEq)]
pub enum RustWasmTarget {
pub enum WasmTarget {
#[default]
#[serde(alias = "wasm32-unknown-unknown")]
CoreModule,
#[serde(alias = "wasm32-wasi", alias = "wasm32-wasi-preview1")]
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<String> 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<String> for TinyGoWasmTarget {
impl From<String> 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",
})
}
}
Expand Down Expand Up @@ -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<PathBuf>,
/// The target wasm target to build for. Defaults to "wasm".
pub wasm_target: Option<TinyGoWasmTarget>,
}

#[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<PathBuf>,
/// The target wasm target to build for. Defaults to "wasm".
pub wasm_target: Option<TinyGoWasmTarget>,
}

impl TryFrom<RawTinyGoConfig> for TinyGoConfig {
Expand All @@ -318,7 +292,6 @@ impl TryFrom<RawTinyGoConfig> for TinyGoConfig {
fn try_from(raw_config: RawTinyGoConfig) -> Result<Self> {
Ok(Self {
tinygo_path: raw_config.tinygo_path,
wasm_target: raw_config.wasm_target,
})
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
16 changes: 16 additions & 0 deletions crates/wash-lib/tests/parser/files/tinygo_actor_module.toml
Original file line number Diff line number Diff line change
@@ -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"
49 changes: 38 additions & 11 deletions crates/wash-lib/tests/parser/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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())
})
Expand All @@ -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,
);

Expand All @@ -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()),
})
);

Expand All @@ -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())
})
);

Expand All @@ -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() {
Expand Down Expand Up @@ -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,
..
})
));
Expand All @@ -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,
..
})
));
Expand All @@ -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,
..
})
));
Expand Down

0 comments on commit 6d71c1f

Please sign in to comment.