use std::path::PathBuf;
use clap::Args;
use wash_lib::build::load_lock_file;
use wash_lib::cli::{CommandOutput, CommonPackageArgs};
use wash_lib::deps::WkgFetcher;
use wash_lib::parser::load_config;
use wasm_pkg_core::wit::{self};
#[derive(Debug, Args, Clone)]
pub struct BuildArgs {
#[clap(short = 'd', long = "wit-dir", default_value = "wit")]
pub dir: PathBuf,
#[clap(short = 'f', long = "file")]
pub output_file: Option<PathBuf>,
#[clap(flatten)]
pub common: CommonPackageArgs,
#[clap(short = 'p', long = "config-path")]
config_path: Option<PathBuf>,
}
pub async fn invoke(
BuildArgs {
dir,
output_file,
common,
config_path,
}: BuildArgs,
) -> anyhow::Result<CommandOutput> {
let wkg_config = if let Ok(proj) = load_config(config_path.clone(), Some(true)).await {
proj.package_config
} else {
wasm_pkg_core::config::Config::load().await?
};
let wkg = WkgFetcher::from_common(&common, wkg_config).await?;
let project_cfg_dir = load_config(config_path, Some(true))
.await
.map(|cfg| cfg.wasmcloud_toml_dir)
.unwrap_or(dir.clone());
let mut lock_file = load_lock_file(&project_cfg_dir).await?;
let (pkg_ref, version, bytes) = wit::build_package(
&wkg.get_config().to_owned(),
dir,
&mut lock_file,
wkg.into_client(),
)
.await?;
let output_path = match output_file {
Some(path) => path,
None => {
let mut file_name = pkg_ref.to_string();
if let Some(ref version) = version {
file_name.push_str(&format!("@{version}"));
}
file_name.push_str(".wasm");
PathBuf::from(file_name)
}
};
tokio::fs::write(&output_path, bytes).await?;
lock_file.write().await?;
Ok(CommandOutput::new(
format!("WIT package written to {}", output_path.display()),
[
("path".to_string(), serde_json::to_value(output_path)?),
("package".to_string(), pkg_ref.to_string().into()),
("version".to_string(), version.map(|v| v.to_string()).into()),
]
.into(),
))
}