refactor, new functions
This commit is contained in:
parent
4611d251d5
commit
b2461d0cc8
|
@ -17,6 +17,15 @@ version = "1.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "1.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atomic-waker"
|
name = "atomic-waker"
|
||||||
version = "1.1.2"
|
version = "1.1.2"
|
||||||
|
@ -466,6 +475,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"confy",
|
"confy",
|
||||||
"git2",
|
"git2",
|
||||||
|
"regex",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
@ -736,6 +746,35 @@ dependencies = [
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex"
|
||||||
|
version = "1.10.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-automata",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.4.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "reqwest"
|
name = "reqwest"
|
||||||
version = "0.12.4"
|
version = "0.12.4"
|
||||||
|
|
11
Cargo.toml
11
Cargo.toml
|
@ -3,16 +3,15 @@ name = "klados"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
git2 = "0.18.3"
|
||||||
|
regex = "1.10.4"
|
||||||
|
serde_json = "1.0.117"
|
||||||
|
|
||||||
[dependencies.reqwest]
|
[dependencies.reqwest]
|
||||||
version = "0.12.4"
|
version = "0.12.4"
|
||||||
features = ["json", "blocking"]
|
features = ["json", "blocking"]
|
||||||
|
|
||||||
[dependencies.git2]
|
|
||||||
version = "0.18.3"
|
|
||||||
|
|
||||||
[dependencies.serde_json]
|
|
||||||
version = "1.0.117"
|
|
||||||
|
|
||||||
[dependencies.serde]
|
[dependencies.serde]
|
||||||
version = "1.0.203"
|
version = "1.0.203"
|
||||||
features = ["derive"]
|
features = ["derive"]
|
||||||
|
|
2
TODO.md
2
TODO.md
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
- [X] Define config schema
|
- [X] Define config schema
|
||||||
- [X] Parse config
|
- [X] Parse config
|
||||||
- [ ] Discover local repositories in $KLADOS_DIR
|
|
||||||
- [X] Discover remote repositories
|
- [X] Discover remote repositories
|
||||||
|
- [X] Discover local repositories
|
||||||
- [ ] Clone remote repositories
|
- [ ] Clone remote repositories
|
||||||
- [ ] List unclean local repositories
|
- [ ] List unclean local repositories
|
||||||
- [ ] Pull clean local repositories
|
- [ ] Pull clean local repositories
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
|
||||||
pub struct Config {
|
|
||||||
blacklist: Option<Vec<String>>,
|
|
||||||
lookups: Option<Vec<Lookup>>,
|
|
||||||
map: Option<Vec<Map>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
|
||||||
pub struct Lookup {
|
|
||||||
name: String,
|
|
||||||
url: String,
|
|
||||||
field: String,
|
|
||||||
interpolate: Option<Vec<String>>,
|
|
||||||
token_cmd: Option<String>,
|
|
||||||
block_unmatched: Option<bool>,
|
|
||||||
auth_header: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
|
||||||
pub struct Map {
|
|
||||||
patterns: Option<Vec<String>>,
|
|
||||||
url: Option<String>,
|
|
||||||
directory: Option<String>,
|
|
||||||
rename: Option<Vec<Rename>>,
|
|
||||||
ignore: Option<bool>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
|
||||||
pub struct Rename {
|
|
||||||
replace: String,
|
|
||||||
with: String,
|
|
||||||
}
|
|
|
@ -0,0 +1,134 @@
|
||||||
|
use git2::Repository;
|
||||||
|
use regex::Regex;
|
||||||
|
use reqwest::header::{HeaderMap, HeaderValue, CONTENT_TYPE};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_json::Value;
|
||||||
|
use std::{env, fs, path::PathBuf};
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
pub struct Config {
|
||||||
|
pub root_dir: String,
|
||||||
|
blacklist: Option<Vec<String>>,
|
||||||
|
lookups: Option<Vec<Lookup>>,
|
||||||
|
map: Vec<Map>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
|
pub struct Lookup {
|
||||||
|
name: String,
|
||||||
|
url: String,
|
||||||
|
field: String,
|
||||||
|
interpolate: Option<Vec<String>>,
|
||||||
|
token_cmd: Option<String>,
|
||||||
|
block_unmatched: Option<bool>,
|
||||||
|
auth_header: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
|
pub struct Map {
|
||||||
|
patterns: Option<Vec<String>>,
|
||||||
|
url: Option<String>,
|
||||||
|
directory: Option<PathBuf>,
|
||||||
|
rename: Option<Vec<Rename>>,
|
||||||
|
ignore: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
|
pub struct Rename {
|
||||||
|
replace: String,
|
||||||
|
with: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
pub fn setup(self: &mut Config) {
|
||||||
|
self.root_dir = expand_env_vars(&self.root_dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn list_target_dirs(self: &Config) -> Vec<PathBuf> {
|
||||||
|
self.map
|
||||||
|
.iter()
|
||||||
|
.filter_map(|map| {
|
||||||
|
map.directory
|
||||||
|
.as_ref()
|
||||||
|
.map(|path| PathBuf::from(self.root_dir.clone()).join(path))
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_target_dir(self: &Config, repo_url: &str) -> Option<&PathBuf> {
|
||||||
|
for map in &self.map {
|
||||||
|
if let Some(patterns) = &map.patterns {
|
||||||
|
for pattern in patterns {
|
||||||
|
if repo_url.contains(pattern) {
|
||||||
|
return map.directory.as_ref();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_remote_urls(
|
||||||
|
endpoint: &str,
|
||||||
|
auth_header: &str,
|
||||||
|
field: &str,
|
||||||
|
) -> Result<Vec<String>, Box<dyn std::error::Error>> {
|
||||||
|
let handle = reqwest::blocking::Client::new();
|
||||||
|
let mut headers = HeaderMap::new();
|
||||||
|
|
||||||
|
headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json"));
|
||||||
|
headers.insert(
|
||||||
|
"Authorization",
|
||||||
|
HeaderValue::from_str(auth_header).expect("Malformed auth header"),
|
||||||
|
);
|
||||||
|
|
||||||
|
let res = handle
|
||||||
|
.get(endpoint)
|
||||||
|
.headers(headers)
|
||||||
|
.send()
|
||||||
|
.expect("Request to API Failed")
|
||||||
|
.json::<Value>()
|
||||||
|
.expect("Malformed JSON Response from API");
|
||||||
|
|
||||||
|
let urls = res
|
||||||
|
.as_array()
|
||||||
|
.unwrap_or(&Vec::new())
|
||||||
|
.iter()
|
||||||
|
.filter_map(|obj| obj[field].as_str())
|
||||||
|
.map(|url| url.to_string())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Ok(urls)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_existing_repos(directories: &Vec<PathBuf>) -> Option<Vec<Repository>> {
|
||||||
|
let mut repos: Vec<Repository> = Vec::new();
|
||||||
|
|
||||||
|
for dir in directories {
|
||||||
|
let entries = match fs::read_dir(dir) {
|
||||||
|
Ok(entries) => entries
|
||||||
|
.filter_map(|entry| entry.ok())
|
||||||
|
.map(|entry| entry.path())
|
||||||
|
.filter_map(|path| Repository::open(path).ok())
|
||||||
|
.collect::<Vec<Repository>>(),
|
||||||
|
Err(_) => continue,
|
||||||
|
};
|
||||||
|
repos.extend(entries)
|
||||||
|
}
|
||||||
|
Some(repos)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expand_env_vars(input: &str) -> String {
|
||||||
|
let re = Regex::new(r"\$\{?[a-zA-Z_][a-zA-Z0-9_]*(\}|\b)").unwrap();
|
||||||
|
re.replace_all(input, |captures: ®ex::Captures| {
|
||||||
|
let var = captures
|
||||||
|
.get(0)
|
||||||
|
.unwrap()
|
||||||
|
.as_str()
|
||||||
|
.trim_start_matches('$')
|
||||||
|
.trim_matches(|c| c == '{' || c == '}');
|
||||||
|
env::var(var).unwrap()
|
||||||
|
})
|
||||||
|
.to_string()
|
||||||
|
}
|
|
@ -1,6 +1,4 @@
|
||||||
pub mod config;
|
|
||||||
pub mod remote;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let cfg: config::Config = confy::load("klados", "config").unwrap();
|
let mut cfg: klados::Config = confy::load("klados", "config").unwrap();
|
||||||
|
cfg.setup();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
use reqwest::header::{HeaderMap, HeaderValue, CONTENT_TYPE};
|
|
||||||
use serde_json::Value;
|
|
||||||
|
|
||||||
pub fn get_remote_urls(
|
|
||||||
endpoint: &str,
|
|
||||||
auth_header: &str,
|
|
||||||
field: &str,
|
|
||||||
) -> Result<Vec<String>, Box<dyn std::error::Error>> {
|
|
||||||
let handle = reqwest::blocking::Client::new();
|
|
||||||
let mut headers = HeaderMap::new();
|
|
||||||
|
|
||||||
headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json"));
|
|
||||||
headers.insert(
|
|
||||||
"Authorization",
|
|
||||||
HeaderValue::from_str(auth_header).expect("Malformed auth header"),
|
|
||||||
);
|
|
||||||
|
|
||||||
let res = handle
|
|
||||||
.get(endpoint)
|
|
||||||
.headers(headers)
|
|
||||||
.send()
|
|
||||||
.expect("Request to API Failed")
|
|
||||||
.json::<Value>()
|
|
||||||
.expect("Malformed JSON Response from API");
|
|
||||||
|
|
||||||
let urls = res
|
|
||||||
.as_array()
|
|
||||||
.unwrap_or(&Vec::new())
|
|
||||||
.iter()
|
|
||||||
.filter_map(|obj| obj[field].as_str())
|
|
||||||
.map(|url| url.to_string())
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
Ok(urls)
|
|
||||||
}
|
|
Loading…
Reference in New Issue