diff options
-rw-r--r-- | src/git_config/git_config_entry.rs | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/src/git_config/git_config_entry.rs b/src/git_config/git_config_entry.rs index 4b0d80a3..2dcb8783 100644 --- a/src/git_config/git_config_entry.rs +++ b/src/git_config/git_config_entry.rs @@ -14,13 +14,26 @@ pub enum GitConfigEntry { Path(PathBuf), } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, PartialEq)] pub enum GitRemoteRepo { GitHubRepo(String), } lazy_static! { - static ref GITHUB_REMOTE_URL: Regex = Regex::new(r"github\.com[:/]([^/]+)/(.+)").unwrap(); + static ref GITHUB_REMOTE_URL: Regex = Regex::new( + r"(?x) + ^ + (?:https://|git@) # Support both HTTPS and SSH URLs + github\.com + [:/] # This separator differs between SSH and HTTPS URLs + ([^/]+) # Capture the user/org name + / + (.+?) # Capture the repo name (lazy to avoid consuming '.git' if present) + (?:\.git)? # Non-capturing group to consume '.git' if present + $ + " + ) + .unwrap(); } impl FromStr for GitRemoteRepo { @@ -37,3 +50,26 @@ impl FromStr for GitRemoteRepo { } } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_parse_github_urls() { + let urls = &[ + "https://github.com/dandavison/delta.git", + "https://github.com/dandavison/delta", + "git@github.com:dandavison/delta.git", + "git@github.com:dandavison/delta", + ]; + for url in urls { + let parsed = GitRemoteRepo::from_str(url); + assert!(parsed.is_ok()); + assert_eq!( + parsed.unwrap(), + GitRemoteRepo::GitHubRepo("dandavison/delta".to_string()) + ); + } + } +} |