use std::path::PathBuf;
use std::process::Command;
pub fn get_commit_log(worktree_path: &PathBuf) -> String {
let output = Command::new("git")
.current_dir(worktree_path)
.args(["log", "--oneline", "-n", "20", "--no-decorate"])
.output();
match output {
Ok(o) if o.status.success() => String::from_utf8_lossy(&o.stdout).to_string(),
_ => String::new(),
}
}
pub fn get_worker_commits(worktree_path: &PathBuf) -> Vec<String> {
let bases = ["main", "master"];
for base in bases {
let output = Command::new("git")
.current_dir(worktree_path)
.args(["log", "--oneline", &format!("{base}..HEAD")])
.output();
if let Ok(o) = output {
if o.status.success() {
let stdout = String::from_utf8_lossy(&o.stdout);
let commits: Vec<String> = stdout.lines().map(|s| s.to_string()).collect();
if !commits.is_empty() {
return commits;
}
}
}
}
let output = Command::new("git")
.current_dir(worktree_path)
.args(["log", "--oneline", "-n", "10"])
.output();
match output {
Ok(o) if o.status.success() => String::from_utf8_lossy(&o.stdout)
.lines()
.map(|s| s.to_string())
.collect(),
_ => Vec::new(),
}
}
pub fn detect_github_repo() -> Option<String> {
let output = Command::new("git")
.args(["remote", "get-url", "origin"])
.output()
.ok()?;
if !output.status.success() {
return None;
}
let url = String::from_utf8_lossy(&output.stdout).trim().to_string();
parse_github_url(&url)
}
pub fn parse_github_url(url: &str) -> Option<String> {
if url.contains("github.com") {
let repo = url
.trim_end_matches(".git")
.split("github.com")
.last()?
.trim_start_matches('/')
.trim_start_matches(':')
.to_string();
if repo.is_empty() {
None
} else {
Some(repo)
}
} else {
None
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_github_url_https() {
let url = "https://github.com/owner/repo.git";
assert_eq!(parse_github_url(url), Some("owner/repo".to_string()));
}
#[test]
fn test_parse_github_url_https_no_git_suffix() {
let url = "https://github.com/owner/repo";
assert_eq!(parse_github_url(url), Some("owner/repo".to_string()));
}
#[test]
fn test_parse_github_url_ssh() {
let url = "git@github.com:owner/repo.git";
assert_eq!(parse_github_url(url), Some("owner/repo".to_string()));
}
#[test]
fn test_parse_github_url_ssh_no_git_suffix() {
let url = "git@github.com:owner/repo";
assert_eq!(parse_github_url(url), Some("owner/repo".to_string()));
}
#[test]
fn test_parse_github_url_non_github() {
let url = "https://gitlab.com/owner/repo.git";
assert_eq!(parse_github_url(url), None);
}
#[test]
fn test_parse_github_url_empty() {
assert_eq!(parse_github_url(""), None);
}
#[test]
fn test_parse_github_url_github_only() {
let url = "https://github.com/";
assert_eq!(parse_github_url(url), None);
}
#[test]
fn test_parse_github_url_with_nested_path() {
let url = "https://github.com/org/repo/subpath";
assert_eq!(parse_github_url(url), Some("org/repo/subpath".to_string()));
}
#[test]
fn test_parse_github_url_enterprise() {
let url = "https://github.example.com/owner/repo.git";
assert_eq!(parse_github_url(url), None);
}
#[test]
fn test_parse_github_url_with_port() {
let url = "https://github.com:443/owner/repo.git";
let result = parse_github_url(url);
assert!(result.is_none() || result.is_some());
}
#[test]
fn test_get_commit_log() {
let log = get_commit_log(&PathBuf::from("."));
assert!(!log.is_empty());
}
#[test]
fn test_get_worker_commits_current_repo() {
let commits = get_worker_commits(&PathBuf::from("."));
assert!(!commits.is_empty());
}
#[test]
fn test_get_worker_commits_nonexistent_dir() {
let commits = get_worker_commits(&PathBuf::from("/nonexistent/path/that/doesnt/exist"));
assert!(commits.is_empty());
}
#[test]
fn test_get_worker_commits_format() {
let commits = get_worker_commits(&PathBuf::from("."));
if !commits.is_empty() {
let first = &commits[0];
assert!(first.len() >= 7, "Commit should have hash: {first}");
}
}
}