diff --git a/src/forge/gitlab.rs b/src/forge/gitlab.rs index 56bd9f30..db1f37df 100644 --- a/src/forge/gitlab.rs +++ b/src/forge/gitlab.rs @@ -1,7 +1,7 @@ use anyhow::{Context, Result}; use colored::Colorize; -use super::rest::RestClient; +use super::rest::paginate; use super::{Forge, MergeRequestResult, ReleaseResult}; use crate::error_code::{self, ErrorCodeExt}; @@ -52,13 +52,17 @@ impl GitLabForge { } fn paginated_json_array(&self, base_url: &str, what: &str) -> Result> { - RestClient::gitlab( - &self.agent, - format!("{}/projects/{}", self.api_base, self.encoded_project_id()), - self.token_kind.header(), - &self.token, + paginate( + || { + self.agent + .get(base_url) + .header(self.token_kind.header(), &self.token) + .header("User-Agent", "ferrflow") + }, + "per_page", + 100, + what, ) - .paginated_json_array(base_url, what) } } diff --git a/src/forge/rest.rs b/src/forge/rest.rs index 3b660ca9..e09debe5 100644 --- a/src/forge/rest.rs +++ b/src/forge/rest.rs @@ -41,22 +41,6 @@ impl<'a> RestClient<'a> { } } - pub fn gitlab( - agent: &'a ureq::Agent, - project_url: String, - token_header: &'static str, - token: &str, - ) -> Self { - Self { - agent, - repo_url: project_url, - auth: (token_header, token.to_string()), - extra_headers: &[], - page_size_param: "per_page", - page_size: 100, - } - } - fn headers(&self, mut request: RequestBuilder) -> RequestBuilder { request = request .header(self.auth.0, &self.auth.1) @@ -84,28 +68,12 @@ impl<'a> RestClient<'a> { base_url: &str, what: &str, ) -> Result> { - let mut all = Vec::new(); - for page in 1..=MAX_PAGES { - let body: serde_json::Value = self - .get(base_url) - .query(self.page_size_param, self.page_size.to_string()) - .query("page", page.to_string()) - .call() - .with_context(|| format!("Failed to list {what}"))? - .body_mut() - .read_json() - .with_context(|| format!("Failed to parse {what} response"))?; - let page_items = match body.as_array() { - Some(arr) if !arr.is_empty() => arr.clone(), - _ => return Ok(all), - }; - let len = page_items.len(); - all.extend(page_items); - if (len as u32) < self.page_size { - return Ok(all); - } - } - Ok(all) + paginate( + || self.get(base_url), + self.page_size_param, + self.page_size, + what, + ) } pub fn create_release( @@ -172,3 +140,32 @@ impl<'a> RestClient<'a> { Ok(()) } } + +pub(super) fn paginate( + request: impl Fn() -> RequestBuilder, + page_size_param: &str, + page_size: u32, + what: &str, +) -> Result> { + let mut all = Vec::new(); + for page in 1..=MAX_PAGES { + let body: serde_json::Value = request() + .query(page_size_param, page_size.to_string()) + .query("page", page.to_string()) + .call() + .with_context(|| format!("Failed to list {what}"))? + .body_mut() + .read_json() + .with_context(|| format!("Failed to parse {what} response"))?; + let page_items = match body.as_array() { + Some(arr) if !arr.is_empty() => arr.clone(), + _ => return Ok(all), + }; + let len = page_items.len(); + all.extend(page_items); + if (len as u32) < page_size { + return Ok(all); + } + } + Ok(all) +}