Skip to content

Commit

Permalink
Move api requests to remote type
Browse files Browse the repository at this point in the history
  • Loading branch information
SuperSandro2000 committed Aug 21, 2024
1 parent 5743ec3 commit b9bad9c
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 61 deletions.
70 changes: 10 additions & 60 deletions src/changes.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
use std::sync::Arc;

use anyhow::{anyhow, Context};
use octocrab::commits::PullRequestTarget;
use anyhow::anyhow;
use octocrab::models::commits::Commit;
use octocrab::models::pulls::Review;
use octocrab::models::pulls::ReviewState::Approved;
use octocrab::Octocrab;

use crate::api_clients::ClientSet;
use crate::remote::Remote;
Expand All @@ -21,42 +17,22 @@ pub struct RepoChangeset {

impl RepoChangeset {
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)
.send()
.await
.context(format!(
"failed to compare {}/compare/{}...{}",
self.remote.original.trim_end_matches(".git"),
&self.base_commit,
&self.head_commit
))?;
let compare = self
.remote
.compare(client_set, &self.base_commit, &self.head_commit)
.await?;

for commit in &compare.commits {
self.analyze_commit(octocrab, commit).await?;
self.analyze_commit(client_set, commit).await?;
}

Ok(())
}

async fn analyze_commit(&mut self, octocrab: &Arc<Octocrab>, commit: &Commit) -> Result<(), anyhow::Error> {
let mut associated_prs_page = octocrab
.commits(&self.remote.owner, &self.remote.repository)
.associated_pull_requests(PullRequestTarget::Sha(commit.sha.clone()))
.send()
.await
.context("failed to get associated prs")?;
assert!(
associated_prs_page.next.is_none(),
"found more than one page for associated_prs"
);
let associated_prs = associated_prs_page.take_items();
async fn analyze_commit(&mut self, client_set: &ClientSet, commit: &Commit) -> Result<(), anyhow::Error> {
let associated_prs = self.remote.associated_prs(client_set, commit).await?;

let change_commit = CommitMetadata::new(commit);

if associated_prs.is_empty() {
self.changes.push(Changeset {
commits: vec![change_commit],
Expand All @@ -67,18 +43,7 @@ impl RepoChangeset {
}

for associated_pr in &associated_prs {
let mut pr_reviews_page = octocrab
.pulls(&self.remote.owner, &self.remote.repository)
.list_reviews(associated_pr.number)
.send()
.await
.context("failed to get reviews")?;
assert!(
pr_reviews_page.next.is_none(),
"found more than one page for associated_prs"
);
let mut pr_reviews = pr_reviews_page.take_items();
pr_reviews.sort_by_key(|r| r.submitted_at);
let pr_reviews = self.remote.pr_reviews(client_set, associated_pr.number).await?;

let associated_pr_link = Some(
associated_pr
Expand All @@ -88,22 +53,7 @@ impl RepoChangeset {
.to_string(),
);

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")?;
assert!(
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"
);
let head_sha = pr_commits.last().ok_or(anyhow!("PR contains no commits?"))?.sha.clone();
let head_sha = self.remote.pr_head_hash(client_set, associated_pr.number).await?;

if let Some(changeset) = self.changes.iter_mut().find(|cs| cs.pr_link == associated_pr_link) {
changeset.commits.push(change_commit.clone());
Expand Down
96 changes: 95 additions & 1 deletion src/remote.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
use anyhow::Context;
use anyhow::{anyhow, Context};
use octocrab::commits::PullRequestTarget;
use octocrab::models::commits::{Commit, CommitComparison};
use octocrab::models::pulls::{PullRequest, Review};
use octocrab::models::repos::RepoCommit;
use url::Url;

use crate::api_clients::ClientSet;

#[derive(Clone, Debug)]
#[allow(dead_code)]
pub struct Remote {
Expand All @@ -23,4 +29,92 @@ impl Remote {
original: url.into(),
})
}

pub async fn associated_prs(
&self,
client_set: &ClientSet,
commit: &Commit,
) -> Result<Vec<PullRequest>, anyhow::Error> {
let mut associated_prs_page = client_set
.get(self)?
.commits(&self.owner, &self.repository)
.associated_pull_requests(PullRequestTarget::Sha(commit.clone().sha.clone()))
.send()
.await
.context("failed to get associated prs")?;
assert!(
associated_prs_page.next.is_none(),
"found more than one page for associated_prs"
);
Ok(associated_prs_page.take_items())
}

pub async fn compare(
&self,
client_set: &ClientSet,
base_commit: &str,
head_commit: &str,
) -> Result<CommitComparison, anyhow::Error> {
client_set
.get(self)?
.commits(&self.owner, &self.repository)
.compare(base_commit, head_commit)
.send()
.await
.context(format!(
"failed to compare {}/compare/{}...{}",
self.original.trim_end_matches(".git"),
&base_commit,
&head_commit
))
}

pub async fn pr_head_hash(&self, client_set: &ClientSet, pr_number: u64) -> Result<String, anyhow::Error> {
Ok(self
.pr_commits(client_set, pr_number)
.await
.context("failed to get pr commits")?
.last()
.ok_or(anyhow!("PR contains no commits?"))?
.sha
.clone())
}

pub async fn pr_commits(&self, client_set: &ClientSet, pr_number: u64) -> Result<Vec<RepoCommit>, anyhow::Error> {
let mut pr_commits_page = client_set
.get(self)?
.pulls(&self.owner, &self.repository)
.pr_commits(pr_number)
.await
.context("failed to get pr commits")?;
assert!(
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"
);

Ok(pr_commits)
}

pub async fn pr_reviews(&self, client_set: &ClientSet, pr_number: u64) -> Result<Vec<Review>, anyhow::Error> {
let mut pr_reviews_page = client_set
.get(self)?
.pulls(&self.owner, &self.repository)
.list_reviews(pr_number)
.send()
.await
.context("failed to get reviews")?;
assert!(
pr_reviews_page.next.is_none(),
"found more than one page for associated_prs"
);
let mut pr_reviews = pr_reviews_page.take_items();
pr_reviews.sort_by_key(|r| r.submitted_at);
Ok(pr_reviews)
}
}

0 comments on commit b9bad9c

Please sign in to comment.