use crate::helpers::sync_repositories;
use crate::types::{GenericRepository, Provider};
use anyhow::{Context, Result};
use regex::RegexSetBuilder;
use reqwest::blocking;
use serde::Deserialize;
use std::path::Path;
pub fn run(backup_path: &Path, provider: &Provider) -> Result<()> {
let exclusions = RegexSetBuilder::new(&provider.exclude)
.case_insensitive(true)
.build()?;
let client = blocking::Client::new();
let mut repositories: Vec<GiteaRepository> = vec![];
let mut page = 1;
println!("Retrieving list of {} repositories...", provider.host);
loop {
let mut values = client
.get(format!(
"https://{}/api/v1/user/repos?page={page}&limit=100'",
provider.host
))
.header("Authorization", format!("token {}", &provider.token))
.send()
.with_context(|| {
format!(
"Unable to fetch {} API, please check your credentials",
provider.host
)
})?
.json::<Vec<GiteaRepository>>()
.context("Unable to deserialize repositories")?
.into_iter()
.filter(|r| !exclusions.is_match(&r.full_name()))
.collect::<Vec<GiteaRepository>>();
if values.is_empty() {
break;
}
repositories.append(&mut values);
page += 1;
}
sync_repositories(backup_path, provider, &repositories);
Ok(())
}
#[allow(dead_code)]
#[derive(Deserialize, Debug)]
struct GiteaRepository {
pub id: usize,
pub name: String,
pub full_name: String,
pub description: String,
pub private: bool,
pub default_branch: String,
pub url: String,
pub ssh_url: String,
pub clone_url: String,
pub html_url: String,
pub archived: bool,
pub created_at: String,
pub updated_at: String,
}
impl GenericRepository for GiteaRepository {
fn full_name(&self) -> String {
self.full_name.to_string()
}
fn default_branch(&self) -> String {
self.default_branch.to_string()
}
}