use crate::util;
use anyhow::{Context, Result};
use std::fs;
use std::process::Command;
pub fn run(
input: String,
output: Option<String>,
cargo_args: Vec<String>,
verbose: bool,
) -> Result<()> {
crate::info!("[INFO] Packaging as MSIX...");
let info = util::load_project_info()?;
let manifest_path = info.manifest_dir.join("appxmanifest.xml");
if !manifest_path.exists() {
anyhow::bail!(
"appxmanifest.xml not found. Run 'winapp init' first to set up your project."
);
}
crate::info!("[INFO] Building...");
let build_result = util::build_and_get_exe(&info.manifest_dir, &cargo_args, verbose)?;
let exe_path = &build_result.exe_path;
let dist_dir = std::env::current_dir()
.context("Failed to get current directory")?
.join(input);
fs::create_dir_all(&dist_dir).context("Failed to create dist directory")?;
let exe_name = exe_path
.file_name()
.context("Failed to get executable filename")?;
let dest_exe = dist_dir.join(exe_name);
fs::copy(exe_path, &dest_exe)
.with_context(|| format!("Failed to copy {:?} to {:?}", exe_path, dest_exe))?;
crate::status!(
verbose,
"> Copied {} to {}/",
exe_name.to_string_lossy(),
dist_dir.display()
);
let assets_src = info.manifest_dir.join("Assets");
let assets_dest = dist_dir.join("Assets");
if assets_src.exists() {
copy_dir_recursive(&assets_src, &assets_dest)?;
crate::status!(verbose, "> Copied Assets/");
}
let cert_path = info.manifest_dir.join("devcert.pfx");
if !cert_path.exists() {
crate::info!("[WARN] No certificate found. Generating one...");
let mut cmd = Command::new("winapp");
cmd.args(["cert", "generate"])
.current_dir(&info.manifest_dir);
if verbose {
cmd.arg("--verbose");
}
let status = cmd.status().context("Failed to generate certificate")?;
if !status.success() {
anyhow::bail!("Failed to generate certificate. Run 'winapp cert generate' manually.");
}
}
crate::info!("[INFO] Running winapp pack...");
let mut cmd = Command::new("winapp");
cmd.arg("pack").arg(&dist_dir).arg("--cert").arg(&cert_path);
if let Some(out_path) = output {
cmd.arg("--output").arg(out_path);
}
if verbose {
cmd.arg("--verbose");
}
let status = cmd.status().context("Failed to run winapp pack")?;
if !status.success() {
anyhow::bail!("winapp pack failed");
}
crate::info!("[INFO] MSIX package created.");
crate::info!("To install:");
crate::info!(" 1. Install the certificate: winapp cert install devcert.pfx");
crate::info!(" 2. Double-click the .msix file to install");
Ok(())
}
fn copy_dir_recursive(src: &std::path::Path, dest: &std::path::Path) -> Result<()> {
fs::create_dir_all(dest)?;
for entry in fs::read_dir(src)? {
let entry = entry?;
let file_type = entry.file_type()?;
let src_path = entry.path();
let dest_path = dest.join(entry.file_name());
if file_type.is_dir() {
copy_dir_recursive(&src_path, &dest_path)?;
} else {
fs::copy(&src_path, &dest_path)?;
}
}
Ok(())
}