From 58b81567354cf6c0bd3623e86deb7b6609b1f3be Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Sat, 1 Aug 2020 19:55:55 +0200 Subject: 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. --- src/config.rs | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 src/config.rs (limited to 'src/config.rs') 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 { + pub fn get(args: &[String]) -> Result { + 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) +} -- cgit v1.2.3