aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeddy Wing2020-08-01 21:21:53 +0200
committerTeddy Wing2020-08-01 21:21:53 +0200
commite0f75bb732e2f1c66a9121142399bcd1d604a4f3 (patch)
treec891e4a47b1d4e766de396e3337c5bd682aa0422
parentd64951ef8fc55733d6b87a0ea6f1a16186eba3d2 (diff)
downloadgit-suggestion-e0f75bb732e2f1c66a9121142399bcd1d604a4f3.tar.bz2
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.
-rw-r--r--src/owner_repo.rs28
1 files changed, 27 insertions, 1 deletions
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<Self, Self::Err> {
- 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::<Vec<_>>();
@@ -74,4 +79,25 @@ impl OwnerRepo {
Ok(url.parse()?)
}
+
+ pub fn from_ssh(ssh: &str) -> Result<Self, OwnerRepoError> {
+ 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(),
+ })
+ }
}