git_insights/
git.rs

1use std::process::{Command, Stdio};
2
3/// Executes a Git command and returns its stdout if successful.
4pub 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
18/// Checks if the `git` command is available in the system's PATH.
19pub 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
28/// Counts the number of merged pull requests for a given author.
29pub 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", // %s gets the subject of the commit
36    ])?;
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
50/// Checks if the current directory is within a Git repository.
51pub 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        // This test assumes git is installed on the system running the tests
68        assert!(is_git_installed());
69    }
70
71    #[test]
72    fn test_is_in_git_repo() {
73        // This test will pass because the project is a git repository
74        assert!(is_in_git_repo());
75    }
76
77    #[test]
78    fn test_run_command_success() {
79        // Test a command that should succeed
80        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        // Test a command that should fail
88        let result = run_command(&["invalid-command"]);
89        assert!(result.is_err());
90    }
91}