aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTeddy Wing2020-08-01 19:55:55 +0200
committerTeddy Wing2020-08-01 19:55:55 +0200
commit58b81567354cf6c0bd3623e86deb7b6609b1f3be (patch)
tree72727284795a09add11df05afe11827cb641e64a /src
parent0addf6814485c98c5a9569633f6c4ca4e71038ed (diff)
downloadgit-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.rs9
-rw-r--r--src/config.rs77
-rw-r--r--src/lib.rs2
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)
+}
diff --git a/src/lib.rs b/src/lib.rs
index a08be2b..494c389 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,3 +1,5 @@
#![warn(rust_2018_idioms)]
+pub mod config;
+
pub(crate) mod owner_repo;