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

feat: add preview2 target to wasmcloud.toml #641

Merged
merged 1 commit into from
Jul 7, 2023
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
17 changes: 17 additions & 0 deletions .github/workflows/rust_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,23 @@ jobs:
shared-key: "${{ matrix.os }}-shared-cache"
- name: Install nextest
uses: taiki-e/install-action@nextest

# Sometimes, unit tests will get stuck executing wash during the
# loading CA certificates from the :otp store step. All you see is:
#
# > stderr log: 14:38:03.656 [info] Loading 467 CA(s) from :otp store
#
# when this happens, tests like can_download_and_start_wasmcloud get stuck and fail.
# to avoid this, we can call wash up/down and at least cause this loading as early as possible,
# hoping it does not happen again (or completes near instantaneously) during a test.
- name: Build wash
run: make build
- name: Cycle wash
run: |
cargo run -- up --detached;
sleep 10;
cargo run -- down;

- name: Run all wash & wash-lib unit tests
run: make test-wash-ci

Expand Down
42 changes: 28 additions & 14 deletions crates/wash-lib/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ use std::{fs, io::ErrorKind, path::PathBuf, process, str::FromStr};

use anyhow::{anyhow, bail, Result};

use crate::cli::{
claims::{sign_file, ActorMetadata, SignCommand},
OutputKind,
};
use crate::parser::{
ActorConfig, CommonConfig, InterfaceConfig, LanguageConfig, ProjectConfig, ProviderConfig,
RustConfig, TinyGoConfig, TypeConfig,
use crate::{
cli::{
claims::{sign_file, ActorMetadata, SignCommand},
OutputKind,
},
parser::{
ActorConfig, CommonConfig, InterfaceConfig, LanguageConfig, ProjectConfig, ProviderConfig,
RustConfig, TinyGoConfig, TypeConfig, WasmTarget,
},
};

/// Configuration for signing an artifact (actor or provider) including issuer and subject key, the path to where keys can be found, and an option to
Expand Down Expand Up @@ -126,19 +128,31 @@ fn build_rust_actor(
None => process::Command::new("cargo"),
};

if actor_config.wasm_target == WasmTarget::WasiPreview2 {
bail!("Building projects targeting WASI preview 2 is not yet supported");
}

// Change directory into the project directory
std::env::set_current_dir(&common_config.path)?;

let metadata = cargo_metadata::MetadataCommand::new().exec()?;
let target_path = metadata.target_directory.as_path();

let result = command.args(["build", "--release"]).status().map_err(|e| {
if e.kind() == ErrorKind::NotFound {
anyhow!("{:?} command is not found", command.get_program())
} else {
anyhow!(e)
}
})?;
let result = command
.args([
"build",
"--release",
"--target",
rust_config.build_target(&actor_config.wasm_target),
])
.status()
.map_err(|e| {
if e.kind() == ErrorKind::NotFound {
anyhow!("{:?} command is not found", command.get_program())
} else {
anyhow!(e)
}
})?;

if !result.success() {
bail!("Compiling actor failed: {}", result.to_string())
Expand Down
90 changes: 72 additions & 18 deletions crates/wash-lib/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,26 @@ use anyhow::{anyhow, bail, Result};
use cargo_toml::{Manifest, Product};
use config::Config;
use semver::Version;
use std::{fs, path::PathBuf};
use serde::Deserialize;
use std::{fmt::Display, fs, path::PathBuf};

#[derive(serde::Deserialize, Debug, PartialEq, Eq, Clone)]
#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
#[serde(rename_all = "snake_case")]
pub enum LanguageConfig {
Rust(RustConfig),
TinyGo(TinyGoConfig),
}

#[derive(serde::Deserialize, Debug, PartialEq, Eq, Clone)]
#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
#[serde(rename_all = "snake_case")]
pub enum TypeConfig {
Actor(ActorConfig),
Provider(ProviderConfig),
Interface(InterfaceConfig),
}

#[derive(serde::Deserialize, Debug, Clone)]
/// Project configuration, normally specified in the root keys of a wasmcloud.toml file
#[derive(Deserialize, Debug, Clone)]
pub struct ProjectConfig {
/// The language of the project, e.g. rust, tinygo. Contains specific configuration for that language.
pub language: LanguageConfig,
Expand All @@ -34,7 +36,7 @@ pub struct ProjectConfig {
pub common: CommonConfig,
}

#[derive(serde::Deserialize, Debug, PartialEq, Eq, Clone, Default)]
#[derive(Deserialize, Debug, PartialEq, Eq, Clone, Default)]
pub struct ActorConfig {
/// The list of provider claims that this actor requires. eg. ["wasmcloud:httpserver", "wasmcloud:blobstore"]
pub claims: Vec<String>,
Expand All @@ -47,11 +49,12 @@ 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: String,
pub wasm_target: WasmTarget,
/// The call alias of the actor.
pub call_alias: Option<String>,
}
#[derive(serde::Deserialize, Debug, PartialEq)]

#[derive(Deserialize, Debug, PartialEq)]
struct RawActorConfig {
/// The list of provider claims that this actor requires. eg. ["wasmcloud:httpserver", "wasmcloud:blobstore"]
pub claims: Option<Vec<String>>,
Expand Down Expand Up @@ -83,19 +86,20 @@ impl TryFrom<RawActorConfig> for ActorConfig {
filename: raw_config.filename,
wasm_target: raw_config
.wasm_target
.unwrap_or_else(|| "wasm32-unknown-unknown".to_string()),
.map(WasmTarget::from)
.unwrap_or_default(),
call_alias: raw_config.call_alias,
})
}
}
#[derive(serde::Deserialize, Debug, PartialEq, Eq, Clone, Default)]
#[derive(Deserialize, Debug, PartialEq, Eq, Clone, Default)]
pub struct ProviderConfig {
/// The capability ID of the provider.
pub capability_id: String,
/// The vendor name of the provider.
pub vendor: String,
}
#[derive(serde::Deserialize, Debug, PartialEq)]
#[derive(Deserialize, Debug, PartialEq)]
struct RawProviderConfig {
/// The capability ID of the provider.
pub capability_id: String,
Expand All @@ -114,14 +118,14 @@ impl TryFrom<RawProviderConfig> for ProviderConfig {
}
}

#[derive(serde::Deserialize, Debug, PartialEq, Eq, Clone, Default)]
#[derive(Deserialize, Debug, PartialEq, Eq, Clone, Default)]
pub struct InterfaceConfig {
/// Directory to output HTML.
pub html_target: PathBuf,
/// Path to codegen.toml file.
pub codegen_config: PathBuf,
}
#[derive(serde::Deserialize, Debug, PartialEq)]
#[derive(Deserialize, Debug, PartialEq)]

struct RawInterfaceConfig {
/// Directory to output HTML. Defaults to "./html".
Expand All @@ -145,15 +149,27 @@ impl TryFrom<RawInterfaceConfig> for InterfaceConfig {
}
}

#[derive(serde::Deserialize, Debug, PartialEq, Eq, Clone, Default)]
#[derive(Deserialize, Debug, PartialEq, Eq, Clone, Default)]
pub struct RustConfig {
/// The path to the cargo binary. Optional, will default to search the user's `PATH` for `cargo` if not specified.
pub cargo_path: Option<PathBuf>,
/// Path to cargo/rust's `target` directory. Optional, defaults to the cargo target directory for the workspace or project.
pub target_path: Option<PathBuf>,
}

#[derive(serde::Deserialize, Debug, PartialEq, Default, Clone)]
impl RustConfig {
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 => "wasm32-wasi",
WasmTarget::WasiPreview2 => "wasm32-wasi-preview2",
}
}
}

#[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.
pub cargo_path: Option<PathBuf>,
Expand All @@ -173,7 +189,7 @@ impl TryFrom<RawRustConfig> for RustConfig {
}

/// Configuration common amoung all project types & languages.
#[derive(serde::Deserialize, Debug, PartialEq, Eq, Clone)]
#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct CommonConfig {
/// Name of the project.
pub name: String,
Expand All @@ -186,7 +202,45 @@ pub struct CommonConfig {
pub wasm_bin_name: Option<String>,
}

#[derive(serde::Deserialize, Debug)]
#[derive(Debug, Deserialize, Default, Clone, Eq, PartialEq)]
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,
brooksmtownsend marked this conversation as resolved.
Show resolved Hide resolved
brooksmtownsend marked this conversation as resolved.
Show resolved Hide resolved
}

impl From<&str> for WasmTarget {
fn from(value: &str) -> Self {
match value {
"wasm32-wasi-preview1" => WasmTarget::WasiPreview1,
"wasm32-wasi" => WasmTarget::WasiPreview1,
"wasm32-wasi-preview2" => WasmTarget::WasiPreview2,
_ => WasmTarget::CoreModule,
}
}
}

impl From<String> for WasmTarget {
fn from(value: String) -> Self {
value.as_str().into()
}
}

impl Display for WasmTarget {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match &self {
WasmTarget::CoreModule => "wasm32-unknown-unknown",
WasmTarget::WasiPreview1 => "wasm32-wasi",
WasmTarget::WasiPreview2 => "wasm32-wasi-preview2",
})
}
}

#[derive(Deserialize, Debug)]
struct RawProjectConfig {
/// The language of the project, e.g. rust, tinygo. This is used to determine which config to parse.
pub language: String,
Expand All @@ -205,13 +259,13 @@ struct RawProjectConfig {
pub tinygo: Option<RawTinyGoConfig>,
}

#[derive(serde::Deserialize, Debug, PartialEq, Eq, Clone, Default)]
#[derive(Deserialize, Debug, PartialEq, Eq, Clone, Default)]
pub struct TinyGoConfig {
/// The path to the tinygo binary. Optional, will default to `tinygo` if not specified.
pub tinygo_path: Option<PathBuf>,
}

#[derive(serde::Deserialize, Debug, PartialEq, Default)]
#[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>,
Expand Down
Loading