import.rs
1 use std::{ 2 fs, 3 io::{self}, 4 path::Path, 5 }; 6 7 use anyhow::{Context as _, Result, ensure}; 8 9 use crate::{ 10 add::add, 11 util::{config_path, system_path}, 12 }; 13 14 /// Imports the given config path from the system path 15 pub fn import(cli_path: &Path, copy: bool) -> Result<()> { 16 let config_path = config_path(cli_path)?; 17 let system_path = system_path(cli_path)?; 18 19 if copy { 20 ensure!( 21 !system_path.is_dir(), 22 "Only files and symlinks are currently supported with --copy" 23 ); 24 } 25 26 // Copy system path to config path 27 if system_path.is_dir() { 28 copy_dir(&system_path, &config_path) 29 } else { 30 fs::copy(&system_path, &config_path).map(|_| ()) 31 } 32 .with_context(|| { 33 format!( 34 "copying system path ({}) to config path ({})", 35 system_path.display(), 36 config_path.display() 37 ) 38 })?; 39 40 add(cli_path, true, copy) 41 } 42 43 /// Recursively copies the source directory to the target path 44 fn copy_dir(source: impl AsRef<Path>, target: impl AsRef<Path>) -> io::Result<()> { 45 // Create destination 46 fs::create_dir_all(&target)?; 47 48 for entry in fs::read_dir(source)? { 49 let entry = entry?; 50 51 let entry_source_path = entry.path(); 52 let entry_target_path = target.as_ref().join(entry.file_name()); 53 54 if entry_source_path.is_dir() { 55 copy_dir(entry_source_path, entry_target_path)?; 56 } else { 57 fs::copy(entry_source_path, entry_target_path)?; 58 } 59 } 60 61 Ok(()) 62 }