use crate::{ApiResponse, error::ApiError}; use actix_web::{HttpResponse, Result, web}; use service::AppService; use service::git::branch::{ BranchCreateRequest, BranchDiffQuery, BranchDiffResponse, BranchExistsResponse, BranchFastForwardResponse, BranchInfoResponse, BranchIsAncestorQuery, BranchIsAncestorResponse, BranchIsConflictedResponse, BranchIsDetachedResponse, BranchIsHeadResponse, BranchIsMergedQuery, BranchIsMergedResponse, BranchListQuery, BranchMergeBaseQuery, BranchMergeBaseResponse, BranchMoveRequest, BranchRenameRequest, BranchSetUpstreamRequest, BranchSummaryResponse, BranchTrackingDiffResponse, }; use session::Session; #[utoipa::path( get, path = "/api/repos/{namespace}/{repo}/git/branches", params( ("namespace" = String, Path, description = "Project namespace"), ("repo" = String, Path, description = "Repository name"), ), responses( (status = 401, description = "Unauthorized", body = ApiResponse), (status = 200, description = "List branches", body = ApiResponse>), (status = 404, description = "Not found", body = ApiResponse), ), tag = "Git" )] pub async fn git_branch_list( service: web::Data, session: Session, path: web::Path<(String, String)>, query: web::Query, ) -> Result { let (namespace, repo_name) = path.into_inner(); let resp = service .git_branch_list(namespace, repo_name, query.into_inner(), &session) .await?; Ok(ApiResponse::ok(resp).to_response()) } #[utoipa::path( get, path = "/api/repos/{namespace}/{repo}/git/branches/summary", params( ("namespace" = String, Path, description = "Project namespace"), ("repo" = String, Path, description = "Repository name"), ), responses( (status = 401, description = "Unauthorized", body = ApiResponse), (status = 200, description = "Get branch summary", body = ApiResponse), (status = 404, description = "Not found", body = ApiResponse), ), tag = "Git" )] pub async fn git_branch_summary( service: web::Data, session: Session, path: web::Path<(String, String)>, ) -> Result { let (namespace, repo_name) = path.into_inner(); let resp = service .git_branch_summary(namespace, repo_name, &session) .await?; Ok(ApiResponse::ok(resp).to_response()) } #[utoipa::path( get, path = "/api/repos/{namespace}/{repo}/git/branches/{name}", params( ("namespace" = String, Path, description = "Project namespace"), ("repo" = String, Path, description = "Repository name"), ("name" = String, Path, description = "Branch name"), ), responses( (status = 401, description = "Unauthorized", body = ApiResponse), (status = 200, description = "Get branch", body = ApiResponse), (status = 404, description = "Not found", body = ApiResponse), ), tag = "Git" )] pub async fn git_branch_get( service: web::Data, session: Session, path: web::Path<(String, String, String)>, ) -> Result { let (namespace, repo_name, name) = path.into_inner(); let resp = service .git_branch_get(namespace, repo_name, name, &session) .await?; Ok(ApiResponse::ok(resp).to_response()) } #[utoipa::path( get, path = "/api/repos/{namespace}/{repo}/git/branches/current", params( ("namespace" = String, Path, description = "Project namespace"), ("repo" = String, Path, description = "Repository name"), ), responses( (status = 401, description = "Unauthorized", body = ApiResponse), (status = 200, description = "Get current branch", body = ApiResponse), (status = 404, description = "Not found", body = ApiResponse), ), tag = "Git" )] pub async fn git_branch_current( service: web::Data, session: Session, path: web::Path<(String, String)>, ) -> Result { let (namespace, repo_name) = path.into_inner(); let resp = service .git_branch_current(namespace, repo_name, &session) .await?; Ok(ApiResponse::ok(resp).to_response()) } #[utoipa::path( get, path = "/api/repos/{namespace}/{repo}/git/branches/{name}/exists", params( ("namespace" = String, Path, description = "Project namespace"), ("repo" = String, Path, description = "Repository name"), ("name" = String, Path, description = "Branch name"), ), responses( (status = 401, description = "Unauthorized", body = ApiResponse), (status = 200, description = "Check branch exists", body = ApiResponse), (status = 404, description = "Not found", body = ApiResponse), ), tag = "Git" )] pub async fn git_branch_exists( service: web::Data, session: Session, path: web::Path<(String, String, String)>, ) -> Result { let (namespace, repo_name, name) = path.into_inner(); let resp = service .git_branch_exists(namespace, repo_name, name, &session) .await?; Ok(ApiResponse::ok(resp).to_response()) } #[utoipa::path( get, path = "/api/repos/{namespace}/{repo}/git/branches/{name}/is-head", params( ("namespace" = String, Path, description = "Project namespace"), ("repo" = String, Path, description = "Repository name"), ("name" = String, Path, description = "Branch name"), ), responses( (status = 401, description = "Unauthorized", body = ApiResponse), (status = 200, description = "Check if branch is HEAD", body = ApiResponse), (status = 404, description = "Not found", body = ApiResponse), ), tag = "Git" )] pub async fn git_branch_is_head( service: web::Data, session: Session, path: web::Path<(String, String, String)>, ) -> Result { let (namespace, repo_name, name) = path.into_inner(); let resp = service .git_branch_is_head(namespace, repo_name, name, &session) .await?; Ok(ApiResponse::ok(resp).to_response()) } #[utoipa::path( get, path = "/api/repos/{namespace}/{repo}/git/branches/is-detached", params( ("namespace" = String, Path, description = "Project namespace"), ("repo" = String, Path, description = "Repository name"), ), responses( (status = 401, description = "Unauthorized", body = ApiResponse), (status = 200, description = "Check if HEAD is detached", body = ApiResponse), (status = 404, description = "Not found", body = ApiResponse), ), tag = "Git" )] pub async fn git_branch_is_detached( service: web::Data, session: Session, path: web::Path<(String, String)>, ) -> Result { let (namespace, repo_name) = path.into_inner(); let resp = service .git_branch_is_detached(namespace, repo_name, &session) .await?; Ok(ApiResponse::ok(resp).to_response()) } #[utoipa::path( get, path = "/api/repos/{namespace}/{repo}/git/branches/{name}/upstream", params( ("namespace" = String, Path, description = "Project namespace"), ("repo" = String, Path, description = "Repository name"), ("name" = String, Path, description = "Branch name"), ), responses( (status = 401, description = "Unauthorized", body = ApiResponse), (status = 200, description = "Get upstream branch", body = ApiResponse), (status = 404, description = "Not found", body = ApiResponse), ), tag = "Git" )] pub async fn git_branch_upstream( service: web::Data, session: Session, path: web::Path<(String, String, String)>, ) -> Result { let (namespace, repo_name, name) = path.into_inner(); let resp = service .git_branch_upstream(namespace, repo_name, name, &session) .await?; Ok(ApiResponse::ok(resp).to_response()) } #[utoipa::path( get, path = "/api/repos/{namespace}/{repo}/git/branches/diff", params( ("namespace" = String, Path, description = "Project namespace"), ("repo" = String, Path, description = "Repository name"), ), responses( (status = 401, description = "Unauthorized", body = ApiResponse), (status = 200, description = "Get branch diff", body = ApiResponse), (status = 404, description = "Not found", body = ApiResponse), ), tag = "Git" )] pub async fn git_branch_diff( service: web::Data, session: Session, path: web::Path<(String, String)>, query: web::Query, ) -> Result { let (namespace, repo_name) = path.into_inner(); let resp = service .git_branch_diff(namespace, repo_name, query.into_inner(), &session) .await?; Ok(ApiResponse::ok(resp).to_response()) } #[utoipa::path( get, path = "/api/repos/{namespace}/{repo}/git/branches/{name}/tracking-difference", params( ("namespace" = String, Path, description = "Project namespace"), ("repo" = String, Path, description = "Repository name"), ("name" = String, Path, description = "Branch name"), ), responses( (status = 401, description = "Unauthorized", body = ApiResponse), (status = 200, description = "Get tracking difference", body = ApiResponse), (status = 404, description = "Not found", body = ApiResponse), ), tag = "Git" )] pub async fn git_branch_tracking_difference( service: web::Data, session: Session, path: web::Path<(String, String, String)>, ) -> Result { let (namespace, repo_name, name) = path.into_inner(); let resp = service .git_branch_tracking_difference(namespace, repo_name, name, &session) .await?; Ok(ApiResponse::ok(resp).to_response()) } #[utoipa::path( post, path = "/api/repos/{namespace}/{repo}/git/branches", request_body = BranchCreateRequest, params( ("namespace" = String, Path, description = "Project namespace"), ("repo" = String, Path, description = "Repository name"), ), responses( (status = 401, description = "Unauthorized", body = ApiResponse), (status = 200, description = "Create branch", body = ApiResponse), (status = 404, description = "Not found", body = ApiResponse), ), tag = "Git" )] pub async fn git_branch_create( service: web::Data, session: Session, path: web::Path<(String, String)>, body: web::Json, ) -> Result { let (namespace, repo_name) = path.into_inner(); let resp = service .git_branch_create(namespace, repo_name, body.into_inner(), &session) .await?; Ok(ApiResponse::ok(resp).to_response()) } #[utoipa::path( delete, path = "/api/repos/{namespace}/{repo}/git/branches/{name}", params( ("namespace" = String, Path, description = "Project namespace"), ("repo" = String, Path, description = "Repository name"), ("name" = String, Path, description = "Branch name"), ), responses( (status = 401, description = "Unauthorized", body = ApiResponse), (status = 200, description = "Delete branch"), (status = 404, description = "Not found", body = ApiResponse), ), tag = "Git" )] pub async fn git_branch_delete( service: web::Data, session: Session, path: web::Path<(String, String, String)>, ) -> Result { let (namespace, repo_name, name) = path.into_inner(); service .git_branch_delete(namespace, repo_name, name, &session) .await?; Ok(HttpResponse::Ok().json(serde_json::json!({ "success": true }))) } #[utoipa::path( delete, path = "/api/repos/{namespace}/{repo}/git/branches/remote/{name}", params( ("namespace" = String, Path, description = "Project namespace"), ("repo" = String, Path, description = "Repository name"), ("name" = String, Path, description = "Remote branch name"), ), responses( (status = 401, description = "Unauthorized", body = ApiResponse), (status = 200, description = "Delete remote branch"), (status = 404, description = "Not found", body = ApiResponse), ), tag = "Git" )] pub async fn git_branch_delete_remote( service: web::Data, session: Session, path: web::Path<(String, String, String)>, ) -> Result { let (namespace, repo_name, name) = path.into_inner(); service .git_branch_delete_remote(namespace, repo_name, name, &session) .await?; Ok(HttpResponse::Ok().json(serde_json::json!({ "success": true }))) } #[utoipa::path( patch, path = "/api/repos/{namespace}/{repo}/git/branches/rename", request_body = BranchRenameRequest, params( ("namespace" = String, Path, description = "Project namespace"), ("repo" = String, Path, description = "Repository name"), ), responses( (status = 401, description = "Unauthorized", body = ApiResponse), (status = 200, description = "Rename branch", body = ApiResponse), (status = 404, description = "Not found", body = ApiResponse), ), tag = "Git" )] pub async fn git_branch_rename( service: web::Data, session: Session, path: web::Path<(String, String)>, body: web::Json, ) -> Result { let (namespace, repo_name) = path.into_inner(); let resp = service .git_branch_rename(namespace, repo_name, body.into_inner(), &session) .await?; Ok(ApiResponse::ok(resp).to_response()) } #[utoipa::path( patch, path = "/api/repos/{namespace}/{repo}/git/branches/move", request_body = BranchMoveRequest, params( ("namespace" = String, Path, description = "Project namespace"), ("repo" = String, Path, description = "Repository name"), ), responses( (status = 401, description = "Unauthorized", body = ApiResponse), (status = 200, description = "Move branch", body = ApiResponse), (status = 404, description = "Not found", body = ApiResponse), ), tag = "Git" )] pub async fn git_branch_move( service: web::Data, session: Session, path: web::Path<(String, String)>, body: web::Json, ) -> Result { let (namespace, repo_name) = path.into_inner(); let resp = service .git_branch_move(namespace, repo_name, body.into_inner(), &session) .await?; Ok(ApiResponse::ok(resp).to_response()) } #[utoipa::path( patch, path = "/api/repos/{namespace}/{repo}/git/branches/upstream", request_body = BranchSetUpstreamRequest, params( ("namespace" = String, Path, description = "Project namespace"), ("repo" = String, Path, description = "Repository name"), ), responses( (status = 401, description = "Unauthorized", body = ApiResponse), (status = 200, description = "Set upstream branch"), (status = 404, description = "Not found", body = ApiResponse), ), tag = "Git" )] pub async fn git_branch_set_upstream( service: web::Data, session: Session, path: web::Path<(String, String)>, body: web::Json, ) -> Result { let (namespace, repo_name) = path.into_inner(); service .git_branch_set_upstream(namespace, repo_name, body.into_inner(), &session) .await?; Ok(HttpResponse::Ok().json(serde_json::json!({ "success": true }))) } #[utoipa::path( get, path = "/api/repos/{namespace}/{repo}/git/branches/is-merged", params( ("namespace" = String, Path, description = "Project namespace"), ("repo" = String, Path, description = "Repository name"), ), responses( (status = 401, description = "Unauthorized", body = ApiResponse), (status = 200, description = "Check if branch is merged", body = ApiResponse), (status = 404, description = "Not found", body = ApiResponse), ), tag = "Git" )] pub async fn git_branch_is_merged( service: web::Data, session: Session, path: web::Path<(String, String)>, query: web::Query, ) -> Result { let (namespace, repo_name) = path.into_inner(); let resp = service .git_branch_is_merged(namespace, repo_name, query.into_inner(), &session) .await?; Ok(ApiResponse::ok(resp).to_response()) } #[utoipa::path( get, path = "/api/repos/{namespace}/{repo}/git/branches/merge-base", params( ("namespace" = String, Path, description = "Project namespace"), ("repo" = String, Path, description = "Repository name"), ), responses( (status = 401, description = "Unauthorized", body = ApiResponse), (status = 200, description = "Get merge base", body = ApiResponse), (status = 404, description = "Not found", body = ApiResponse), ), tag = "Git" )] pub async fn git_branch_merge_base( service: web::Data, session: Session, path: web::Path<(String, String)>, query: web::Query, ) -> Result { let (namespace, repo_name) = path.into_inner(); let resp = service .git_branch_merge_base(namespace, repo_name, query.into_inner(), &session) .await?; Ok(ApiResponse::ok(resp).to_response()) } #[utoipa::path( get, path = "/api/repos/{namespace}/{repo}/git/branches/is-ancestor", params( ("namespace" = String, Path, description = "Project namespace"), ("repo" = String, Path, description = "Repository name"), ), responses( (status = 401, description = "Unauthorized", body = ApiResponse), (status = 200, description = "Check if branch is ancestor", body = ApiResponse), (status = 404, description = "Not found", body = ApiResponse), ), tag = "Git" )] pub async fn git_branch_is_ancestor( service: web::Data, session: Session, path: web::Path<(String, String)>, query: web::Query, ) -> Result { let (namespace, repo_name) = path.into_inner(); let resp = service .git_branch_is_ancestor(namespace, repo_name, query.into_inner(), &session) .await?; Ok(ApiResponse::ok(resp).to_response()) } #[utoipa::path( post, path = "/api/repos/{namespace}/{repo}/git/branches/fast-forward/{target}", params( ("namespace" = String, Path, description = "Project namespace"), ("repo" = String, Path, description = "Repository name"), ("target" = String, Path, description = "Target branch name"), ), responses( (status = 401, description = "Unauthorized", body = ApiResponse), (status = 200, description = "Fast-forward branch", body = ApiResponse), (status = 404, description = "Not found", body = ApiResponse), ), tag = "Git" )] pub async fn git_branch_fast_forward( service: web::Data, session: Session, path: web::Path<(String, String, String)>, ) -> Result { let (namespace, repo_name, target) = path.into_inner(); let resp = service .git_branch_fast_forward(namespace, repo_name, target, None, &session) .await?; Ok(ApiResponse::ok(resp).to_response()) } #[utoipa::path( get, path = "/api/repos/{namespace}/{repo}/git/branches/is-conflicted", params( ("namespace" = String, Path, description = "Project namespace"), ("repo" = String, Path, description = "Repository name"), ), responses( (status = 401, description = "Unauthorized", body = ApiResponse), (status = 200, description = "Check if branch has conflicts", body = ApiResponse), (status = 404, description = "Not found", body = ApiResponse), ), tag = "Git" )] pub async fn git_branch_is_conflicted( service: web::Data, session: Session, path: web::Path<(String, String)>, ) -> Result { let (namespace, repo_name) = path.into_inner(); let resp = service .git_branch_is_conflicted(namespace, repo_name, &session) .await?; Ok(ApiResponse::ok(resp).to_response()) }