git.rs
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
use crate::errors::{ Result, Error };
use std::fs;
use std::path::{ PathBuf };
pub struct GitRoot {
path: PathBuf,
}
impl GitRoot {
pub fn open(path: &std::path::Path) -> Result<GitRoot> {
match fs::read_dir(path) {
Ok(_) => Ok(GitRoot { path: path.to_path_buf() }),
Err(e) => Err(Error::InvalidGitRoot(e)),
}
}
pub fn repositories(&self) -> Result<Vec<Repository>> {
let mut repositories = Vec::new();
for entry in fs::read_dir(&self.path)? {
let repo_path = entry?.path();
if !repo_path.is_dir() {
tracing::debug!("{} is not a directory", repo_path.display());
continue;
}
if repo_path.extension() != Some(std::ffi::OsStr::new("git")) {
tracing::debug!("{} is not a git repository", repo_path.display());
continue;
}
let Some(repo_name) = repo_path.file_stem() else {
tracing::debug!("{} doesn't have a file stem", repo_path.display());
continue;
};
let Some(repo_name) = repo_name.to_str() else {
tracing::debug!("{} isn't valid UTF-8", repo_path.display());
continue;
};
tracing::debug!("Found git repository {} at {}", repo_name, repo_path.display());
let repository = Repository::new(repo_name.to_string(), repo_path);
repositories.push(repository);
}
Ok(repositories)
}
}
pub struct Repository {
name: String,
path: PathBuf,
}
impl Repository {
pub fn new(name: String, path: PathBuf) -> Repository {
Repository {
name,
path,
}
}
pub fn name(&self) -> String {
self.name.clone()
}
pub fn path(&self) -> PathBuf {
self.path.clone()
}
}