From e0f75bb732e2f1c66a9121142399bcd1d604a4f3 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Sat, 1 Aug 2020 21:21:53 +0200 Subject: OwnerRepo: Parse from SSH-style paths Remotes can be HTTP URLs or use SSH/SCP-style paths like: git@github.com/teddywing/github-suggestion.git We need to handle both regular URLs and the above style, which isn't parseable by the 'url' crate. Add a custom parsing function to get the owner and repo from this format. When trying to parse `OwnerRepo` from a string, first try to parse it as a URL. If that fails with a `RelativeUrlWithoutBase` error, assume it's the other style of reference. --- src/owner_repo.rs | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/owner_repo.rs b/src/owner_repo.rs index 67572ef..a94c67f 100644 --- a/src/owner_repo.rs +++ b/src/owner_repo.rs @@ -41,7 +41,12 @@ impl FromStr for OwnerRepo { type Err = OwnerRepoError; fn from_str(s: &str) -> Result { - let url = Url::parse(s)?; + let url = match Url::parse(s) { + Err(url::ParseError::RelativeUrlWithoutBase) => + return OwnerRepo::from_ssh(s), + + r => r, + }?; let path = url.path_segments() .ok_or(OwnerRepoError::NoPath)? .collect::>(); @@ -74,4 +79,25 @@ impl OwnerRepo { Ok(url.parse()?) } + + pub fn from_ssh(ssh: &str) -> Result { + let address_path: Vec<_> = ssh.splitn(2, ':').collect(); + let path = address_path.get(1) + .ok_or(OwnerRepoError::NoOwnerRepo)?; + + let path = path + .strip_suffix(".git") + .unwrap_or(path); + + let segments: Vec<_> = path.split('/').collect(); + + if segments.len() < 2 { + return Err(OwnerRepoError::NoOwnerRepo); + } + + Ok(OwnerRepo { + owner: segments[0].to_owned(), + repo: segments[1].to_owned(), + }) + } } -- cgit v1.2.3