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() } }