diff options
| author | Teddy Wing | 2020-08-01 01:38:07 +0200 | 
|---|---|---|
| committer | Teddy Wing | 2020-08-01 01:38:07 +0200 | 
| commit | eb74fee6be6876b86c97cdea0205ec970152358e (patch) | |
| tree | 0c0f84de46684e0baf5a39b69cccf9f71ff6f4d0 | |
| parent | 25ce03b6102cf017cf9cbba7e28dbd0d76ab5a5d (diff) | |
| download | git-suggestion-eb74fee6be6876b86c97cdea0205ec970152358e.tar.bz2 | |
Add a function to get an owner-repo pair from the Git repo remote
This will allow us to accept suggestion IDs alone, without a full URL,
like the following:
    $ git sugapply 459691747
    # or
    $ git sugapply --remote upstream 459691747
    # or
    $ git config github-suggestion.remote upstream
    $ git sugapply 459691747
We do this by extracting the pair from the remote URL.
| -rw-r--r-- | Cargo.lock | 10 | ||||
| -rw-r--r-- | Cargo.toml | 8 | ||||
| -rw-r--r-- | github-suggestion-config/Cargo.toml | 9 | ||||
| -rw-r--r-- | github-suggestion-config/src/lib.rs | 75 | 
4 files changed, 102 insertions, 0 deletions
| @@ -264,6 +264,7 @@ version = "0.0.1"  dependencies = [   "git2",   "github-rs", + "github-suggestion-config",   "regex",   "serde",   "serde_json", @@ -273,6 +274,15 @@ dependencies = [  ]  [[package]] +name = "github-suggestion-config" +version = "0.0.1" +dependencies = [ + "git2", + "thiserror", + "url", +] + +[[package]]  name = "h2"  version = "0.1.26"  source = "registry+https://github.com/rust-lang/crates.io-index" @@ -12,3 +12,11 @@ serde_json = "1.0.56"  tempfile = "3.1.0"  thiserror = "1.0.20"  url = "2.1.1" + +github-suggestion-config = { path = "github-suggestion-config" } + + +[workspace] +members = [ +	"github-suggestion-config", +] diff --git a/github-suggestion-config/Cargo.toml b/github-suggestion-config/Cargo.toml new file mode 100644 index 0000000..788d00d --- /dev/null +++ b/github-suggestion-config/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "github-suggestion-config" +version = "0.0.1" +edition = "2018" + +[dependencies] +git2 = "0.13.8" +thiserror = "1.0.20" +url = "2.1.1" diff --git a/github-suggestion-config/src/lib.rs b/github-suggestion-config/src/lib.rs new file mode 100644 index 0000000..c0d97a2 --- /dev/null +++ b/github-suggestion-config/src/lib.rs @@ -0,0 +1,75 @@ +use std::str::FromStr; + +use git2::Repository; +use thiserror::Error; +use url; +use url::Url; + + +#[derive(Debug, Error)] +pub enum Error { +    #[error(transparent)] +    Git(#[from] git2::Error), + +    #[error(transparent)] +    OwnerRepo(#[from] OwnerRepoError), + +    #[error("Unable to find remote '{0}'")] +    NoRemote(String), +} + +#[derive(Debug, Error)] +pub enum OwnerRepoError { +    #[error("Unable to parse URL")] +    Url(#[from] url::ParseError), + +    #[error("URL has no path")] +    NoPath, + +    #[error("Unable to parse owner or repo")] +    NoOwnerRepo, +} + + +#[derive(Debug)] +pub struct OwnerRepo { +    pub owner: String, +    pub repo: String, +} + +impl FromStr for OwnerRepo { +    type Err = OwnerRepoError; + +    fn from_str(s: &str) -> Result<Self, Self::Err> { +        let url = Url::parse(s)?; +        let path = url.path_segments() +            .ok_or(OwnerRepoError::NoPath)? +            .collect::<Vec<_>>(); + +        if path.len() < 2 { +            return Err(OwnerRepoError::NoOwnerRepo); +        } + +        Ok(OwnerRepo { +            owner: path[0].to_owned(), +            repo: path[1].to_owned(), +        }) +    } +} + +pub fn identifier_for_remote( +    remote_name: Option<&str>, +) -> Result<OwnerRepo, Error> { +    let repo = Repository::open(".")?; + +    let remote_name = match remote_name { +        Some(r) => r, +        None => "origin", +    }; + +    let remote = repo.find_remote(remote_name)?; +    let url = remote.url() +        .ok_or_else(|| Error::NoRemote(remote_name.to_owned()))?; + +    Ok(url.parse()?) +} | 
