libkelp/lib/cli/
install.rs1use crate::lib::{
2 config::loader::load_cfg,
3 fsutil::{
4 copy::copy,
5 paths::{get_ins_root, get_root},
6 },
7 structs::{config::KelpDotConfig, pm::PackageManager},
8 util::{
9 exec::get_root_exec_program,
10 os::{get_host_os, is_os},
11 pm::get_distro_pm,
12 scripts::run_script,
13 },
14};
15use anyhow::Context;
16use kelpdot_macros::*;
17use std::{path::Path, process::Command};
18pub fn install() -> anyhow::Result<()> {
19 let root = get_root()?;
20 cyan_print!("[INFO] Installing dotfiles {}", root);
21 debug_print!("Building OS list...");
22 let os = get_host_os()?;
23 let insroot = get_ins_root()?;
24 debug_print!("Install root: {}", insroot);
25 cyan_print!("Found OS {}", os.prettyname);
26 let config: KelpDotConfig = load_cfg(root.clone())?;
27 if let Some(scripts) = config.prerun {
28 for script in scripts {
29 cyan_print!("[PRERUN] Running script {}", script.path);
30 run_script(root.clone(), script)?;
31 }
32 }
33 if let Some(files) = config.homefiles {
34 let home_files_path = format!("{}/home", root);
35 for file in files {
36 if let Some(distro) = &file.onlyon {
37 if &os.name != distro && !os.submatches.iter().any(|mat| mat == distro) {
38 debug_print!("Not installing file {} because host != onlyon", file);
39 break;
40 }
41 }
42 let home =
43 std::env::var("HOME").with_context(|| red!("Unable to get env var $HOME!"))?; debug_print!("Home: {}", home);
45 if Path::new(&format!("{}/{}", home_files_path, file.path)).exists() {
46 cyan_print!("[INFO] Installing {}", file);
47 copy(
48 format!("{}/{}", home_files_path, file.path),
49 format!("{}/{}/{}", insroot, home, file.path),
50 )?;
51 }
52 }
53 }
54 if let Some(files) = config.rootfiles {
60 let mut bash_code = String::from("#!/usr/bin/env sh\n#This script has been auto-generated and will be runned by KelpDot\n#It isn't intended to be modified manually\n");
61 for file in files {
62 if let Some(distro) = &file.onlyon {
63 if &os.name != distro && !os.submatches.iter().any(|mat| mat == distro) {
64 debug_print!("Not installing file {} because host != onlyon", file);
65 break;
66 }
67 }
68 let fpath = format!("{}{}", root, file.path);
69 let path = Path::new(&fpath);
71 let inspath = format!("{}/{}", insroot, &file.path);
72 let dest_parent = Path::new(&inspath).parent().unwrap().to_str().unwrap();
73 if path.exists() {
74 bash_code = format!(
75 "{}if [[ ! -d {} ]]\nthen\nmkdir -p {}\nfi\ncp -r {} {}\n",
76 bash_code,
77 dest_parent,
78 dest_parent,
79 path.to_str().unwrap(),
80 dest_parent
81 );
82 }
83 }
84 std::fs::write("/tmp/kelpdot_install.sh", bash_code)?;
85 let rexec = get_root_exec_program()?;
86 Command::new(&rexec) .arg("sh")
88 .arg("/tmp/kelpdot_install.sh")
89 .status()
90 .with_context(|| red!("Unable to call rootfiles install script!"))?;
91 }
92 if let Some(packages) = config.packages {
94 let mut pm = get_distro_pm()?;
95 if let Some(gentoo) = packages.gentoo {
96 if is_os("gentoo")? {
97 if let Some(pkgs) = gentoo.packages {
98 pm.install_packages(pkgs)?;
99 }
100 if let Some(file) = gentoo.with_file {
101 let mut packages: Vec<String> = Vec::new();
102 let filepath = format!("{}/{}", root, file);
103 let fpath = Path::new(&filepath);
104 if fpath.exists() {
105 let contents = std::fs::read_to_string(filepath)?;
106 contents.lines().into_iter().for_each(|x| {
107 packages.push(String::from(x));
108 });
109 }
110 pm.install_packages(packages)?;
111 }
112 }
113 }
114 }
115 if let Some(scripts) = config.postrun {
116 for script in scripts {
117 cyan_print!("[POSTRUN] Running script {}", script.path);
118 run_script(root.clone(), script)?;
119 }
120 }
121 Ok(())
122}