diff options
author | Teddy Wing | 2020-08-01 19:55:55 +0200 |
---|---|---|
committer | Teddy Wing | 2020-08-01 19:55:55 +0200 |
commit | 58b81567354cf6c0bd3623e86deb7b6609b1f3be (patch) | |
tree | 72727284795a09add11df05afe11827cb641e64a | |
parent | 0addf6814485c98c5a9569633f6c4ca4e71038ed (diff) | |
download | git-suggestion-58b81567354cf6c0bd3623e86deb7b6609b1f3be.tar.bz2 |
Get config
We need the following values in order to build a `Client`:
* GitHub token
* Repo owner
* Repo name
Get the token from a command-line argument, or else the Git config, or
else an environment variable.
Get the repo identifiers from the repo's remote URL. Use the remote
specified as a command-line argument, otherwise get it from the Git
config, or else default to "origin".
TODO: Only try to get the owner-name pair from the remote if a comment
ID was given, not if a URL argument was passed.
-rw-r--r-- | Cargo.lock | 16 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/bin/git-sugpatch.rs | 9 | ||||
-rw-r--r-- | src/config.rs | 77 | ||||
-rw-r--r-- | src/lib.rs | 2 |
5 files changed, 102 insertions, 3 deletions
@@ -212,6 +212,15 @@ dependencies = [ ] [[package]] +name = "getopts" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" +dependencies = [ + "unicode-width", +] + +[[package]] name = "getrandom" version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -276,6 +285,7 @@ dependencies = [ name = "github-suggestion-cli" version = "0.0.1" dependencies = [ + "getopts", "git2", "github-suggestion", "thiserror", @@ -1245,6 +1255,12 @@ dependencies = [ ] [[package]] +name = "unicode-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" + +[[package]] name = "unicode-xid" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4,6 +4,7 @@ version = "0.0.1" edition = "2018" [dependencies] +getopts = "0.2.21" git2 = "0.13.8" thiserror = "1.0.20" url = "2.1.1" diff --git a/src/bin/git-sugpatch.rs b/src/bin/git-sugpatch.rs index 0ad8874..2a9b348 100644 --- a/src/bin/git-sugpatch.rs +++ b/src/bin/git-sugpatch.rs @@ -2,11 +2,14 @@ use std::env; use std::process; use github_suggestion::{Client, SuggestionUrl}; +use github_suggestion_cli::config::Config; fn main() { let args: Vec<_> = env::args().collect(); + let config = Config::get(&args).unwrap(); + if args.len() < 2 { process::exit(111); } @@ -14,9 +17,9 @@ fn main() { let url: SuggestionUrl = args[1].parse().unwrap(); let client = Client::new( - env!("GITHUB_TOKEN"), - &url.owner, - &url.repo, + &config.github_token, + &config.owner, + &config.repo, ).unwrap(); let suggestion = client.fetch(&url.comment_id).unwrap(); diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..321ea50 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,77 @@ +use std::env; + +use getopts::Options; +use git2::Repository; +use thiserror::Error; + +use crate::owner_repo::{self, OwnerRepo}; + + +const GIT_CONFIG_PREFIX: &'static str = "githubSuggestion."; + +#[derive(Debug, Error)] +pub enum Error { + #[error("Unable to parse arguments")] + Opts(#[from] getopts::Fail), + + #[error("Error getting environment variable")] + EnvVar(#[from] env::VarError), + + #[error(transparent)] + OwnerRepo(#[from] owner_repo::Error), + + #[error(transparent)] + Git(#[from] git2::Error), +} + +#[derive(Debug)] +pub struct Config { + pub github_token: String, + pub owner: String, + pub repo: String, +} + +impl Config { + // fn from_args(args: &env::Args) -> Result<Self, Error> { + pub fn get(args: &[String]) -> Result<Self, Error> { + let mut opts = Options::new(); + + opts.optopt("", "github-token", "", "TOKEN"); + opts.optopt("", "remote", "", "REMOTE"); + + let opt_matches = opts.parse(&args[1..])?; + + let git_config = Repository::open(".")?.config()?; + + let github_token = match opt_matches.opt_str("github-token") { + Some(t) => Ok(t), + None => + match git_config.get_string(&git_config_key("githubToken")) { + Err(e) if e.code() == git2::ErrorCode::NotFound => + env::var("GITHUB_TOKEN") + .map_err(|e| Error::EnvVar(e)), + r => r.map_err(|e| Error::Git(e)), + }, + }?; + + let remote = match opt_matches.opt_str("remote") { + Some(r) => Ok(Some(r)), + None => match git_config.get_string(&git_config_key("remote")) { + Err(e) if e.code() == git2::ErrorCode::NotFound => Ok(None), + r => r.map(|r| Some(r)), + }, + }?; + + let o_r = OwnerRepo::from_remote(remote.as_deref())?; + + Ok(Config { + github_token, + owner: o_r.owner, + repo: o_r.repo, + }) + } +} + +fn git_config_key(key: &str) -> String { + format!("{}.{}", GIT_CONFIG_PREFIX, key) +} @@ -1,3 +1,5 @@ #![warn(rust_2018_idioms)] +pub mod config; + pub(crate) mod owner_repo; |