1use std::{path::PathBuf, process::Command};
2
3use anyhow::{Result, bail};
4
5pub fn git_root() -> Result<PathBuf> {
6 let output = Command::new("git").args(["rev-parse", "--show-toplevel"]).output()?;
7
8 if !output.status.success() {
9 bail!("Failed to get Git repository root path");
10 }
11
12 let git_root = String::from_utf8_lossy(&output.stdout).trim_end_matches('\n').to_string();
13
14 Ok(PathBuf::from(git_root))
15}
16
17#[cfg(test)]
18mod test {
19 use std::env;
20
21 use anyhow::{Result, anyhow};
22
23 use crate::git_root;
24
25 #[test]
26 fn test() -> Result<()> {
27 assert_eq!("sercli", git_root()?.iter().last().unwrap());
28
29 let original_dir = env::current_dir()?;
30 let home_dir = home::home_dir().ok_or(anyhow!("No HOME"))?;
31
32 env::set_current_dir(&home_dir)?;
33
34 let result = git_root();
35
36 env::set_current_dir(original_dir)?;
37
38 assert_eq!(
39 anyhow!("Failed to get Git repository root path").to_string(),
40 result.err().unwrap().to_string()
41 );
42
43 Ok(())
44 }
45}