1use std::path::Path;
6use std::process::Command;
7
8use crate::error::TldrError;
9use crate::TldrResult;
10
11pub fn is_git_repository(path: &Path) -> bool {
13 Command::new("git")
14 .arg("rev-parse")
15 .arg("--git-dir")
16 .current_dir(path)
17 .output()
18 .map(|o| o.status.success())
19 .unwrap_or(false)
20}
21
22pub fn is_shallow_clone(path: &Path) -> bool {
24 Command::new("git")
25 .arg("rev-parse")
26 .arg("--is-shallow-repository")
27 .current_dir(path)
28 .output()
29 .map(|o| {
30 o.status.success()
31 && String::from_utf8_lossy(&o.stdout).trim() == "true"
32 })
33 .unwrap_or(false)
34}
35
36pub fn git_log(
38 path: &Path,
39 since_days: u32,
40 format: &str,
41 extra_args: &[&str],
42) -> TldrResult<String> {
43 let since = format!("--since={} days ago", since_days);
44 let format_arg = format!("--pretty=format:{}", format);
45
46 let mut cmd = Command::new("git");
47 cmd.arg("log")
48 .arg(&since)
49 .arg(&format_arg)
50 .current_dir(path);
51
52 for arg in extra_args {
53 cmd.arg(arg);
54 }
55
56 let output = cmd.output().map_err(|e| {
57 TldrError::GitError(format!("Failed to run git log: {}", e))
58 })?;
59
60 if !output.status.success() {
61 let stderr = String::from_utf8_lossy(&output.stderr);
62 return Err(TldrError::GitError(format!(
63 "git log failed: {}",
64 stderr
65 )));
66 }
67
68 Ok(String::from_utf8_lossy(&output.stdout).to_string())
69}
70
71pub fn git_log_numstat(path: &Path, since_days: u32) -> TldrResult<String> {
73 let since = format!("--since={} days ago", since_days);
74
75 let output = Command::new("git")
76 .arg("log")
77 .arg(&since)
78 .arg("--numstat")
79 .arg("--format=")
80 .current_dir(path)
81 .output()
82 .map_err(|e| {
83 TldrError::GitError(format!("Failed to run git log: {}", e))
84 })?;
85
86 if !output.status.success() {
87 let stderr = String::from_utf8_lossy(&output.stderr);
88 return Err(TldrError::GitError(format!(
89 "git log --numstat failed: {}",
90 stderr
91 )));
92 }
93
94 Ok(String::from_utf8_lossy(&output.stdout).to_string())
95}