use clap::Parser;
use jam_pvm_builder::{BlobType, ProfileType};
use temp_dir::TempDir;
#[derive(clap::ValueEnum, Clone, Debug)]
#[value(rename_all = "lowercase")]
enum ModuleType {
#[clap(alias = "auto")]
Automatic,
#[clap(alias = "serv")]
Service,
#[clap(alias = "auth")]
Authorizer,
#[clap(alias = "guest")]
CoreVmGuest,
}
#[derive(clap::ValueEnum, Clone, Debug)]
#[value(rename_all = "lowercase")]
enum Profile {
Debug,
Release,
Production,
}
impl From<Profile> for ProfileType {
fn from(profile: Profile) -> ProfileType {
match profile {
Profile::Debug => ProfileType::Debug,
Profile::Release => ProfileType::Release,
Profile::Production => ProfileType::Other("production"),
}
}
}
#[derive(Parser, Debug)]
#[command(name = "jam-pvm-build", version, long_version = format!("{}\nGP {}", env!("CARGO_PKG_VERSION"), jam_types::GP_VERSION))]
struct Args {
path: Option<std::path::PathBuf>,
#[arg(short, long)]
output: Option<std::path::PathBuf>,
#[arg(short, long, value_enum, default_value_t = ModuleType::Automatic)]
module: ModuleType,
#[arg(long)]
auto_install: bool,
#[arg(short, long, value_enum, default_value_t = Profile::Release)]
profile: Profile,
}
fn main() -> std::process::ExitCode {
let args = Args::parse();
let cd = std::env::current_dir().expect("Unable to get current directory");
let crate_dir = args.path.unwrap_or_else(|| cd.clone());
let blob_type = match args.module {
ModuleType::Automatic => {
let filename = crate_dir.file_name().and_then(|x| x.to_str()).expect("Invalid path?");
let con_serv = filename.contains("service");
let con_auth = filename.contains("authorizer");
let con_corevm = filename.contains("corevm");
if filename.ends_with("-service") || (con_serv && !con_auth && !con_corevm) {
BlobType::Service
} else if filename.ends_with("-authorizer") || (!con_serv && con_auth && !con_corevm) {
BlobType::Authorizer
} else if filename.ends_with("-guest") || (!con_serv && !con_auth && con_corevm) {
BlobType::CoreVmGuest
} else {
panic!("Could not determine module type from crate name");
}
},
ModuleType::Service => BlobType::Service,
ModuleType::Authorizer => BlobType::Authorizer,
ModuleType::CoreVmGuest => BlobType::CoreVmGuest,
};
let out_dir = TempDir::new().expect("Could not create temporary directory");
let (crate_name, pvm_path, _hash_path) = jam_pvm_builder::build_pvm_blob(
&crate_dir,
blob_type,
out_dir.path(),
args.auto_install,
args.profile.into(),
);
let output_file = match args.output {
Some(output_path) if output_path.is_dir() =>
blob_type.output_file(&output_path, &crate_name),
Some(output_path) => output_path,
None => blob_type.output_file(&cd, &crate_name),
};
std::fs::copy(pvm_path, &output_file).expect("Unable to write to output file");
let blob_type_name = match blob_type {
BlobType::Service | BlobType::Authorizer => "JAM",
BlobType::CoreVmGuest => "CoreVM",
};
println!("Written {blob_type_name}-PVM blob for {crate_name} to {}...", output_file.display());
std::process::ExitCode::SUCCESS
}