1use crate::commands::PresetReportFormat;
4use anyhow::Result;
5use shine_core::runtime::PresetPackReportV1;
6use std::path::{Path, PathBuf};
7
8pub async fn handle_pack(
9 path: &Path,
10 output: &Path,
11 force: bool,
12 format: PresetReportFormat,
13) -> Result<bool> {
14 let cwd = std::env::current_dir().unwrap_or_else(|_| Path::new(".").to_path_buf());
15 let mut artifact =
16 shine_core::runtime::pack_preset_path(&shine_core::runtime::RealHost, &cwd, path).await;
17 if artifact.report.valid {
18 let category_input = if path.ends_with("shine.toml") {
19 path.parent().unwrap_or(path)
20 } else {
21 path
22 };
23 let category = absolute(&cwd, category_input);
24 let output = absolute(&cwd, output);
25 if output.starts_with(&category) {
26 invalidate(&mut artifact.report, "output_inside_category");
27 } else if output.exists() && !force {
28 invalidate(&mut artifact.report, "output_exists");
29 } else if shine_core::persist::atomic_write(&output, &artifact.bytes)
30 .await
31 .is_err()
32 {
33 invalidate(&mut artifact.report, "output_write_failed");
34 }
35 }
36 match format {
37 PresetReportFormat::Text => print_text_report(&artifact.report),
38 PresetReportFormat::Json => {
39 println!("{}", serde_json::to_string_pretty(&artifact.report)?)
40 }
41 }
42 Ok(artifact.report.valid)
43}
44
45fn absolute(cwd: &Path, path: &Path) -> PathBuf {
46 if path.is_absolute() {
47 path.to_path_buf()
48 } else {
49 cwd.join(path)
50 }
51}
52
53fn invalidate(report: &mut PresetPackReportV1, code: &str) {
54 report.valid = false;
55 report.files = 0;
56 report.archive_bytes = 0;
57 report.bundle_sha256 = None;
58 report.diagnostics.push(code.to_string());
59}
60
61fn print_text_report(report: &PresetPackReportV1) {
62 println!(
63 "Preset pack: {}",
64 if report.valid { "created" } else { "blocked" }
65 );
66 if let Some(target) = &report.target {
67 println!(" Target: {target}");
68 }
69 for diagnostic in &report.diagnostics {
70 println!(" error[{diagnostic}]");
71 }
72 if report.valid {
73 println!(" Files: {}", report.files);
74 println!(" Archive bytes: {}", report.archive_bytes);
75 println!(
76 " SHA-256: {}",
77 report.bundle_sha256.as_deref().unwrap_or_default()
78 );
79 }
80}