/ src / import.rs
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  }