use crate::models::common::DEFAULT_REVISION; use actix_web::{HttpResponse, web}; use serde::Deserialize; use utoipa::IntoParams; use crate::api::response::ApiResponse; use crate::error::AppError; use crate::service::AppService; use crate::session::Session; #[derive(Debug, Deserialize, IntoParams)] pub struct PathParams { pub workspace_name: String, pub repo_name: String, } #[derive(Debug, Deserialize, IntoParams)] pub struct RevisionPathParams { pub workspace_name: String, pub repo_name: String, pub revision: String, } #[utoipa::path( get, path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/default-branch", tag = "Git", operation_id = "gitDefaultBranch", params(PathParams), responses((status = 200, body = ApiResponse)), security(("session_cookie" = [])) )] pub async fn git_default_branch( service: web::Data, session: Session, path: web::Path, ) -> Result { let r = service .repo .git_get_default_branch(&session, &path.workspace_name, &path.repo_name) .await?; Ok(HttpResponse::Ok().json(ApiResponse::new(r))) } #[utoipa::path( get, path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/object-format", tag = "Git", operation_id = "gitObjectFormat", params(PathParams), responses((status = 200, body = ApiResponse)), security(("session_cookie" = [])) )] pub async fn git_object_format( service: web::Data, session: Session, path: web::Path, ) -> Result { let r = service .repo .git_get_object_format(&session, &path.workspace_name, &path.repo_name) .await?; Ok(HttpResponse::Ok().json(ApiResponse::new(r))) } #[utoipa::path( get, path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/size", tag = "Git", operation_id = "gitRepositorySize", params(PathParams), responses(( status = 200, body = ApiResponse )), security(("session_cookie" = [])) )] pub async fn git_repository_size( service: web::Data, session: Session, path: web::Path, ) -> Result { let r = service .repo .git_repository_size(&session, &path.workspace_name, &path.repo_name) .await?; Ok(HttpResponse::Ok().json(ApiResponse::new(r))) } #[derive(Debug, Deserialize, utoipa::ToSchema)] pub struct ObjectsSizeBody { pub oids: Vec, } #[utoipa::path( post, path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/objects-size", tag = "Git", operation_id = "gitObjectsSize", params(PathParams), request_body(content = ObjectsSizeBody), responses(( status = 200, body = ApiResponse )), security(("session_cookie" = [])) )] pub async fn git_objects_size( service: web::Data, session: Session, path: web::Path, body: web::Json, ) -> Result { let r = service .repo .git_objects_size( &session, &path.workspace_name, &path.repo_name, body.oids.clone(), ) .await?; Ok(HttpResponse::Ok().json(ApiResponse::new(r))) } #[derive(Debug, Deserialize, IntoParams)] pub struct MergeBaseQuery { pub revisions: Vec, } #[utoipa::path( get, path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/merge-base", tag = "Git", operation_id = "gitMergeBase", params(PathParams, MergeBaseQuery), responses(( status = 200, body = ApiResponse )), security(("session_cookie" = [])) )] pub async fn git_merge_base( service: web::Data, session: Session, path: web::Path, q: web::Query, ) -> Result { let r = service .repo .git_find_merge_base( &session, &path.workspace_name, &path.repo_name, q.revisions.clone(), ) .await?; Ok(HttpResponse::Ok().json(ApiResponse::new(r))) } #[derive(Debug, Deserialize, IntoParams)] pub struct ArchiveEntriesQuery { pub treeish: Option, pub limit: Option, } #[utoipa::path( get, path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/archive/entries", tag = "Git", operation_id = "gitArchiveEntries", params(PathParams, ArchiveEntriesQuery), responses(( status = 200, body = ApiResponse )), security(("session_cookie" = [])) )] pub async fn git_archive_entries( service: web::Data, session: Session, path: web::Path, q: web::Query, ) -> Result { let r = service .repo .git_list_archive_entries( &session, &path.workspace_name, &path.repo_name, q.treeish.as_deref().unwrap_or(DEFAULT_REVISION), q.limit.unwrap_or(50).clamp(1, 100) as u32, ) .await?; Ok(HttpResponse::Ok().json(ApiResponse::new(r))) } #[derive(Debug, Deserialize, IntoParams)] pub struct CommitAncestorsQuery { pub max_count: Option, } #[utoipa::path( get, path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/commits/{revision}/ancestors", tag = "Git", operation_id = "gitCommitAncestors", params(RevisionPathParams, CommitAncestorsQuery), responses(( status = 200, body = ApiResponse )), security(("session_cookie" = [])) )] pub async fn git_commit_ancestors( service: web::Data, session: Session, path: web::Path, q: web::Query, ) -> Result { let r = service .repo .git_get_commit_ancestors( &session, &path.workspace_name, &path.repo_name, &path.revision, q.max_count.unwrap_or(100), ) .await?; Ok(HttpResponse::Ok().json(ApiResponse::new(r))) } #[derive(Debug, Deserialize, utoipa::ToSchema)] pub struct CheckObjectsBody { pub revisions: Vec, } #[utoipa::path( post, path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/check-objects", tag = "Git", operation_id = "gitCheckObjects", params(PathParams), request_body(content = CheckObjectsBody), responses(( status = 200, body = ApiResponse )), security(("session_cookie" = [])) )] pub async fn git_check_objects( service: web::Data, session: Session, path: web::Path, body: web::Json, ) -> Result { let r = service .repo .git_check_objects_exist( &session, &path.workspace_name, &path.repo_name, body.revisions.clone(), ) .await?; Ok(HttpResponse::Ok().json(ApiResponse::new(r))) }