diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 84dc162..f297ef5 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -14,7 +14,7 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: | ~/.cargo/bin/ diff --git a/Cargo.lock b/Cargo.lock index c5c2bea..9a51109 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -142,6 +142,7 @@ dependencies = [ "serde", "serde_json", "tokio", + "toml", ] [[package]] @@ -791,6 +792,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -956,6 +966,40 @@ dependencies = [ "tracing", ] +[[package]] +name = "toml" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tower" version = "0.4.13" @@ -1271,6 +1315,15 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +[[package]] +name = "winnow" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.50.0" diff --git a/Cargo.toml b/Cargo.toml index f6a4cfc..0f24101 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,3 +30,4 @@ tokio = { version = "1", features = ["full"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" anyhow = "1.0" +toml = "0.8.8" diff --git a/config.toml b/config.toml new file mode 100644 index 0000000..0017e13 --- /dev/null +++ b/config.toml @@ -0,0 +1,5 @@ +config = "github" +token = "ghp_4" +reviews = ["baerwang"] +owners = [{ name = "baerwang", repos = ["pika"] }] +orgs = { } \ No newline at end of file diff --git a/src/conf/config.rs b/src/conf/config.rs new file mode 100644 index 0000000..33bdaf8 --- /dev/null +++ b/src/conf/config.rs @@ -0,0 +1,18 @@ +use std::collections::HashMap; + +use serde::Deserialize; + +#[derive(Deserialize, Debug)] +pub struct ConfigData { + pub config: String, + pub token: String, + pub reviews: Vec, + pub owners: Vec, + pub orgs: HashMap>, +} + +#[derive(Deserialize, Debug)] +pub struct Owner { + pub name: String, + pub repos: Vec, +} diff --git a/src/conf/mod.rs b/src/conf/mod.rs new file mode 100644 index 0000000..c66400e --- /dev/null +++ b/src/conf/mod.rs @@ -0,0 +1,18 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +pub mod config; diff --git a/src/lib.rs b/src/lib.rs index 29a901c..4067b7b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,4 +15,5 @@ * limitations under the License. */ +pub mod conf; pub mod plugins; diff --git a/src/main.rs b/src/main.rs index 79ee4c5..6fbae86 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,11 +15,33 @@ * limitations under the License. */ -use std::env; +use std::fs; +use flexible::conf::config::ConfigData; use flexible::plugins::get_api; fn main() { - let api = get_api("github", "baerwang".to_string()); - _ = api.execute(env::var("token").unwrap().as_str()); + let toml_data = match fs::read_to_string("config.toml") { + Ok(content) => content, + Err(err) => { + panic!("Failed to read TOML file: {}", err); + } + }; + + let config: ConfigData = match toml::from_str(&toml_data) { + Ok(parsed) => parsed, + Err(err) => { + panic!("Failed to parse TOML data: {}", err); + } + }; + + let token = config.token.as_str(); + let plugin = config.config.as_str(); + + config.owners.iter().for_each(|owner| { + let api = get_api(plugin, owner.name.clone()); + owner.repos.iter().for_each(|repo| { + _ = api.execute(token, repo.as_str()); + }) + }); } diff --git a/src/plugins/api.rs b/src/plugins/api.rs index 5bcfd89..2dc9a41 100644 --- a/src/plugins/api.rs +++ b/src/plugins/api.rs @@ -18,11 +18,10 @@ use reqwest::header::HeaderMap; pub trait Api { - fn domain(&self) -> &str { - "https://api.github.com" - } - fn execute(&self, token: &str) -> Result<(), anyhow::Error>; + fn domain(&self) -> &str; + fn execute(&self, token: &str, repo: &str) -> Result<(), anyhow::Error>; fn headers(&self, token: &str) -> HeaderMap; + fn repo(&self, repo: &str) -> String; fn repos(&self) -> String; fn pull_requests(&self, repo: &str) -> String; fn issues(&self, repo: &str) -> String; diff --git a/src/plugins/github.rs b/src/plugins/github.rs index 5f5888a..ecaf197 100644 --- a/src/plugins/github.rs +++ b/src/plugins/github.rs @@ -28,25 +28,19 @@ impl GitHub { } impl Api for GitHub { - fn execute(&self, token: &str) -> Result<(), anyhow::Error> { - let resp = client(self.repos(), self.headers(token))?; - let parsed_json: Value = serde_json::from_str(&resp)?; + fn domain(&self) -> &str { + "https://api.github.com" + } + + fn execute(&self, token: &str, repo: &str) -> Result<(), anyhow::Error> { + let rsp = client(self.pull_requests(repo), self.headers(token))?; + let parsed_json: Value = serde_json::from_str(&rsp)?; if let Some(array) = parsed_json.as_array() { for element in array { - if let Some(name) = element.get("name").and_then(|name| name.as_str()) { - let rsp = client(self.pull_requests(name), self.headers(token))?; - let parsed_json: Value = serde_json::from_str(&rsp)?; - if let Some(array) = parsed_json.as_array() { - for element in array { - if let Some(number) = - element.get("number").and_then(|number| number.as_i64()) - { - let rsp = client(self.reviews(name, number), self.headers(token))?; - // todo - println!("{}", rsp) - } - } - } + if let Some(number) = element.get("number").and_then(|number| number.as_i64()) { + let rsp = client(self.reviews(repo, number), self.headers(token))?; + // todo + println!("{}", rsp) } } } @@ -61,6 +55,10 @@ impl Api for GitHub { headers } + fn repo(&self, name: &str) -> String { + format!("{}/users/{}/repos?page=1&per_page=100", self.domain(), name) + } + fn repos(&self) -> String { match self.owner { Some(ref s) => format!("{}/users/{}/repos?page=1&per_page=100", self.domain(), s),