diff options
Diffstat (limited to 'src/git_config/git_config_entry.rs')
-rw-r--r-- | src/git_config/git_config_entry.rs | 97 |
1 files changed, 78 insertions, 19 deletions
diff --git a/src/git_config/git_config_entry.rs b/src/git_config/git_config_entry.rs index 66a9f840..56dcc1c2 100644 --- a/src/git_config/git_config_entry.rs +++ b/src/git_config/git_config_entry.rs @@ -14,18 +14,22 @@ pub enum GitConfigEntry { #[derive(Clone, Debug, PartialEq, Eq)] pub enum GitRemoteRepo { - GitHubRepo { repo_slug: String }, - GitLabRepo { repo_slug: String }, + GitHub { slug: String }, + GitLab { slug: String }, + SourceHut { slug: String }, } impl GitRemoteRepo { pub fn format_commit_url(&self, commit: &str) -> String { match self { - Self::GitHubRepo { repo_slug } => { - format!("https://github.com/{}/commit/{}", repo_slug, commit) + Self::GitHub { slug } => { + format!("https://github.com/{}/commit/{}", slug, commit) } - Self::GitLabRepo { repo_slug } => { - format!("https://gitlab.com/{}/-/commit/{}", repo_slug, commit) + Self::GitLab { slug } => { + format!("https://gitlab.com/{}/-/commit/{}", slug, commit) + } + Self::SourceHut { slug } => { + format!("https://git.sr.ht/{}/commit/{}", slug, commit) } } } @@ -61,30 +65,51 @@ lazy_static! { " ) .unwrap(); + static ref SOURCEHUT_REMOTE_URL: Regex = Regex::new( + r"(?x) + ^ + (?:https://|git@)? # Support both HTTPS and SSH URLs, SSH URLs optionally omitting the git@ + git\.sr\.ht + [:/] # This separator differs between SSH and HTTPS URLs + ~([^/]+) # Capture the username + / + (.+) # Capture the repo name + $ + " + ) + .unwrap(); } impl FromStr for GitRemoteRepo { type Err = Error; fn from_str(s: &str) -> Result<Self, Self::Err> { if let Some(caps) = GITHUB_REMOTE_URL.captures(s) { - Ok(Self::GitHubRepo { - repo_slug: format!( + Ok(Self::GitHub { + slug: format!( "{user}/{repo}", user = caps.get(1).unwrap().as_str(), repo = caps.get(2).unwrap().as_str() ), }) } else if let Some(caps) = GITLAB_REMOTE_URL.captures(s) { - Ok(Self::GitLabRepo { - repo_slug: format!( + Ok(Self::GitLab { + slug: format!( "{user}{groups}/{repo}", user = caps.get(1).unwrap().as_str(), groups = caps.get(2).map(|x| x.as_str()).unwrap_or_default(), repo = caps.get(3).unwrap().as_str() ), }) + } else if let Some(caps) = SOURCEHUT_REMOTE_URL.captures(s) { + Ok(Self::SourceHut { + slug: format!( + "~{user}/{repo}", + user = caps.get(1).unwrap().as_str(), + repo = caps.get(2).unwrap().as_str() + ), + }) } else { - Err("Not a GitHub or GitLab repo.".into()) + Err("Not a GitHub, GitLab or SourceHut repo.".into()) } } } @@ -108,8 +133,8 @@ mod tests { assert!(parsed.is_ok()); assert_eq!( parsed.unwrap(), - GitRemoteRepo::GitHubRepo { - repo_slug: "dandavison/delta".to_string() + GitRemoteRepo::GitHub { + slug: "dandavison/delta".to_string() } ); } @@ -117,8 +142,8 @@ mod tests { #[test] fn test_format_github_commit_link() { - let repo = GitRemoteRepo::GitHubRepo { - repo_slug: "dandavison/delta".to_string(), + let repo = GitRemoteRepo::GitHub { + slug: "dandavison/delta".to_string(), }; let commit_hash = "d3b07384d113edec49eaa6238ad5ff00"; assert_eq!( @@ -153,8 +178,8 @@ mod tests { assert!(parsed.is_ok()); assert_eq!( parsed.unwrap(), - GitRemoteRepo::GitLabRepo { - repo_slug: expected.to_string() + GitRemoteRepo::GitLab { + slug: expected.to_string() } ); } @@ -162,8 +187,8 @@ mod tests { #[test] fn test_format_gitlab_commit_link() { - let repo = GitRemoteRepo::GitLabRepo { - repo_slug: "proj/grp/repo".to_string(), + let repo = GitRemoteRepo::GitLab { + slug: "proj/grp/repo".to_string(), }; let commit_hash = "d3b07384d113edec49eaa6238ad5ff00"; assert_eq!( @@ -171,4 +196,38 @@ mod tests { format!("https://gitlab.com/proj/grp/repo/-/commit/{}", commit_hash) ) } + + #[test] + fn test_parse_sourcehut_urls() { + let urls = &[ + "https://git.sr.ht/~someuser/somerepo", + "git@git.sr.ht:~someuser/somerepo", + "git.sr.ht:~someuser/somerepo", + ]; + for url in urls { + let parsed = GitRemoteRepo::from_str(url); + assert!(parsed.is_ok()); + assert_eq!( + parsed.unwrap(), + GitRemoteRepo::SourceHut { + slug: "~someuser/somerepo".to_string() + } + ); + } + } + + #[test] + fn test_format_sourcehut_commit_link() { + let repo = GitRemoteRepo::SourceHut { + slug: "~someuser/somerepo".to_string(), + }; + let commit_hash = "df41ac86f08a40e64c76062fd67e238522c14990"; + assert_eq!( + repo.format_commit_url(commit_hash), + format!( + "https://git.sr.ht/~someuser/somerepo/commit/{}", + commit_hash + ) + ) + } } |