use serde::Serialize; use crate::service::GitService; use crate::service::gitcmd::run_git_soft; use crate::share::errors::{GitError, map_baby}; #[derive(Debug, Clone, Serialize, utoipa::ToSchema)] pub struct PruneResultDto { pub reachable: i64, pub unreachable: i64, pub total: i64, } #[derive(Debug, Clone, Serialize, utoipa::ToSchema)] pub struct FsckDto { pub ok: bool, pub dangling: i64, pub broken: i64, } impl GitService { pub async fn maintenance_prune( &self, space_name: String, repo_name: String, ) -> Result { let ctx = self.context(space_name, repo_name).await?; self.baby(&ctx).prune().await.map_err(map_baby)?; let timeout = self.state.config.git.git_command_timeout_secs; let out = run_git_soft( "maintenance::count_objects", &ctx.repo_dir(), vec!["count-objects".to_string(), "-v".to_string()], &[], timeout, ) .await?; let mut total: i64 = 0; if out.status.success() { for line in String::from_utf8_lossy(&out.stdout).lines() { if let Some(rest) = line.strip_prefix("count: ") { total = rest.trim().parse().unwrap_or(0); } } } Ok(PruneResultDto { reachable: total, unreachable: 0, total, }) } pub async fn maintenance_fsck( &self, space_name: String, repo_name: String, ) -> Result { let ctx = self.context(space_name, repo_name).await?; let timeout = self.state.config.git.git_command_timeout_secs; let out = run_git_soft( "maintenance::fsck", &ctx.repo_dir(), vec!["fsck".to_string(), "--no-progress".to_string()], &[], timeout, ) .await?; let stdout = String::from_utf8_lossy(&out.stdout); let dangling = stdout.lines().filter(|l| l.contains("dangling")).count() as i64; Ok(FsckDto { ok: out.status.success(), dangling, broken: if out.status.success() { 0 } else { 1 }, }) } }