1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use anyhow::Context;
use keyring::Keyring;
use std::{env, fmt::Debug};
#[cfg(test)]
use std::sync::Once;
mod client;
mod git;
mod pulls;
mod repositories;
mod teams;
mod users;
pub use client::*;
pub use git::*;
pub use pulls::*;
pub use repositories::*;
pub use teams::*;
pub use users::*;
#[cfg(test)]
static LOG: Once = Once::new();
#[cfg(test)]
fn log() {
LOG.call_once(|| jacklog::init(Some(&"debug")).unwrap());
}
#[cfg(test)]
fn handle() -> String {
env::var("GITHUB_HANDLE").expect("error reading GITHUB_HANDLE")
}
#[cfg(test)]
fn org() -> String {
env::var("GITHUB_TEST_ORG").expect("error reading GITHUB_TEST_ORG")
}
#[cfg(test)]
fn repo() -> String {
env::var("GITHUB_TEST_REPO").expect("error reading GITHUB_TEST_REPO")
}
#[cfg(test)]
fn client() -> GithubClient {
GithubClient::new(&EnvironmentProvider::default()).unwrap()
}
#[derive(Debug)]
pub struct AuthToken(String);
#[derive(Debug, Default)]
pub struct EnvironmentProvider {
pub token_env_var: Option<String>,
token: String,
}
#[derive(Debug)]
pub struct KeychainProvider {
service: String,
name: String,
}
impl Default for KeychainProvider {
fn default() -> Self {
Self {
service: "buhtig".into(),
name: "github-token".into(),
}
}
}
impl KeychainProvider {
pub fn new<T: AsRef<str>>(service: Option<T>, name: Option<T>) -> Self {
Self {
service: match service {
Some(s) => s.as_ref().to_string(),
None => "buhtig".to_string(),
},
name: match name {
Some(n) => n.as_ref().to_string(),
None => "github-token".to_string(),
},
}
}
}
pub trait CredentialsProvider {
fn token(&self) -> String;
}
impl CredentialsProvider for AuthToken {
fn token(&self) -> String {
self.0.clone()
}
}
impl CredentialsProvider for EnvironmentProvider {
fn token(&self) -> String {
let var = self
.token_env_var
.clone()
.unwrap_or_else(|| "GITHUB_TOKEN".to_string());
env::var(&var).context(format!("{} not set", var)).unwrap()
}
}
impl CredentialsProvider for KeychainProvider {
fn token(&self) -> String {
Keyring::new(&self.service, &self.name)
.get_password()
.expect("missing github token in keyring")
}
}
#[derive(Debug)]
pub enum SortDirection {
Asc,
Desc,
}