aboutsummaryrefslogtreecommitdiff
path: root/src/utils.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils.rs')
-rw-r--r--src/utils.rs178
1 files changed, 0 insertions, 178 deletions
diff --git a/src/utils.rs b/src/utils.rs
deleted file mode 100644
index 5abb491..0000000
--- a/src/utils.rs
+++ /dev/null
@@ -1,178 +0,0 @@
1use std::{
2 collections::VecDeque,
3 path::{Component, Path, PathBuf},
4};
5
6use crate::{
7 dotup::{self, Dotup},
8 Flags,
9};
10
11pub const DEFAULT_DEPOT_FILE_NAME: &str = ".depot";
12
13/// Returns a list of canonical paths to all the files in `dir`. This includes files in
14/// subdirectories.
15/// Fails if dir isnt a directory or if there is some other io error.
16pub fn collect_files_in_dir_recursive(dir: impl Into<PathBuf>) -> anyhow::Result<Vec<PathBuf>> {
17 let mut paths = Vec::new();
18 let mut dirs = VecDeque::new();
19 dirs.push_back(dir.into());
20
21 while let Some(dir) = dirs.pop_front() {
22 for entry in std::fs::read_dir(dir)? {
23 let entry = entry?;
24 let filetype = entry.file_type()?;
25 if filetype.is_dir() {
26 dirs.push_back(entry.path());
27 } else {
28 paths.push(entry.path());
29 }
30 }
31 }
32
33 Ok(paths)
34}
35
36pub fn collect_paths_in_dir(dir: impl AsRef<Path>) -> anyhow::Result<Vec<PathBuf>> {
37 Ok(std::fs::read_dir(dir)?
38 .filter_map(|e| e.ok())
39 .map(|e| e.path())
40 .collect())
41}
42
43pub fn read_dotup(flags: &Flags) -> anyhow::Result<Dotup> {
44 let depot_path = depot_path_from_flags(flags)?;
45 let install_base = install_base_from_flags(flags);
46 dotup::read(depot_path, install_base)
47}
48
49pub fn write_dotup(dotup: &Dotup) -> anyhow::Result<()> {
50 dotup::write(dotup)
51}
52
53pub fn depot_path_from_flags(flags: &Flags) -> anyhow::Result<PathBuf> {
54 match flags.depot {
55 Some(ref path) => Ok(path.clone()),
56 None => find_depot_path().ok_or_else(|| anyhow::anyhow!("Failed to find depot path")),
57 }
58}
59
60pub fn default_depot_path() -> PathBuf {
61 current_working_directory().join(DEFAULT_DEPOT_FILE_NAME)
62}
63
64pub fn find_depot_path() -> Option<PathBuf> {
65 let mut cwd = current_working_directory();
66 loop {
67 let path = cwd.join(DEFAULT_DEPOT_FILE_NAME);
68 if path.exists() {
69 break Some(path);
70 }
71 if !cwd.pop() {
72 break None;
73 }
74 }
75}
76
77pub fn install_base_from_flags(flags: &Flags) -> PathBuf {
78 match flags.install_base {
79 Some(ref path) => path.clone(),
80 None => default_install_base(),
81 }
82}
83
84pub fn default_install_base() -> PathBuf {
85 PathBuf::from(std::env::var("HOME").expect("Failed to obtain HOME environment variable"))
86}
87pub fn weakly_canonical(path: impl AsRef<Path>) -> PathBuf {
88 let cwd = current_working_directory();
89 weakly_canonical_cwd(path, cwd)
90}
91
92fn weakly_canonical_cwd(path: impl AsRef<Path>, cwd: PathBuf) -> PathBuf {
93 // Adapated from
94 // https://github.com/rust-lang/cargo/blob/fede83ccf973457de319ba6fa0e36ead454d2e20/src/cargo/util/paths.rs#L61
95 let path = path.as_ref();
96
97 let mut components = path.components().peekable();
98 let mut canonical = cwd;
99 let prefix = if let Some(c @ Component::Prefix(..)) = components.peek().cloned() {
100 components.next();
101 PathBuf::from(c.as_os_str())
102 } else {
103 PathBuf::new()
104 };
105
106 for component in components {
107 match component {
108 Component::Prefix(_) => unreachable!(),
109 Component::RootDir => {
110 canonical = prefix.clone();
111 canonical.push(component.as_os_str())
112 }
113 Component::CurDir => {}
114 Component::ParentDir => {
115 canonical.pop();
116 }
117 Component::Normal(p) => canonical.push(p),
118 };
119 }
120
121 canonical
122}
123
124pub fn current_working_directory() -> PathBuf {
125 std::env::current_dir().expect("Failed to obtain current working directory")
126}
127
128pub fn path_ends_with_slash(path: impl AsRef<Path>) -> bool {
129 path.as_ref()
130 .to_str()
131 .map(|s| s.ends_with('/'))
132 .unwrap_or_default()
133}
134
135#[cfg(test)]
136mod tests {
137 use super::*;
138
139 #[test]
140 fn test_weakly_canonical() {
141 let cwd = PathBuf::from("/home/user");
142 assert_eq!(
143 PathBuf::from("/home/dest"),
144 weakly_canonical_cwd("../dest", cwd.clone())
145 );
146 assert_eq!(
147 PathBuf::from("/home/dest/configs/init.vim"),
148 weakly_canonical_cwd("../dest/configs/init.vim", cwd.clone())
149 );
150 assert_eq!(
151 PathBuf::from("/dest/configs/init.vim"),
152 weakly_canonical_cwd("/dest/configs/init.vim", cwd.clone())
153 );
154 assert_eq!(
155 PathBuf::from("/home/user/configs/nvim/lua/setup.lua"),
156 weakly_canonical_cwd("./configs/nvim/lua/setup.lua", cwd.clone())
157 );
158 assert_eq!(
159 PathBuf::from("/home/user/configs/nvim/lua/setup.lua"),
160 weakly_canonical_cwd("configs/nvim/lua/setup.lua", cwd)
161 );
162 }
163
164 #[test]
165 fn test_path_ends_with_slash() {
166 assert!(!path_ends_with_slash(""));
167 assert!(!path_ends_with_slash("/f1"));
168 assert!(!path_ends_with_slash("/f1/f2"));
169 assert!(!path_ends_with_slash("./f1/f2"));
170 assert!(!path_ends_with_slash("./f1/f2/../f3"));
171
172 assert!(path_ends_with_slash("/"));
173 assert!(path_ends_with_slash("/f1/"));
174 assert!(path_ends_with_slash("f1/"));
175 assert!(path_ends_with_slash("f1/f2/"));
176 assert!(path_ends_with_slash("f1/f2/../f3/"));
177 }
178}