Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Use dedicated library for getting PR list #807

Merged
merged 10 commits into from
Feb 14, 2024
12 changes: 6 additions & 6 deletions src-tauri/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,6 @@ pub const SECTION_ORDER: [&str; 11] = [
"feat", "fix", "docs", "style", "refactor", "build", "test", "i18n", "ci", "chore", "other",
];

/// GitHub API endpoints for launcher/mods PRs
pub const PULLS_API_ENDPOINT_LAUNCHER: &str =
"https://api.github.com/repos/R2Northstar/NorthstarLauncher/pulls";
pub const PULLS_API_ENDPOINT_MODS: &str =
"https://api.github.com/repos/R2Northstar/NorthstarMods/pulls";

/// Statistics (players and servers counts) refresh delay
pub const REFRESH_DELAY: Duration = Duration::from_secs(5 * 60);

Expand All @@ -46,6 +40,12 @@ pub const FLIGHTCORE_REPO_NAME: &str = "R2NorthstarTools/FlightCore";
/// Northstar release repo name and org name on GitHub
pub const NORTHSTAR_RELEASE_REPO_NAME: &str = "R2Northstar/Northstar";

/// NorthstarLauncher repo name on GitHub
pub const NORTHSTAR_LAUNCHER_REPO_NAME: &str = "NorthstarLauncher";

/// NorthstarMods repo name on GitHub
pub const NORTHSTAR_MODS_REPO_NAME: &str = "NorthstarMods";

/// URL to launcher commits API URL
pub const NS_LAUNCHER_COMMITS_API_URL: &str =
"https://api.github.com/repos/R2Northstar/NorthstarLauncher/commits";
Expand Down
78 changes: 49 additions & 29 deletions src-tauri/src/github/pull_requests.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use crate::github::release_notes::fetch_github_releases_api;

use crate::constants::{APP_USER_AGENT, PULLS_API_ENDPOINT_LAUNCHER, PULLS_API_ENDPOINT_MODS};
use crate::constants::{APP_USER_AGENT, NORTHSTAR_LAUNCHER_REPO_NAME, NORTHSTAR_MODS_REPO_NAME};
use crate::repair_and_verify::check_is_valid_game_path;
use crate::GameInstall;
use anyhow::anyhow;
Expand Down Expand Up @@ -66,32 +64,56 @@ pub enum PullRequestType {
}

/// Parse pull requests from specified URL
pub async fn get_pull_requests(url: String) -> Result<Vec<PullsApiResponseElement>, String> {
let mut all_pull_requests: Vec<PullsApiResponseElement> = vec![];
pub async fn get_pull_requests(
repo: PullRequestType,
) -> Result<Vec<PullsApiResponseElement>, anyhow::Error> {
let repo = match repo {
PullRequestType::Mods => NORTHSTAR_MODS_REPO_NAME,
PullRequestType::Launcher => NORTHSTAR_LAUNCHER_REPO_NAME,
};

let mut i = 1; // pagination on GitHub starts with `1`.
loop {
let paginated_url = format!("{}?page={}", url, i);
// Grab list of PRs
let octocrab = octocrab::instance();
let page = octocrab
.pulls("R2Northstar", repo)
.list()
.state(octocrab::params::State::Open)
.per_page(50) // Only grab 50 PRs
.page(1u32)
.send()
.await?;

let json_response = match fetch_github_releases_api(&paginated_url).await {
Ok(result) => result,
Err(err) => return Err(format!("Failed fetching GitHub API {err}")),
// Iterate over pull request elements and insert into struct
let mut all_pull_requests: Vec<PullsApiResponseElement> = vec![];
for item in page.items {
let repo = Repo {
full_name: item
.head
.repo
.ok_or(anyhow!("repo not found"))?
.full_name
.ok_or(anyhow!("full_name not found"))?,
};

let pulls_response: Vec<PullsApiResponseElement> =
match serde_json::from_str(&json_response) {
Ok(res) => res,
Err(err) => return Err(err.to_string()),
};
let head = CommitHead {
sha: item.head.sha,
gh_ref: item.head.ref_field,
repo,
};

// Check if we still got a result
if pulls_response.is_empty() {
// Empty result means we went through all pages with content
break;
}
// TODO there's probably a way to automatically serialize into the struct but I don't know yet how to
let elem = PullsApiResponseElement {
number: item.number,
title: item.title.ok_or(anyhow!("title not found"))?,
url: item.url,
head,
html_url: item
.html_url
.ok_or(anyhow!("html_url not found"))?
.to_string(),
};

all_pull_requests.extend(pulls_response);
i += 1;
all_pull_requests.push(elem);
}

Ok(all_pull_requests)
Expand All @@ -102,12 +124,10 @@ pub async fn get_pull_requests(url: String) -> Result<Vec<PullsApiResponseElemen
pub async fn get_pull_requests_wrapper(
install_type: PullRequestType,
) -> Result<Vec<PullsApiResponseElement>, String> {
let api_pr_url = match install_type {
PullRequestType::Mods => PULLS_API_ENDPOINT_MODS,
PullRequestType::Launcher => PULLS_API_ENDPOINT_LAUNCHER,
};

get_pull_requests(api_pr_url.to_string()).await
match get_pull_requests(install_type).await {
Ok(res) => Ok(res),
Err(err) => Err(err.to_string()),
}
}

pub async fn check_github_api(url: &str) -> Result<serde_json::Value, Box<dyn std::error::Error>> {
Expand Down
Loading