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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
use std::{
collections::VecDeque,
path::{Path, PathBuf},
};
use crate::prelude::*;
const DEFAULT_DEPOT_NAME: &str = "depot.toml";
pub fn home_directory() -> anyhow::Result<PathBuf> {
match std::env::var("HOME") {
Ok(val) => Ok(PathBuf::from(val)),
Err(e) => {
log::error!("Failed to get home directory from enviornment variable");
Err(e.into())
}
}
}
pub fn find_archive_path() -> anyhow::Result<PathBuf> {
let cwd = std::env::current_dir()?;
let compn = cwd.components().count();
let mut start = PathBuf::new();
for _ in 0..=compn {
start.push(DEFAULT_DEPOT_NAME);
if dotup::archive_exists(&start) {
return Ok(start);
}
start.pop();
start.push("..");
}
Ok(PathBuf::from(DEFAULT_DEPOT_NAME))
}
pub fn write_archive(path: impl AsRef<Path>, archive: &Archive) -> anyhow::Result<()> {
let path = path.as_ref();
log::debug!("Writing archive to {}", path.display());
match dotup::archive_write(path, archive) {
Ok(_) => Ok(()),
Err(e) => {
log::error!(
"Failed to write archive to : {}\nError : {}",
path.display(),
e
);
Err(e.into())
}
}
}
pub fn write_depot(depot: &Depot) -> anyhow::Result<()> {
let write_path = depot.archive_path();
let archive = depot.archive();
match dotup::archive_write(write_path, &archive) {
Ok(_) => Ok(()),
Err(e) => {
log::error!(
"Failed to write depot archive to : {}\nError : {}",
write_path.display(),
e
);
Err(e.into())
}
}
}
pub fn read_archive(path: impl AsRef<Path>) -> anyhow::Result<Archive> {
let path = path.as_ref();
match dotup::archive_read(path) {
Ok(archive) => Ok(archive),
Err(e) => {
log::error!(
"Failed to read archive from : {}\nError : {}",
path.display(),
e
);
Err(e.into())
}
}
}
pub fn read_depot(archive_path: impl AsRef<Path>) -> anyhow::Result<Depot> {
let archive_path = archive_path.as_ref().to_path_buf();
let archive = read_archive(&archive_path)?;
let depot_config = DepotConfig {
archive: Default::default(),
archive_path,
};
let mut depot = Depot::new(depot_config)?;
for archive_link in archive.links {
let link_params = LinkCreateParams::from(archive_link);
if let Err(e) = depot.create_link(link_params) {
log::warn!("Error while adding link : {}", e);
}
}
Ok(depot)
}
pub fn collect_links_by_base_paths(
depot: &Depot,
paths: impl IntoIterator<Item = impl AsRef<Path>>,
) -> Vec<&Link> {
let canonical_paths: Vec<_> = paths
.into_iter()
.map(|p| p.as_ref().canonicalize().unwrap())
.collect();
depot
.links()
.filter(|&l| {
canonical_paths
.iter()
.any(|p| l.origin_canonical().starts_with(p))
})
.collect()
}
pub fn collect_link_ids_by_base_paths(
depot: &Depot,
paths: impl IntoIterator<Item = impl AsRef<Path>>,
) -> Vec<LinkID> {
collect_links_by_base_paths(depot, paths)
.into_iter()
.map(|l| l.id())
.collect()
}
/// Returns a list of canonical paths to all the files in `dir`. This includes files in
/// subdirectories.
/// Fails if dir isnt a directory or if there is some other io error.
pub fn collect_files_in_dir(dir: impl Into<PathBuf>) -> anyhow::Result<Vec<PathBuf>> {
let mut paths = Vec::new();
let mut dirs = VecDeque::new();
dirs.push_back(dir.into());
while let Some(dir) = dirs.pop_front() {
for entry in std::fs::read_dir(dir)? {
let entry = entry?;
let filetype = entry.file_type()?;
if filetype.is_dir() {
dirs.push_back(entry.path());
} else {
paths.push(entry.path());
}
}
}
Ok(paths)
}
/// Collects the result of std::fs::read_dir into two vecs
/// The first one contains all the directories and the second one all the files
pub fn collect_read_dir_split(
dir: impl AsRef<Path>,
) -> anyhow::Result<(Vec<PathBuf>, Vec<PathBuf>)> {
Ok(std::fs::read_dir(dir)?
.filter_map(|e| e.ok())
.map(|e| e.path())
.partition(|p| p.is_dir()))
}
|