use super::init::extract_template_pack_toml_zfile;
use super::packer::pack_dir;
use crate::exec::cli::PackArgs;
use crate::hub::get_hub;
use crate::{Error, Result, term};
use aho_corasick::AhoCorasick;
use simple_fs::SPath;
use std::fs;
use std::io::{self};
pub async fn exec_pack(pack_args: &PackArgs) -> Result<()> {
let hub = get_hub();
let src_dir = SPath::from(&pack_args.dir_path);
if !src_dir.exists() {
return Err(Error::custom(format!("Source directory '{src_dir}' does not exist")));
}
let dest_dir = if let Some(output_dir) = &pack_args.output_dir {
SPath::from(output_dir)
} else {
SPath::from(".")
};
if !dest_dir.exists() {
std::fs::create_dir_all(&dest_dir)?;
}
hub.publish(format!("\nPacking directory '{src_dir}' into a .aipack file..."))
.await;
match pack_dir(&src_dir, &dest_dir) {
Ok(pack_data) => {
hub.publish(format!(
"\nSuccessfully packed directory into '{}'",
pack_data.pack_file
))
.await;
Ok(())
}
Err(Error::AipackTomlMissing(_missing_toml_path)) => {
if let Err(gen_err) = generate_pack_toml(&src_dir).await {
hub.publish(format!("Failed to generate pack.toml: {gen_err}")).await;
return Ok(());
}
hub.publish(format!(
"\n{src_dir}/pack.toml was missing, a default one was generated\n\nPlease check {src_dir}/pack.toml"
))
.await;
hub.publish("\nContinue with packing? (Y/n): ").await;
tokio::task::yield_now().await;
tokio::time::sleep(std::time::Duration::from_millis(10)).await;
let mut input = String::new();
io::stdin().read_line(&mut input)?;
if term::is_input_yes(&input) {
match pack_dir(&src_dir, &dest_dir) {
Ok(pack_data) => {
hub.publish(format!("Successfully packed directory into '{}'", pack_data.pack_file))
.await;
}
Err(retry_err) => {
hub.publish(format!(
"Failed to pack directory after generating pack.toml: {retry_err}",
))
.await;
}
}
} else {
hub.publish("\nPacking cancelled by user.").await;
}
Ok(())
}
Err(other) => Err(other),
}
}
async fn generate_pack_toml(dir_path: &SPath) -> Result<()> {
let hub = get_hub();
let pack_toml_zfile = extract_template_pack_toml_zfile()?;
let mut content =
String::from_utf8(pack_toml_zfile.content).map_err(|_| Error::custom("template pack.toml is not UTF8 ??"))?;
let dir_name = dir_path
.file_name()
.ok_or_else(|| Error::custom("Unable to extract directory name"))?;
let patterns = &["DIR_NAME"];
let replacements = &[dir_name];
let ac =
AhoCorasick::new(patterns).map_err(|err| Error::custom(format!("AhoCorasick pattern fail.\nCause: {err}")))?;
content = ac.replace_all(&content, replacements);
let toml_path = dir_path.join("pack.toml");
fs::write(&toml_path, content)?;
hub.publish(format!("-> Created default pack.toml at '{toml_path}'")).await;
Ok(())
}