Skip to content

Commit

Permalink
Add ground work to talk to multiple github instances
Browse files Browse the repository at this point in the history
  • Loading branch information
SuperSandro2000 committed Aug 19, 2024
1 parent 8e7f094 commit deb9d3e
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 22 deletions.
55 changes: 55 additions & 0 deletions src/api_clients.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use std::collections::HashMap;
use std::env;
use std::sync::Arc;

use anyhow::{anyhow, Context, Ok};
use octocrab::Octocrab;

use crate::util::Remote;

pub struct ClientSet {
octocrab: HashMap<String, Arc<Octocrab>>,
}

impl ClientSet {
pub fn new() -> Self {
ClientSet {
octocrab: HashMap::new(),
}
}

pub fn add(&mut self, remote: &Remote) -> Result<(), anyhow::Error> {
let mut api_endpoint = "https://api.github.com".to_string();
let mut env_name = "GITHUB_TOKEN".to_string();
if remote.host.to_string() != "github.com" {
api_endpoint = format!("https://{}", &remote.host);
env_name = format!(
"GITHUB_{}_TOKEN",
&remote
.host
.to_string()
.replace('.', "_")
.to_uppercase()
.trim_start_matches("GITHUB_")
);
};

octocrab::initialise(
Octocrab::builder()
.personal_token(env::var(&env_name).with_context(|| format!("missing {env_name} env"))?)
.base_uri(&api_endpoint)
.with_context(|| format!("failed to set base_uri to {api_endpoint}"))?
.build()
.context("failed to build octocrab client")?,
);
self.octocrab.insert(remote.host.to_string(), octocrab::instance());

Ok(())
}

pub fn get(&self, remote: &Remote) -> Result<&Arc<Octocrab>, anyhow::Error> {
self.octocrab
.get(&remote.host.to_string())
.ok_or(anyhow!("no api client for {}", &remote.host))
}
}
23 changes: 13 additions & 10 deletions src/changes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use octocrab::models::pulls::Review;
use octocrab::models::pulls::ReviewState::Approved;
use octocrab::Octocrab;

use crate::api_clients::ClientSet;
use crate::util::Remote;

#[derive(Clone, Debug)]
Expand All @@ -19,7 +20,9 @@ pub struct RepoChangeset {
}

impl RepoChangeset {
pub async fn analyze_commits(&mut self, octocrab: &Arc<Octocrab>) -> Result<(), anyhow::Error> {
pub async fn analyze_commits(&mut self, client_set: &ClientSet) -> Result<(), anyhow::Error> {
let octocrab = client_set.get(&self.remote)?;

let compare = octocrab
.commits(&self.remote.owner, &self.remote.repository)
.compare(&self.base_commit, &self.head_commit)
Expand Down Expand Up @@ -86,19 +89,19 @@ impl RepoChangeset {
);

let mut pr_commits_page = octocrab
.pulls(&self.remote.owner, &self.remote.repository)
.pr_commits(associated_pr.number)
.await
.context("failed to get pr commits")?;
.pulls(&self.remote.owner, &self.remote.repository)
.pr_commits(associated_pr.number)
.await
.context("failed to get pr commits")?;
assert!(
pr_commits_page.next.is_none(),
"found more than one page for associated_prs"
pr_commits_page.next.is_none(),
"found more than one page for associated_prs"
);

let pr_commits = pr_commits_page.take_items();
assert!(
pr_commits.len() <= 250,
"found more than 250 commits which requires a different api endpoint per doc"
pr_commits.len() <= 250,
"found more than 250 commits which requires a different api endpoint per doc"
);
let head_sha = pr_commits.last().ok_or(anyhow!("PR contains no commits?"))?.sha.clone();

Expand Down Expand Up @@ -151,7 +154,7 @@ impl Changeset {
// Only account for reviews done on the last commit of the PR.
// We could count the PR as partly reviewed but that is to complicated to present at the moment.
if pr_review.commit_id != Some(head_sha.to_string()) {
continue;
continue;
}

// in case it isn't approve, ignore it
Expand Down
24 changes: 12 additions & 12 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
#![warn(clippy::pedantic)]

mod api_clients;
mod changes;
mod helm_config;
mod repo;
mod util;

use std::str;
use std::sync::LazyLock;
use std::{env, str};

use anyhow::{anyhow, Context};
use api_clients::ClientSet;
use changes::RepoChangeset;
use clap::builder::styling::Style;
use clap::{Parser, Subcommand};
use git2::Repository;
use helm_config::ImageRefs;
use octocrab::Octocrab;
use util::Remote;

const BOLD_UNDERLINE: Style = Style::new().bold().underline();
static GITHUB_TOKEN_HELP: LazyLock<String> = LazyLock::new(|| {
Expand Down Expand Up @@ -77,33 +79,31 @@ enum Commands {
async fn main() -> Result<(), anyhow::Error> {
let cli = Cli::parse();

octocrab::initialise(
Octocrab::builder()
.personal_token(env::var("GITHUB_TOKEN").context("missing GITHUB_TOKEN env")?)
.build()
.context("failed to build octocrab client")?,
);
let octocrab = octocrab::instance();
let mut api_clients = ClientSet::new();

match &cli.command {
Commands::Repo { remote } => {
let remote = util::Remote::parse(remote)?;
let remote = Remote::parse(remote)?;
api_clients.add(&remote)?;
let repo = &mut RepoChangeset {
name: remote.repository.clone(),
remote,
base_commit: cli.base,
head_commit: cli.head,
changes: Vec::new(),
};
repo.analyze_commits(&octocrab).await.context("while finding reviews")?;
repo.analyze_commits(&api_clients)
.await
.context("while finding reviews")?;
print_changes(&[repo.clone()]);
},
Commands::HelmChart { workspace } => {
let mut changes =
find_values_yaml(workspace.clone(), &cli.base, &cli.head).context("while finding values.yaml files")?;

for repo in &mut changes {
repo.analyze_commits(&octocrab)
api_clients.add(&repo.remote)?;
repo.analyze_commits(&api_clients)
.await
.context("while collecting repo changes")?;
}
Expand Down

0 comments on commit deb9d3e

Please sign in to comment.