1use std::process::{Command, Stdio};
2
3pub fn run_command(args: &[&str]) -> Result<String, String> {
5 let output = Command::new("git").args(args).output();
6 match output {
7 Ok(output) => {
8 if output.status.success() {
9 Ok(String::from_utf8_lossy(&output.stdout).trim().to_string())
10 } else {
11 Err(String::from_utf8_lossy(&output.stderr).to_string())
12 }
13 }
14 Err(e) => Err(format!("Failed to execute git command: {}", e)),
15 }
16}
17
18pub fn is_git_installed() -> bool {
20 Command::new("git")
21 .arg("--version")
22 .stdout(Stdio::null())
23 .stderr(Stdio::null())
24 .status()
25 .map_or(false, |s| s.success())
26}
27
28pub fn count_pull_requests(author: &str) -> Result<usize, String> {
30 let log_output = run_command(&[
31 "log",
32 "--merges",
33 "--author",
34 author,
35 "--pretty=format:%s", ])?;
37
38 let pr_merges = log_output
39 .lines()
40 .filter(|line| {
41 line.starts_with("Merge pull request #")
42 || line.starts_with("Merge branch '")
43 || line.starts_with("Merged in")
44 })
45 .count();
46
47 Ok(pr_merges)
48}
49
50pub fn is_in_git_repo() -> bool {
52 Command::new("git")
53 .arg("rev-parse")
54 .arg("--is-inside-work-tree")
55 .stdout(Stdio::null())
56 .stderr(Stdio::null())
57 .status()
58 .map_or(false, |s| s.success())
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64
65 #[test]
66 fn test_is_git_installed() {
67 assert!(is_git_installed());
69 }
70
71 #[test]
72 fn test_is_in_git_repo() {
73 assert!(is_in_git_repo());
75 }
76
77 #[test]
78 fn test_run_command_success() {
79 let result = run_command(&["--version"]);
81 assert!(result.is_ok());
82 assert!(result.unwrap().starts_with("git version"));
83 }
84
85 #[test]
86 fn test_run_command_failure() {
87 let result = run_command(&["invalid-command"]);
89 assert!(result.is_err());
90 }
91}