use std::path::{Path, PathBuf};
use anyhow::Context;
use clap::{Args, Subcommand};
use wasm_pkg_core::{
lock::LockFile,
wit::{self, OutputType},
};
use crate::Common;
#[derive(Debug, Subcommand)]
pub enum WitCommands {
Build(BuildArgs),
Fetch(FetchArgs),
Update(UpdateArgs),
}
impl WitCommands {
pub async fn run(self) -> anyhow::Result<()> {
match self {
WitCommands::Build(args) => args.run().await,
WitCommands::Fetch(args) => args.run().await,
WitCommands::Update(args) => args.run().await,
}
}
}
#[derive(Debug, Args)]
pub struct BuildArgs {
#[clap(short = 'd', long = "wit-dir", default_value = "wit")]
pub dir: PathBuf,
#[clap(short = 'o', long = "output")]
pub output: Option<PathBuf>,
#[clap(flatten)]
pub common: Common,
}
#[derive(Debug, Args)]
pub struct FetchArgs {
#[clap(short = 'd', long = "wit-dir", default_value = "wit")]
pub dir: PathBuf,
#[clap(short = 't', long = "type")]
pub output_type: Option<OutputType>,
#[clap(flatten)]
pub common: Common,
}
#[derive(Debug, Args)]
pub struct UpdateArgs {
#[clap(short = 'd', long = "wit-dir", default_value = "wit")]
pub dir: PathBuf,
#[clap(short = 't', long = "type")]
pub output_type: Option<OutputType>,
#[clap(flatten)]
pub common: Common,
}
impl BuildArgs {
pub async fn run(self) -> anyhow::Result<()> {
check_dir(&self.dir).await?;
let client = self.common.get_client().await?;
let wkg_config = wasm_pkg_core::config::Config::load().await?;
let mut lock_file = LockFile::load(false).await?;
let (pkg_ref, version, bytes) =
wit::build_package(&wkg_config, self.dir, &mut lock_file, client).await?;
let output_path = if let Some(path) = self.output {
path
} else {
let mut file_name = pkg_ref.to_string();
if let Some(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?;
println!("WIT package written to {}", output_path.display());
Ok(())
}
}
impl FetchArgs {
pub async fn run(self) -> anyhow::Result<()> {
check_dir(&self.dir).await?;
let client = self.common.get_client().await?;
let wkg_config = wasm_pkg_core::config::Config::load().await?;
let mut lock_file = LockFile::load(false).await?;
wit::fetch_dependencies(
&wkg_config,
self.dir,
&mut lock_file,
client,
self.output_type.unwrap_or_default(),
)
.await?;
lock_file.write().await?;
Ok(())
}
}
impl UpdateArgs {
pub async fn run(self) -> anyhow::Result<()> {
check_dir(&self.dir).await?;
let client = self.common.get_client().await?;
let wkg_config = wasm_pkg_core::config::Config::load().await?;
let mut lock_file = LockFile::load(false).await?;
lock_file.packages.clear();
wit::fetch_dependencies(
&wkg_config,
self.dir,
&mut lock_file,
client,
self.output_type.unwrap_or_default(),
)
.await?;
lock_file.write().await?;
todo!()
}
}
async fn check_dir(dir: impl AsRef<Path>) -> anyhow::Result<()> {
tokio::fs::metadata(dir).await.context("Unable to read wit directory. This command should be run from the parent directory of the wit directory or a directory can be overridden with the --wit-dir argument").map(|_|())
}