oxide_cli/addons/steps/
copy.rs1use 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}