github_local_remote/
lib.rs1#![cfg_attr(feature = "nightly", deny(missing_docs))]
2#![cfg_attr(feature = "nightly", feature(external_doc))]
3#![cfg_attr(feature = "nightly", doc(include = "../README.md"))]
4#![cfg_attr(test, deny(warnings))]
5#![forbid(unsafe_code, missing_debug_implementations)]
6
7#[macro_use]
8extern crate failure;
9extern crate git2;
10
11mod error;
12
13pub use error::{Error, ErrorKind, Result};
14
15use failure::ResultExt;
16use git2::Repository;
17use std::convert::AsRef;
18use std::path::Path;
19
20#[derive(Debug, Clone)]
22pub struct Remote {
23 url: String,
24 user: String,
25 repo: String,
26}
27
28impl Remote {
29 pub fn url(&self) -> &str {
31 &self.url
32 }
33
34 pub fn user(&self) -> &str {
36 &self.user
37 }
38
39 pub fn repo(&self) -> &str {
41 &self.repo
42 }
43}
44
45pub fn stat(path: impl AsRef<Path>) -> ::Result<Remote> {
47 let path = path.as_ref();
48 let repo = Repository::open(path).context(::ErrorKind::Git)?;
49 let remote = repo
50 .find_remote("origin")
51 .context(::ErrorKind::GitRemoteOrigin)?;
52 let url = remote.url().ok_or(::ErrorKind::GitRemoteUrl)?;
53
54 let parts: Vec<&str> = url.split(":").collect();
55 let repo_username = parts.get(1).ok_or(::ErrorKind::GitHubUrl)?;
56 let repo_username = repo_username.replace(".git", "");
57
58 let parts: Vec<&str> = repo_username.split("/").collect();
59 let user = parts.get(0).ok_or(::ErrorKind::GitHubUrl)?;
60 let repo = parts.get(1).ok_or(::ErrorKind::GitHubUrl)?;
61
62 Ok(Remote {
63 url: format!("https://github.com/{}", repo_username),
64 repo: repo.to_string(),
65 user: user.to_string(),
66 })
67}