github_local_remote/
lib.rs

1#![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/// Remote represenation.
21#[derive(Debug, Clone)]
22pub struct Remote {
23  url: String,
24  user: String,
25  repo: String,
26}
27
28impl Remote {
29  /// Get the url.
30  pub fn url(&self) -> &str {
31    &self.url
32  }
33
34  /// Get the user.
35  pub fn user(&self) -> &str {
36    &self.user
37  }
38
39  /// Get the repo.
40  pub fn repo(&self) -> &str {
41    &self.repo
42  }
43}
44
45/// Find out what the GitHub url, user and repo are for a directory
46pub 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}