123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- use std::collections::HashMap;
- use async_trait::async_trait;
- use reqwest::Client;
- use tera::{Context, Tera};
- use crate::github::{self, GithubClient, Repository};
- #[async_trait]
- pub trait Action {
- async fn call(&self) -> String;
- }
- pub struct Step<'a> {
- pub name: &'a str,
- pub actions: Vec<Query<'a>>,
- }
- pub struct Query<'a> {
- pub repo: &'a str,
- pub queries: Vec<QueryMap<'a>>,
- }
- pub struct QueryMap<'a> {
- pub name: &'a str,
- pub query: github::Query<'a>,
- }
- #[derive(serde::Serialize)]
- pub struct IssueDecorator {
- pub number: u64,
- pub title: String,
- pub html_url: String,
- pub repo_name: String,
- pub labels: String,
- pub assignees: String,
- }
- lazy_static! {
- pub static ref TEMPLATES: Tera = {
- match Tera::new("templates/*") {
- Ok(t) => t,
- Err(e) => {
- println!("Parsing error(s): {}", e);
- ::std::process::exit(1);
- }
- }
- };
- }
- #[async_trait]
- impl<'a> Action for Step<'a> {
- async fn call(&self) -> String {
- let gh = GithubClient::new_with_default_token(Client::new());
- let mut context = Context::new();
- let mut results = HashMap::new();
- for Query { repo, queries } in &self.actions {
- let repository = Repository {
- full_name: repo.to_string(),
- };
- for QueryMap { name, query } in queries {
- match query.kind {
- github::QueryKind::List => {
- let issues_search_result = repository.get_issues(&gh, &query).await;
- match issues_search_result {
- Ok(issues) => {
- let issues_decorator: Vec<_> = issues
- .iter()
- .map(|issue| IssueDecorator {
- title: issue.title.clone(),
- number: issue.number,
- html_url: issue.html_url.clone(),
- repo_name: repository
- .full_name
- .split("/")
- .last()
- .expect("Failed to split repository name")
- .to_string(),
- labels: issue
- .labels
- .iter()
- .map(|l| l.name.as_ref())
- .collect::<Vec<_>>()
- .join(", "),
- assignees: issue
- .assignees
- .iter()
- .map(|u| u.login.as_ref())
- .collect::<Vec<_>>()
- .join(", "),
- })
- .collect();
- results
- .entry(*name)
- .or_insert(Vec::new())
- .extend(issues_decorator);
- }
- Err(err) => {
- eprintln!("ERROR: {}", err);
- err.chain()
- .skip(1)
- .for_each(|cause| eprintln!("because: {}", cause));
- std::process::exit(1);
- }
- }
- }
- github::QueryKind::Count => {
- let count = repository.get_issues_count(&gh, &query).await;
- match count {
- Ok(count) => {
- context.insert(*name, &count);
- }
- Err(err) => {
- eprintln!("ERROR: {}", err);
- err.chain()
- .skip(1)
- .for_each(|cause| eprintln!("because: {}", cause));
- std::process::exit(1);
- }
- }
- }
- };
- }
- }
- for (name, issues) in &results {
- context.insert(*name, issues);
- }
- TEMPLATES
- .render(&format!("{}.tt", self.name), &context)
- .unwrap()
- }
- }
|