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(
11  step: &CopyStep,
12  addon_dir: &Path,
13  project_root: &Path,
14) -> Result<Vec<Rollback>> {
15  let src = super::safe_join(addon_dir, &step.src, "addon source")?;
16  let dest = super::safe_join(project_root, &step.dest, "copy destination")?;
17
18  let mut rollbacks = Vec::new();
19
20  if dest.exists() {
21    match step.if_exists {
22      IfExists::Skip => return Ok(rollbacks),
23      IfExists::Ask => {
24        let overwrite = Confirm::new(&format!("{} already exists. Overwrite?", step.dest))
25          .with_default(false)
26          .prompt()?;
27        if !overwrite {
28          return Ok(rollbacks);
29        }
30        rollbacks.push(Rollback::RestoreFile {
31          path: dest.clone(),
32          original: std::fs::read(&dest)?,
33        });
34      }
35      IfExists::Overwrite => {
36        rollbacks.push(Rollback::RestoreFile {
37          path: dest.clone(),
38          original: std::fs::read(&dest)?,
39        });
40      }
41    }
42  } else {
43    rollbacks.push(Rollback::DeleteCreatedFile { path: dest.clone() });
44  }
45
46  if let Some(parent) = dest.parent() {
47    std::fs::create_dir_all(parent)?;
48  }
49  std::fs::copy(&src, &dest)
50    .with_context(|| format!("Failed to copy {} to {}", src.display(), dest.display()))?;
51
52  Ok(rollbacks)
53}