use std::collections::HashMap;
use std::path::PathBuf;
use anyhow::Result;
use clap::Parser;
use serde_json::json;
use wash_lib::build::{build_project, SignConfig};
use wash_lib::cli::CommandOutput;
use wash_lib::parser::{get_config, TypeConfig};
#[derive(Debug, Parser, Clone)]
#[clap(name = "build")]
pub(crate) struct BuildCommand {
#[clap(short = 'p', long = "config-path")]
config_path: Option<PathBuf>,
#[clap(long = "keys-directory", env = "WASH_KEYS", hide_env_values = true)]
pub keys_directory: Option<PathBuf>,
#[clap(
short = 'i',
long = "issuer",
env = "WASH_ISSUER_KEY",
hide_env_values = true
)]
pub issuer: Option<String>,
#[clap(
short = 's',
long = "subject",
env = "WASH_SUBJECT_KEY",
hide_env_values = true
)]
pub subject: Option<String>,
#[clap(long = "disable-keygen")]
pub disable_keygen: bool,
#[clap(long = "build-only")]
pub build_only: bool,
}
pub(crate) fn handle_command(command: BuildCommand) -> Result<CommandOutput> {
let config = get_config(command.config_path, Some(true))?;
match config.project_type {
TypeConfig::Actor(ref _actor_config) => {
let sign_config = if command.build_only {
None
} else {
Some(SignConfig {
keys_directory: command.keys_directory,
issuer: command.issuer,
subject: command.subject,
disable_keygen: command.disable_keygen,
})
};
let actor_path = build_project(&config, sign_config)?;
let json_output = HashMap::from([
("actor_path".to_string(), json!(actor_path)),
("signed".to_string(), json!(command.build_only)),
]);
Ok(CommandOutput::new(
if command.build_only {
format!("Actor built and can be found at {:?}", actor_path)
} else {
format!(
"Actor built and signed and can be found at {:?}",
actor_path
)
},
json_output,
))
}
_ => {
let path = build_project(&config, None)?;
Ok(CommandOutput::new(
format!("Built artifact can be found at {:?}", path),
HashMap::from([("path".to_string(), json!(path))]),
))
}
}
}
#[cfg(test)]
mod test {
use super::*;
use clap::Parser;
#[test]
fn test_build_comprehensive() {
let cmd: BuildCommand = Parser::try_parse_from(["build"]).unwrap();
assert!(cmd.config_path.is_none());
assert!(!cmd.disable_keygen);
assert!(cmd.issuer.is_none());
assert!(cmd.subject.is_none());
assert!(cmd.keys_directory.is_none());
let cmd: BuildCommand = Parser::try_parse_from([
"build",
"-p",
"/",
"--disable-keygen",
"--issuer",
"/tmp/iss.nk",
"--subject",
"/tmp/sub.nk",
"--keys-directory",
"/tmp",
])
.unwrap();
assert_eq!(cmd.config_path, Some(PathBuf::from("/")));
assert!(cmd.disable_keygen);
assert_eq!(cmd.issuer, Some("/tmp/iss.nk".to_string()));
assert_eq!(cmd.subject, Some("/tmp/sub.nk".to_string()));
assert_eq!(cmd.keys_directory, Some(PathBuf::from("/tmp")));
}
}