cod_git_info/
repo_owner.rs

1use std::path::PathBuf;
2
3use anyhow::Context;
4
5#[derive(Debug, Clone)]
6pub struct RepoAndOwner {
7    pub repo: String,
8    pub owner: String,
9}
10
11pub fn get_repo_owner() -> anyhow::Result<RepoAndOwner> {
12    std::process::Command::new("git")
13        .arg("remote")
14        .arg("-v")
15        .output()
16        .context("Couldn't detect git repository")
17        .map(|output| String::from_utf8_lossy(output.stdout.as_slice()).to_string())
18        .and_then(|output| {
19            output
20                .lines()
21                .next()
22                .and_then(|repo| repo.split_whitespace().nth(1).map(|repo| repo.to_owned()))
23                .context("Couldn't detect git repository")
24        })
25        .map(PathBuf::from)
26        .and_then(|mut git_path| {
27            let repo = git_path
28                .file_name()
29                .map(|name| name.to_owned())
30                .context("Couldn't find repo name in git path")?;
31            git_path.pop();
32            let owner = git_path
33                .file_name()
34                .map(|name| name.to_owned())
35                .context("Couldn't find repo owner in git path")?;
36            Ok((repo, owner))
37        })
38        .and_then(|(repo, owner)| {
39            let repo = repo
40                .to_str()
41                .map(|repo_name| repo_name.trim().to_owned())
42                .context("Couldn't convert repo name into string")?;
43            // owner needs additional cleanup since original url can be something like
44            // git@codeberg.org:UserName/RepoName
45            let owner = owner
46                .to_str()
47                .map(|repo_name| {
48                    repo_name
49                        .chars()
50                        .rev()
51                        .take_while(char::is_ascii_alphanumeric)
52                        .collect::<String>()
53                        .chars()
54                        .rev()
55                        .collect::<String>()
56                })
57                .context("Couldn't convert repo name into string")?;
58            Ok(RepoAndOwner { repo, owner })
59        })
60}
61
62#[test]
63fn cod_repo_name() -> anyhow::Result<()> {
64    let repo_and_owner = get_repo_owner()?;
65    assert_eq!(repo_and_owner.repo.as_str(), "codeberg-cli");
66    assert_eq!(repo_and_owner.owner.as_str(), "RobWalt");
67    Ok(())
68}