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 /src | |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/bin/git-sugpatch.rs | 9 | ||||
-rw-r--r-- | src/config.rs | 77 | ||||
-rw-r--r-- | src/lib.rs | 2 |
3 files changed, 85 insertions, 3 deletions
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; |