aboutsummaryrefslogtreecommitdiffstats
path: root/src/install.rs
blob: 57da4316a6ac5b8a5a686c1808206f6ea9143a4c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
use crate::config::{Step, CopyPath};
use std::{fs, path::PathBuf};
use crate::util::expand_home;

fn resolve_paths_and_mkdir(paths: &CopyPath, base_path: &PathBuf) -> Result<(PathBuf, PathBuf), Box<dyn std::error::Error>> {
    let expanded_home = &expand_home(&paths.to);
    let destination = PathBuf::from(expanded_home);
    let mut source = base_path.clone();
    source.push(&paths.from);
    
    let dest_parent = destination.parent().unwrap();
    fs::create_dir_all(dest_parent)?;
    Ok((source, destination))
}

fn ln(paths: &CopyPath, base_path: &PathBuf) -> Result<bool, Box<dyn std::error::Error>> {
    let (source, destination) = resolve_paths_and_mkdir(paths, base_path)?;
    let source = source.as_path();
    let destination = destination.as_path();
    
    let _ = fs::remove_file(destination);
    fs::hard_link(source, destination)?;
    Ok(true)
}

fn cp(paths: &CopyPath, base_path: &PathBuf) -> Result<bool, Box<dyn std::error::Error>> {
    let (source, destination) = resolve_paths_and_mkdir(paths, base_path)?;
    let source = source.as_path();
    let destination = destination.as_path();

    if fs::metadata(destination).is_ok() {
        return Ok(false); 
    }
    fs::copy(source, destination)?;
    Ok(true)
}

fn run_shell(command: &String) -> Result<bool, Box<dyn std::error::Error>> {
    let exit = std::process::Command::new("/bin/sh").arg("-c").arg(command).output()?;
    return Ok(exit.status.success());
}

pub fn run_step(step: &Step, base_path: &PathBuf) -> Result<bool, Box<dyn std::error::Error>> {
    match step {
        Step::Link(path) => { ln(path, base_path) },
        Step::Copy(path) => { cp(path, base_path) },
        Step::Shell(command) => run_shell(command),
    }
}