Add git forge integration
This commit is contained in:
128
src/config.rs
128
src/config.rs
@@ -1,19 +1,61 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::process;
|
||||
|
||||
use crate::output::*;
|
||||
|
||||
use super::repo::RepoConfig;
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use crate::get_token_from_command;
|
||||
use crate::provider;
|
||||
use crate::provider::Filter;
|
||||
use crate::provider::Provider;
|
||||
|
||||
pub type RemoteProvider = crate::provider::RemoteProvider;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum Config {
|
||||
ConfigTree(ConfigTree),
|
||||
ConfigProvider(ConfigProvider),
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Config {
|
||||
pub struct ConfigTree {
|
||||
pub trees: Trees,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct ConfigProviderFilter {
|
||||
pub access: Option<bool>,
|
||||
pub owner: Option<bool>,
|
||||
pub users: Option<Vec<String>>,
|
||||
pub groups: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct ConfigProvider {
|
||||
pub provider: RemoteProvider,
|
||||
pub token_command: String,
|
||||
pub root: String,
|
||||
pub filters: Option<ConfigProviderFilter>,
|
||||
|
||||
pub force_ssh: Option<bool>,
|
||||
|
||||
pub api_url: Option<String>,
|
||||
|
||||
pub worktree: Option<bool>,
|
||||
pub init_worktree: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Trees(Vec<Tree>);
|
||||
|
||||
impl Trees {
|
||||
pub fn to_config(self) -> Config {
|
||||
Config { trees: self }
|
||||
Config::ConfigTree(ConfigTree { trees: self })
|
||||
}
|
||||
|
||||
pub fn from_vec(vec: Vec<Tree>) -> Self {
|
||||
@@ -30,6 +72,81 @@ impl Trees {
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn trees(self) -> Result<Trees, String> {
|
||||
match self {
|
||||
Config::ConfigTree(config) => Ok(config.trees),
|
||||
Config::ConfigProvider(config) => {
|
||||
let token = match get_token_from_command(&config.token_command) {
|
||||
Ok(token) => token,
|
||||
Err(error) => {
|
||||
print_error(&format!("Getting token from command failed: {}", error));
|
||||
process::exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
let filters = config.filters.unwrap_or(ConfigProviderFilter {
|
||||
access: Some(false),
|
||||
owner: Some(false),
|
||||
users: Some(vec![]),
|
||||
groups: Some(vec![]),
|
||||
});
|
||||
|
||||
let filter = Filter::new(
|
||||
filters.users.unwrap_or_default(),
|
||||
filters.groups.unwrap_or_default(),
|
||||
filters.owner.unwrap_or(false),
|
||||
filters.access.unwrap_or(false),
|
||||
);
|
||||
|
||||
let repos = match config.provider {
|
||||
RemoteProvider::Github => {
|
||||
match provider::Github::new(filter, token, config.api_url) {
|
||||
Ok(provider) => provider,
|
||||
Err(error) => {
|
||||
print_error(&format!("Error: {}", error));
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
.get_repos(
|
||||
config.worktree.unwrap_or(false),
|
||||
config.force_ssh.unwrap_or(false),
|
||||
)?
|
||||
}
|
||||
RemoteProvider::Gitlab => {
|
||||
match provider::Gitlab::new(filter, token, config.api_url) {
|
||||
Ok(provider) => provider,
|
||||
Err(error) => {
|
||||
print_error(&format!("Error: {}", error));
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
.get_repos(
|
||||
config.worktree.unwrap_or(false),
|
||||
config.force_ssh.unwrap_or(false),
|
||||
)?
|
||||
}
|
||||
};
|
||||
|
||||
let mut trees = vec![];
|
||||
|
||||
for (namespace, namespace_repos) in repos {
|
||||
let tree = Tree {
|
||||
root: crate::path_as_string(&Path::new(&config.root).join(namespace)),
|
||||
repos: Some(namespace_repos),
|
||||
};
|
||||
trees.push(tree);
|
||||
}
|
||||
Ok(Trees(trees))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_trees(trees: Vec<Tree>) -> Self {
|
||||
Config::ConfigTree(ConfigTree {
|
||||
trees: Trees::from_vec(trees),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn as_toml(&self) -> Result<String, String> {
|
||||
match toml::to_string(self) {
|
||||
Ok(toml) => Ok(toml),
|
||||
@@ -49,7 +166,10 @@ pub struct Tree {
|
||||
pub repos: Option<Vec<RepoConfig>>,
|
||||
}
|
||||
|
||||
pub fn read_config(path: &str) -> Result<Config, String> {
|
||||
pub fn read_config<'a, T>(path: &str) -> Result<T, String>
|
||||
where
|
||||
T: for<'de> serde::Deserialize<'de>,
|
||||
{
|
||||
let content = match std::fs::read_to_string(&path) {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
@@ -64,7 +184,7 @@ pub fn read_config(path: &str) -> Result<Config, String> {
|
||||
}
|
||||
};
|
||||
|
||||
let config: Config = match toml::from_str(&content) {
|
||||
let config: T = match toml::from_str(&content) {
|
||||
Ok(c) => c,
|
||||
Err(_) => match serde_yaml::from_str(&content) {
|
||||
Ok(c) => c,
|
||||
|
||||
Reference in New Issue
Block a user