1#![feature(exit_status_error)]
21
22use std::path::Path;
23use std::path::PathBuf;
24
25use color_eyre::owo_colors::OwoColorize;
26use ytil_sys::cli::Args;
27
28const BINS: &[&str] = &[
31 "idt", "catl", "fkr", "gch", "gcu", "ghl", "oe", "rmr", "tec", "try", "vpg", "yghfl", "yhfp",
32];
33const LIBS: &[(&str, &str)] = &[("libnvrim.dylib", "nvrim.so")];
35const BINS_DEFAULT_PATH: &[&str] = &[".local", "bin"];
37const NVIM_LIBS_DEFAULT_PATH: &[&str] = &[".config", "nvim", "lua"];
39
40fn remove_last_n_dirs(path: &mut PathBuf, n: usize) {
42 for _ in 0..n {
43 if !path.pop() {
44 return;
45 }
46 }
47}
48
49fn drop_element<T, U: ?Sized>(vec: &mut Vec<T>, target: &U) -> bool
52where
53 T: PartialEq<U>,
54{
55 if let Some(idx) = vec.iter().position(|x| x == target) {
56 vec.swap_remove(idx);
57 return true;
58 }
59 false
60}
61
62fn cp(from: &Path, to: &Path) -> color_eyre::Result<()> {
69 ytil_sys::file::atomic_cp(from, to)?;
70 println!("{} {} to {}", "Copied".green().bold(), from.display(), to.display());
71 Ok(())
72}
73
74fn main() -> color_eyre::Result<()> {
76 color_eyre::install()?;
77
78 let mut args = ytil_sys::cli::get();
79
80 if args.has_help() {
81 println!("{}", include_str!("../help.txt"));
82 return Ok(());
83 }
84
85 let is_debug = drop_element(&mut args, "--debug");
86 let bins_path = args.first().cloned().map_or_else(
87 || ytil_sys::dir::build_home_path(BINS_DEFAULT_PATH),
88 |supplied_bins_path| Ok(PathBuf::from(supplied_bins_path)),
89 )?;
90 let cargo_target_path = args.get(1).cloned().map_or_else(
91 || {
92 std::env::var("CARGO_MANIFEST_DIR").map(|cargo_manifest_dir| {
93 let mut x = PathBuf::from(cargo_manifest_dir);
94 remove_last_n_dirs(&mut x, 2);
95 x.join("target")
96 })
97 },
98 |x| Ok(PathBuf::from(x)),
99 )?;
100 let nvim_libs_path = args.get(2).cloned().map_or_else(
101 || ytil_sys::dir::build_home_path(NVIM_LIBS_DEFAULT_PATH),
102 |supplied_nvim_libs_path| Ok(PathBuf::from(supplied_nvim_libs_path)),
103 )?;
104
105 let (cargo_target_location, build_profile) = if is_debug {
106 (cargo_target_path.join("debug"), None)
107 } else {
108 (cargo_target_path.join("release"), Some("--release"))
109 };
110
111 ytil_cmd::silent_cmd("cargo").args(["fmt"]).status()?.exit_ok()?;
112
113 if !is_debug {
115 ytil_cmd::silent_cmd("cargo")
116 .args(["clippy", "--all-targets", "--all-features", "--", "-D", "warnings"])
117 .status()?
118 .exit_ok()?;
119 }
120
121 ytil_cmd::silent_cmd("cargo")
122 .args([Some("build"), build_profile].into_iter().flatten())
123 .status()?
124 .exit_ok()?;
125
126 for bin in BINS {
127 cp(&cargo_target_location.join(bin), &bins_path.join(bin))?;
128 }
129
130 for (source_lib_name, target_lib_name) in LIBS {
131 cp(
132 &cargo_target_location.join(source_lib_name),
133 &nvim_libs_path.join(target_lib_name),
134 )?;
135 }
136
137 Ok(())
138}
139
140#[cfg(test)]
141mod tests {
142 use rstest::rstest;
143
144 use super::*;
145
146 #[test]
147 fn drop_element_returns_true_and_removes_the_element_from_the_vec() {
148 let mut input = vec![42, 7];
149 assert!(drop_element(&mut input, &7));
150 assert_eq!(input, vec![42]);
151 }
152
153 #[test]
154 fn drop_element_returns_false_and_does_nothing_to_a_non_empty_vec() {
155 let mut input = vec![42, 7];
156 assert!(!drop_element(&mut input, &3));
157 assert_eq!(input, vec![42, 7]);
158 }
159
160 #[test]
161 fn drop_element_returns_false_and_does_nothing_to_an_empty_vec() {
162 let mut input: Vec<usize> = vec![];
163 assert!(!drop_element(&mut input, &3));
164 assert!(input.is_empty());
165 }
166
167 #[rstest]
168 #[case::no_dirs_removed(PathBuf::from("/home/user/docs"), 0, PathBuf::from("/home/user/docs"))]
169 #[case::remove_one_dir(PathBuf::from("/home/user/docs"), 1, PathBuf::from("/home/user"))]
170 #[case::remove_more_than_exist(PathBuf::from("/home/user"), 5, PathBuf::from("/"))]
171 #[case::root_path(PathBuf::from("/"), 1, PathBuf::from("/"))]
172 #[case::empty_path(PathBuf::new(), 1, PathBuf::new())]
173 fn remove_last_n_dirs_works(#[case] mut initial: PathBuf, #[case] n: usize, #[case] expected: PathBuf) {
174 remove_last_n_dirs(&mut initial, n);
175 pretty_assertions::assert_eq!(initial, expected);
176 }
177}