flodl_cli/util/
archive.rs1use std::path::Path;
6use std::process::{Command, Stdio};
7
8pub fn extract_zip(zip_path: &Path, dest_dir: &Path) -> Result<(), String> {
12 std::fs::create_dir_all(dest_dir)
13 .map_err(|e| format!("cannot create {}: {}", dest_dir.display(), e))?;
14
15 let zip_str = zip_path
16 .to_str()
17 .ok_or_else(|| "zip path is not valid UTF-8".to_string())?;
18 let dest_str = dest_dir
19 .to_str()
20 .ok_or_else(|| "destination path is not valid UTF-8".to_string())?;
21
22 let status = if cfg!(target_os = "windows") {
23 Command::new("powershell")
24 .args([
25 "-NoProfile",
26 "-Command",
27 &format!(
28 "Expand-Archive -Force -Path '{}' -DestinationPath '{}'",
29 zip_str, dest_str
30 ),
31 ])
32 .stdout(Stdio::null())
33 .stderr(Stdio::inherit())
34 .status()
35 } else {
36 if Command::new("unzip")
38 .arg("--help")
39 .stdout(Stdio::null())
40 .stderr(Stdio::null())
41 .status()
42 .is_err()
43 {
44 return Err(
45 "unzip is required but not installed.\n\
46 \n\
47 \x20 Ubuntu/Debian: sudo apt install unzip\n\
48 \x20 Fedora/RHEL: sudo dnf install unzip\n\
49 \x20 macOS: available by default"
50 .into(),
51 );
52 }
53 Command::new("unzip")
54 .args(["-q", "-o", zip_str, "-d", dest_str])
55 .stdout(Stdio::null())
56 .stderr(Stdio::inherit())
57 .status()
58 };
59
60 match status {
61 Ok(s) if s.success() => Ok(()),
62 Ok(s) => Err(format!(
63 "extraction failed (exit code {})\n Archive: {}",
64 s.code().unwrap_or(-1),
65 zip_path.display()
66 )),
67 Err(e) => Err(format!("failed to run extraction command: {}", e)),
68 }
69}