Skip to main content

oxide_cli/addons/steps/
copy.rs

1use std::path::Path;
2
3use anyhow::{Context, Result};
4use inquire::Confirm;
5
6use crate::addons::manifest::{CopyStep, IfExists};
7
8use super::Rollback;
9
10pub fn execute_copy(step: &CopyStep, addon_dir: &Path, project_root: &Path) -> Result<Vec<Rollback>> {
11  let src = super::safe_join(addon_dir, &step.src, "addon source")?;
12  let dest = super::safe_join(project_root, &step.dest, "copy destination")?;
13
14  let mut rollbacks = Vec::new();
15
16  if dest.exists() {
17    match step.if_exists {
18      IfExists::Skip => return Ok(rollbacks),
19      IfExists::Ask => {
20        let overwrite = Confirm::new(&format!("{} already exists. Overwrite?", step.dest))
21          .with_default(false)
22          .prompt()?;
23        if !overwrite {
24          return Ok(rollbacks);
25        }
26        rollbacks.push(Rollback::RestoreFile { path: dest.clone(), original: std::fs::read(&dest)? });
27      }
28      IfExists::Overwrite => {
29        rollbacks.push(Rollback::RestoreFile { path: dest.clone(), original: std::fs::read(&dest)? });
30      }
31    }
32  } else {
33    rollbacks.push(Rollback::DeleteCreatedFile { path: dest.clone() });
34  }
35
36  if let Some(parent) = dest.parent() {
37    std::fs::create_dir_all(parent)?;
38  }
39  std::fs::copy(&src, &dest)
40    .with_context(|| format!("Failed to copy {} to {}", src.display(), dest.display()))?;
41
42  Ok(rollbacks)
43}