feat(api): expand API endpoints for repo, PR, user, workspace management
- Add git operation endpoints: archive, compare branches, diff, tree, repository extras - Add repo endpoints: contributors, delete fork, get branch/commit status/deploy key/invitation/member/release/tag/webhook, topics, release assets, webhook deliveries/retry - Add PR endpoints: review requests, templates - Add user endpoints: block/unblock, follow/unfollow, presence, personal access tokens, account restore - Add workspace endpoints: billing history, approvals, domains, integrations, invitations, members, webhooks, restore - Add internal API, notification API, IM API modules - Update route configuration and OpenAPI spec
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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 QueryParams {
|
||||
pub revision: String,
|
||||
pub path: String,
|
||||
pub page_size: Option<u32>,
|
||||
}
|
||||
|
||||
/// Blame a file
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/blame",
|
||||
tag = "Git",
|
||||
operation_id = "gitBlame",
|
||||
params(PathParams, QueryParams),
|
||||
responses(
|
||||
(status = 200, description = "Blame retrieved successfully", body = ApiResponse<crate::pb::repo::BlameResponse>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 500, description = "Internal server error", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_blame(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
query: web::Query<QueryParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_blame(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
&query.revision,
|
||||
&query.path,
|
||||
query.page_size.unwrap_or(30),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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 QueryParams {
|
||||
pub revision: String,
|
||||
pub path: String,
|
||||
}
|
||||
|
||||
/// Get blob content
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/blobs",
|
||||
tag = "Git",
|
||||
operation_id = "gitGetBlob",
|
||||
params(PathParams, QueryParams),
|
||||
responses(
|
||||
(status = 200, description = "Blob retrieved successfully", body = ApiResponse<crate::pb::repo::Blob>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 404, description = "Blob not found", body = ApiErrorResponse),
|
||||
(status = 500, description = "Internal server error", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_blob(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
query: web::Query<QueryParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_get_blob(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
&query.revision,
|
||||
&query.path,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, ApiResponse};
|
||||
use crate::error::AppError;
|
||||
use crate::service::AppService;
|
||||
use crate::service::repo::git::merge::CherryPickParams;
|
||||
use crate::session::Session;
|
||||
|
||||
#[derive(Debug, Deserialize, IntoParams)]
|
||||
pub struct PathParams {
|
||||
pub workspace_name: String,
|
||||
pub repo_name: String,
|
||||
}
|
||||
|
||||
/// Cherry-pick a commit
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/cherry-pick",
|
||||
tag = "Git",
|
||||
operation_id = "gitCherryPick",
|
||||
params(PathParams),
|
||||
request_body(
|
||||
content = CherryPickParams,
|
||||
description = "Cherry-pick parameters",
|
||||
content_type = "application/json"
|
||||
),
|
||||
responses(
|
||||
(status = 200, description = "Cherry-pick completed successfully", body = ApiResponse<crate::pb::repo::CreateCommitResponse>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 409, description = "Cherry-pick conflict", body = ApiErrorResponse),
|
||||
(status = 500, description = "Internal server error", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_cherry_pick(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
params: web::Json<CherryPickParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_cherry_pick(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
params.into_inner(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
use crate::api::response::ApiResponse;
|
||||
use crate::error::AppError;
|
||||
use crate::service::AppService;
|
||||
use crate::session::Session;
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
#[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,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, IntoParams)]
|
||||
pub struct FindCommitQuery {
|
||||
pub revision: String,
|
||||
}
|
||||
#[utoipa::path(get, path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/find-commit", tag = "Git", operation_id = "gitFindCommit", params(PathParams, FindCommitQuery), responses((status=200,body=ApiResponse<crate::pb::repo::Commit>)), security(("session_cookie"=[])))]
|
||||
pub async fn git_find_commit(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
q: web::Query<FindCommitQuery>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let r = service
|
||||
.repo
|
||||
.git_find_commit(&session, &path.workspace_name, &path.repo_name, &q.revision)
|
||||
.await?;
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(r)))
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, utoipa::ToSchema)]
|
||||
pub struct ListCommitsByOidBody {
|
||||
pub oids: Vec<String>,
|
||||
}
|
||||
#[utoipa::path(post, path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/commits/by-oid", tag = "Git", operation_id = "gitCommitsByOid", params(PathParams), request_body(content=ListCommitsByOidBody), responses((status=200,body=ApiResponse<crate::pb::repo::ListCommitsByOidResponse>)), security(("session_cookie"=[])))]
|
||||
pub async fn git_commits_by_oid(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
body: web::Json<ListCommitsByOidBody>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let oids: Vec<Vec<u8>> = body
|
||||
.oids
|
||||
.iter()
|
||||
.map(|s| hex::decode(s).unwrap_or_default())
|
||||
.collect();
|
||||
let r = service
|
||||
.repo
|
||||
.git_list_commits_by_oid(&session, &path.workspace_name, &path.repo_name, oids)
|
||||
.await?;
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(r)))
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, IntoParams)]
|
||||
pub struct AncestorQuery {
|
||||
pub ancestor: String,
|
||||
pub descendant: String,
|
||||
}
|
||||
#[utoipa::path(get, path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/commit-is-ancestor", tag = "Git", operation_id = "gitCommitIsAncestor", params(PathParams, AncestorQuery), responses((status=200,body=ApiResponse<bool>)), security(("session_cookie"=[])))]
|
||||
pub async fn git_commit_is_ancestor(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
q: web::Query<AncestorQuery>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let r = service
|
||||
.repo
|
||||
.git_commit_is_ancestor(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
&q.ancestor,
|
||||
&q.descendant,
|
||||
)
|
||||
.await?;
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(r)))
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, IntoParams)]
|
||||
pub struct LastCommitQuery {
|
||||
pub path: String,
|
||||
pub revision: Option<String>,
|
||||
}
|
||||
#[utoipa::path(get, path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/last-commit", tag = "Git", operation_id = "gitLastCommitForPath", params(PathParams, LastCommitQuery), responses((status=200,body=ApiResponse<crate::pb::repo::LastCommitForPathResponse>)), security(("session_cookie"=[])))]
|
||||
pub async fn git_last_commit(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
q: web::Query<LastCommitQuery>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let r = service
|
||||
.repo
|
||||
.git_last_commit_for_path(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
&q.path,
|
||||
q.revision.as_deref(),
|
||||
)
|
||||
.await?;
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(r)))
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, IntoParams)]
|
||||
pub struct CommitsByMsgQuery {
|
||||
pub q: String,
|
||||
pub revision: Option<String>,
|
||||
pub limit: Option<u32>,
|
||||
}
|
||||
#[utoipa::path(get, path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/commits/search", tag = "Git", operation_id = "gitCommitsByMessage", params(PathParams, CommitsByMsgQuery), responses((status=200,body=ApiResponse<crate::pb::repo::CommitsByMessageResponse>)), security(("session_cookie"=[])))]
|
||||
pub async fn git_commits_by_message(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
q: web::Query<CommitsByMsgQuery>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let r = service
|
||||
.repo
|
||||
.git_commits_by_message(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
&q.q,
|
||||
q.revision.as_deref(),
|
||||
q.limit.unwrap_or(20),
|
||||
)
|
||||
.await?;
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(r)))
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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,
|
||||
pub revision: String,
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/commits/{revision}/stats",
|
||||
tag = "Git",
|
||||
operation_id = "gitCommitStats",
|
||||
params(PathParams),
|
||||
responses(
|
||||
(status = 200, description = "Commit stats", body = ApiResponse<crate::pb::repo::CommitStats>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 404, description = "Not found", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_commit_stats(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_commit_stats(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
&path.revision,
|
||||
)
|
||||
.await?;
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, ApiResponse};
|
||||
use crate::error::AppError;
|
||||
use crate::service::AppService;
|
||||
use crate::service::repo::git::merge::CompareParams;
|
||||
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 QueryParams {
|
||||
pub base: String,
|
||||
pub head: String,
|
||||
pub page_size: Option<u32>,
|
||||
}
|
||||
|
||||
/// Compare two commits
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/compare",
|
||||
tag = "Git",
|
||||
operation_id = "gitCompare",
|
||||
params(PathParams, QueryParams),
|
||||
responses(
|
||||
(status = 200, description = "Comparison completed successfully", body = ApiResponse<crate::pb::repo::CompareCommitsResponse>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 500, description = "Internal server error", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_compare(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
query: web::Query<QueryParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_compare_commits(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
CompareParams {
|
||||
base: query.base.clone(),
|
||||
head: query.head.clone(),
|
||||
page_size: query.page_size,
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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 QueryParams {
|
||||
pub target: String,
|
||||
pub source: String,
|
||||
pub page_size: Option<u32>,
|
||||
}
|
||||
|
||||
/// List merge conflicts
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/conflicts",
|
||||
tag = "Git",
|
||||
operation_id = "gitListConflicts",
|
||||
params(PathParams, QueryParams),
|
||||
responses(
|
||||
(status = 200, description = "Conflicts listed successfully", body = ApiResponse<crate::pb::repo::ListMergeConflictsResponse>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 500, description = "Internal server error", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_conflicts(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
query: web::Query<QueryParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_list_conflicts(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
&query.target,
|
||||
&query.source,
|
||||
query.page_size.unwrap_or(30),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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 QueryParams {
|
||||
pub revision: Option<String>,
|
||||
pub path: Option<String>,
|
||||
pub since: Option<String>,
|
||||
pub until: Option<String>,
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/commits/count",
|
||||
tag = "Git",
|
||||
operation_id = "gitCountCommits",
|
||||
params(PathParams, QueryParams),
|
||||
responses(
|
||||
(status = 200, description = "Commit count", body = ApiResponse<crate::pb::repo::CountCommitsResponse>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 404, description = "Not found", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_count_commits(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
query: web::Query<QueryParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_count_commits(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
query.revision.as_deref(),
|
||||
query.path.as_deref(),
|
||||
query.since.as_deref(),
|
||||
query.until.as_deref(),
|
||||
)
|
||||
.await?;
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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 QueryParams {
|
||||
pub left: String,
|
||||
pub right: String,
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/compare/diverging",
|
||||
tag = "Git",
|
||||
operation_id = "gitCountDivergingCommits",
|
||||
params(PathParams, QueryParams),
|
||||
responses(
|
||||
(status = 200, description = "Diverging commit counts", body = ApiResponse<crate::pb::repo::CountDivergingCommitsResponse>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 404, description = "Not found", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_count_diverging(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
query: web::Query<QueryParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_count_diverging_commits(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
&query.left,
|
||||
&query.right,
|
||||
)
|
||||
.await?;
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::{IntoParams, ToSchema};
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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, ToSchema)]
|
||||
pub struct CreateBranchBody {
|
||||
pub branch_name: String,
|
||||
pub start_point: String,
|
||||
}
|
||||
|
||||
/// Create a branch
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/branches",
|
||||
tag = "Git",
|
||||
operation_id = "gitCreateBranch",
|
||||
params(PathParams),
|
||||
request_body(
|
||||
content = CreateBranchBody,
|
||||
description = "Branch creation parameters",
|
||||
content_type = "application/json"
|
||||
),
|
||||
responses(
|
||||
(status = 201, description = "Branch created successfully", body = ApiResponse<crate::pb::repo::Branch>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 500, description = "Internal server error", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_create_branch(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
body: web::Json<CreateBranchBody>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_create_branch(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
&body.branch_name,
|
||||
&body.start_point,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Created().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, ApiResponse};
|
||||
use crate::error::AppError;
|
||||
use crate::service::AppService;
|
||||
use crate::service::repo::git::merge::CreateCommitParams;
|
||||
use crate::session::Session;
|
||||
|
||||
#[derive(Debug, Deserialize, IntoParams)]
|
||||
pub struct PathParams {
|
||||
pub workspace_name: String,
|
||||
pub repo_name: String,
|
||||
}
|
||||
|
||||
/// Create a commit
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/commits",
|
||||
tag = "Git",
|
||||
operation_id = "gitCreateCommit",
|
||||
params(PathParams),
|
||||
request_body(
|
||||
content = CreateCommitParams,
|
||||
description = "Commit creation parameters",
|
||||
content_type = "application/json"
|
||||
),
|
||||
responses(
|
||||
(status = 201, description = "Commit created successfully", body = ApiResponse<crate::pb::repo::CreateCommitResponse>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 500, description = "Internal server error", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_create_commit(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
params: web::Json<CreateCommitParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_create_commit(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
params.into_inner(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Created().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::{IntoParams, ToSchema};
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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, ToSchema)]
|
||||
pub struct CreateTagBody {
|
||||
pub tag_name: String,
|
||||
pub target: String,
|
||||
pub message: Option<String>,
|
||||
pub annotated: Option<bool>,
|
||||
}
|
||||
|
||||
/// Create a tag
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/tags",
|
||||
tag = "Git",
|
||||
operation_id = "gitCreateTag",
|
||||
params(PathParams),
|
||||
request_body(
|
||||
content = CreateTagBody,
|
||||
description = "Tag creation parameters",
|
||||
content_type = "application/json"
|
||||
),
|
||||
responses(
|
||||
(status = 201, description = "Tag created successfully", body = ApiResponse<crate::pb::repo::Tag>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 500, description = "Internal server error", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_create_tag(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
body: web::Json<CreateTagBody>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_create_tag(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
&body.tag_name,
|
||||
&body.target,
|
||||
body.message.clone(),
|
||||
body.annotated.unwrap_or(false),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Created().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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,
|
||||
pub branch_name: String,
|
||||
}
|
||||
|
||||
/// Delete a branch
|
||||
#[utoipa::path(
|
||||
delete,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/branches/{branch_name}",
|
||||
tag = "Git",
|
||||
operation_id = "gitDeleteBranch",
|
||||
params(PathParams),
|
||||
responses(
|
||||
(status = 200, description = "Branch deleted successfully", body = ApiResponse<String>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 500, description = "Internal server error", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_delete_branch(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
service
|
||||
.repo
|
||||
.git_delete_branch(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
&path.branch_name,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new("Branch deleted successfully".to_string())))
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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,
|
||||
pub tag_name: String,
|
||||
}
|
||||
|
||||
/// Delete a tag
|
||||
#[utoipa::path(
|
||||
delete,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/tags/{tag_name}",
|
||||
tag = "Git",
|
||||
operation_id = "gitDeleteTag",
|
||||
params(PathParams),
|
||||
responses(
|
||||
(status = 200, description = "Tag deleted successfully", body = ApiResponse<String>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 500, description = "Internal server error", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_delete_tag(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
service
|
||||
.repo
|
||||
.git_delete_tag(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
&path.tag_name,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new("Tag deleted successfully".to_string())))
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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 QueryParams {
|
||||
pub base: String,
|
||||
pub head: String,
|
||||
pub page_size: Option<u32>,
|
||||
}
|
||||
|
||||
/// Get diff between two revisions
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/diff",
|
||||
tag = "Git",
|
||||
operation_id = "gitDiff",
|
||||
params(PathParams, QueryParams),
|
||||
responses(
|
||||
(status = 200, description = "Diff retrieved successfully", body = ApiResponse<crate::pb::repo::GetDiffResponse>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 500, description = "Internal server error", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_diff(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
query: web::Query<QueryParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_diff(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
&query.base,
|
||||
&query.head,
|
||||
query.page_size.unwrap_or(30),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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 QueryParams {
|
||||
pub base: String,
|
||||
pub head: String,
|
||||
}
|
||||
|
||||
/// Get diff statistics between two revisions
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/diff-stats",
|
||||
tag = "Git",
|
||||
operation_id = "gitDiffStats",
|
||||
params(PathParams, QueryParams),
|
||||
responses(
|
||||
(status = 200, description = "Diff stats retrieved successfully", body = ApiResponse<crate::pb::repo::DiffStats>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 500, description = "Internal server error", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_diff_stats(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
query: web::Query<QueryParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_diff_stats(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
&query.base,
|
||||
&query.head,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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,
|
||||
}
|
||||
|
||||
/// Check if repository exists
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/exists",
|
||||
tag = "Git",
|
||||
operation_id = "gitRepoExists",
|
||||
params(PathParams),
|
||||
responses(
|
||||
(status = 200, description = "Repository existence check completed", body = ApiResponse<bool>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 500, description = "Internal server error", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_exists(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_repo_exists(&session, &path.workspace_name, &path.repo_name)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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,
|
||||
}
|
||||
|
||||
/// Run garbage collection
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/garbage-collect",
|
||||
tag = "Git",
|
||||
operation_id = "gitGarbageCollect",
|
||||
params(PathParams),
|
||||
responses(
|
||||
(status = 200, description = "Garbage collection completed", body = ApiResponse<crate::pb::repo::RepositoryMaintenanceResponse>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 500, description = "Internal server error", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_gc(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_garbage_collect(&session, &path.workspace_name, &path.repo_name)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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,
|
||||
pub branch_name: String,
|
||||
}
|
||||
|
||||
/// Get a branch
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/branches/{branch_name}",
|
||||
tag = "Git",
|
||||
operation_id = "gitGetBranch",
|
||||
params(PathParams),
|
||||
responses(
|
||||
(status = 200, description = "Branch retrieved successfully", body = ApiResponse<crate::pb::repo::Branch>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 404, description = "Branch not found", body = ApiErrorResponse),
|
||||
(status = 500, description = "Internal server error", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_get_branch(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_get_branch(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
&path.branch_name,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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,
|
||||
pub revision: String,
|
||||
}
|
||||
|
||||
/// Get a single commit
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/commits/{revision}",
|
||||
tag = "Git",
|
||||
operation_id = "gitGetCommit",
|
||||
params(PathParams),
|
||||
responses(
|
||||
(status = 200, description = "Commit retrieved successfully", body = ApiResponse<crate::pb::repo::Commit>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 404, description = "Commit not found", body = ApiErrorResponse),
|
||||
(status = 500, description = "Internal server error", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_get_commit(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_get_commit(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
&path.revision,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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,
|
||||
pub tag_name: String,
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/tags/{tag_name}",
|
||||
tag = "Git",
|
||||
operation_id = "gitGetTag",
|
||||
params(PathParams),
|
||||
responses(
|
||||
(status = 200, description = "Tag details", body = ApiResponse<crate::pb::repo::Tag>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 404, description = "Not found", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_get_tag(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_get_tag(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
&path.tag_name,
|
||||
)
|
||||
.await?;
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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,
|
||||
}
|
||||
|
||||
/// Check repository health
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/health",
|
||||
tag = "Git",
|
||||
operation_id = "gitRepoHealth",
|
||||
params(PathParams),
|
||||
responses(
|
||||
(status = 200, description = "Repository health check completed", body = ApiResponse<crate::pb::repo::RepositoryHealthResponse>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 500, description = "Internal server error", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_health(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_repo_health(&session, &path.workspace_name, &path.repo_name)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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,
|
||||
}
|
||||
|
||||
/// Get repository info
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/info",
|
||||
tag = "Git",
|
||||
operation_id = "gitRepoInfo",
|
||||
params(PathParams),
|
||||
responses(
|
||||
(status = 200, description = "Repository info retrieved successfully", body = ApiResponse<crate::pb::repo::Repository>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 500, description = "Internal server error", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_info(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_repo_info(&session, &path.workspace_name, &path.repo_name)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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,
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/license",
|
||||
tag = "Git",
|
||||
operation_id = "gitLicense",
|
||||
params(PathParams),
|
||||
responses(
|
||||
(status = 200, description = "License detection result", body = ApiResponse<crate::pb::repo::FindLicenseResponse>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 404, description = "Not found", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_license(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_find_license(&session, &path.workspace_name, &path.repo_name)
|
||||
.await?;
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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 QueryParams {
|
||||
pub pattern: Option<String>,
|
||||
pub page_size: Option<u32>,
|
||||
pub page_token: Option<String>,
|
||||
}
|
||||
|
||||
/// List branches
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/branches",
|
||||
tag = "Git",
|
||||
operation_id = "gitListBranches",
|
||||
params(PathParams, QueryParams),
|
||||
responses(
|
||||
(status = 200, description = "Branches listed successfully", body = ApiResponse<crate::pb::repo::ListBranchesResponse>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 500, description = "Internal server error", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_list_branches(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
query: web::Query<QueryParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_list_branches(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
query.pattern.clone(),
|
||||
query.page_size.unwrap_or(30),
|
||||
query.page_token.clone(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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 QueryParams {
|
||||
pub revision: String,
|
||||
pub path: Option<String>,
|
||||
pub page_size: Option<u32>,
|
||||
}
|
||||
|
||||
/// List commits
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/commits",
|
||||
tag = "Git",
|
||||
operation_id = "gitListCommits",
|
||||
params(PathParams, QueryParams),
|
||||
responses(
|
||||
(status = 200, description = "Commits listed successfully", body = ApiResponse<crate::pb::repo::ListCommitsResponse>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 500, description = "Internal server error", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_list_commits(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
query: web::Query<QueryParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_list_commits(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
&query.revision,
|
||||
query.path.clone(),
|
||||
query.page_size.unwrap_or(30),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, ApiResponse};
|
||||
use crate::error::AppError;
|
||||
use crate::service::AppService;
|
||||
use crate::service::repo::git::merge::MergeParams;
|
||||
use crate::session::Session;
|
||||
|
||||
#[derive(Debug, Deserialize, IntoParams)]
|
||||
pub struct PathParams {
|
||||
pub workspace_name: String,
|
||||
pub repo_name: String,
|
||||
}
|
||||
|
||||
/// Merge branches
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/merge",
|
||||
tag = "Git",
|
||||
operation_id = "gitMerge",
|
||||
params(PathParams),
|
||||
request_body(
|
||||
content = MergeParams,
|
||||
description = "Merge parameters",
|
||||
content_type = "application/json"
|
||||
),
|
||||
responses(
|
||||
(status = 200, description = "Merge completed successfully", body = ApiResponse<crate::pb::repo::MergeResult>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 409, description = "Merge conflict", body = ApiErrorResponse),
|
||||
(status = 500, description = "Internal server error", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_merge(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
params: web::Json<MergeParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_merge(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
params.into_inner(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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 QueryParams {
|
||||
pub target: String,
|
||||
pub source: String,
|
||||
}
|
||||
|
||||
/// Check if a merge is possible
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/merge-check",
|
||||
tag = "Git",
|
||||
operation_id = "gitMergeCheck",
|
||||
params(PathParams, QueryParams),
|
||||
responses(
|
||||
(status = 200, description = "Merge check completed successfully", body = ApiResponse<crate::pb::repo::MergeResult>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 500, description = "Internal server error", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_merge_check(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
query: web::Query<QueryParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_check_merge(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
&query.target,
|
||||
&query.source,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, ApiResponse};
|
||||
use crate::error::AppError;
|
||||
use crate::service::AppService;
|
||||
use crate::service::repo::git::merge::RebaseParams;
|
||||
use crate::session::Session;
|
||||
|
||||
#[derive(Debug, Deserialize, IntoParams)]
|
||||
pub struct PathParams {
|
||||
pub workspace_name: String,
|
||||
pub repo_name: String,
|
||||
}
|
||||
|
||||
/// Rebase a branch
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/rebase",
|
||||
tag = "Git",
|
||||
operation_id = "gitRebase",
|
||||
params(PathParams),
|
||||
request_body(
|
||||
content = RebaseParams,
|
||||
description = "Rebase parameters",
|
||||
content_type = "application/json"
|
||||
),
|
||||
responses(
|
||||
(status = 200, description = "Rebase completed successfully", body = ApiResponse<crate::pb::repo::RebaseResult>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 409, description = "Rebase conflict", body = ApiErrorResponse),
|
||||
(status = 500, description = "Internal server error", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_rebase(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
params: web::Json<RebaseParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_rebase(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
params.into_inner(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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,
|
||||
pub branch_name: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, utoipa::ToSchema)]
|
||||
pub struct RenameBody {
|
||||
pub new_name: String,
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/branches/{branch_name}/rename",
|
||||
tag = "Git",
|
||||
operation_id = "gitRenameBranch",
|
||||
params(PathParams),
|
||||
request_body(content = RenameBody),
|
||||
responses(
|
||||
(status = 200, description = "Branch renamed", body = ApiResponse<crate::pb::repo::Branch>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 404, description = "Not found", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_rename_branch(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
body: web::Json<RenameBody>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_rename_branch(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
&path.branch_name,
|
||||
&body.new_name,
|
||||
)
|
||||
.await?;
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, ApiResponse};
|
||||
use crate::error::AppError;
|
||||
use crate::service::AppService;
|
||||
use crate::service::repo::git::merge::RevertParams;
|
||||
use crate::session::Session;
|
||||
|
||||
#[derive(Debug, Deserialize, IntoParams)]
|
||||
pub struct PathParams {
|
||||
pub workspace_name: String,
|
||||
pub repo_name: String,
|
||||
}
|
||||
|
||||
/// Revert a commit
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/revert",
|
||||
tag = "Git",
|
||||
operation_id = "gitRevert",
|
||||
params(PathParams),
|
||||
request_body(
|
||||
content = RevertParams,
|
||||
description = "Revert parameters",
|
||||
content_type = "application/json"
|
||||
),
|
||||
responses(
|
||||
(status = 200, description = "Revert completed successfully", body = ApiResponse<crate::pb::repo::CreateCommitResponse>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 500, description = "Internal server error", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_revert(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
params: web::Json<RevertParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_revert(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
params.into_inner(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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 SearchQueryParams {
|
||||
pub q: String,
|
||||
pub revision: Option<String>,
|
||||
pub max_results: Option<u32>,
|
||||
pub case_sensitive: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, IntoParams)]
|
||||
pub struct SearchFilesQueryParams {
|
||||
pub q: String,
|
||||
pub revision: Option<String>,
|
||||
pub max_results: Option<u32>,
|
||||
pub recursive: Option<bool>,
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/search/content",
|
||||
tag = "Git",
|
||||
operation_id = "gitSearchContent",
|
||||
params(PathParams, SearchQueryParams),
|
||||
responses(
|
||||
(status = 200, description = "Search results", body = ApiResponse<crate::pb::repo::SearchFilesByContentResponse>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 404, description = "Not found", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_search_content(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
query: web::Query<SearchQueryParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_search_content(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
&query.q,
|
||||
query.revision.as_deref(),
|
||||
query.max_results.unwrap_or(100),
|
||||
query.case_sensitive.unwrap_or(false),
|
||||
)
|
||||
.await?;
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/search/files",
|
||||
tag = "Git",
|
||||
operation_id = "gitSearchFiles",
|
||||
params(PathParams, SearchFilesQueryParams),
|
||||
responses(
|
||||
(status = 200, description = "File search results", body = ApiResponse<crate::pb::repo::SearchFilesByNameResponse>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 404, description = "Not found", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_search_files(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
query: web::Query<SearchFilesQueryParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_search_files(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
&query.q,
|
||||
query.revision.as_deref(),
|
||||
query.max_results.unwrap_or(100),
|
||||
query.recursive.unwrap_or(true),
|
||||
)
|
||||
.await?;
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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,
|
||||
}
|
||||
|
||||
/// Get repository statistics
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/stats",
|
||||
tag = "Git",
|
||||
operation_id = "gitRepoStats",
|
||||
params(PathParams),
|
||||
responses(
|
||||
(status = 200, description = "Repository statistics retrieved successfully", body = ApiResponse<crate::pb::repo::RepositoryStatistics>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 500, description = "Internal server error", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_stats(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_repo_stats(&session, &path.workspace_name, &path.repo_name)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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 QueryParams {
|
||||
pub pattern: Option<String>,
|
||||
pub page_size: Option<u32>,
|
||||
}
|
||||
|
||||
/// List tags
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/tags",
|
||||
tag = "Git",
|
||||
operation_id = "gitListTags",
|
||||
params(PathParams, QueryParams),
|
||||
responses(
|
||||
(status = 200, description = "Tags listed successfully", body = ApiResponse<crate::pb::repo::ListTagsResponse>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 500, description = "Internal server error", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_tags(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
query: web::Query<QueryParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_list_tags(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
query.pattern.clone(),
|
||||
query.page_size.unwrap_or(30),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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 QueryParams {
|
||||
pub revision: String,
|
||||
pub path: Option<String>,
|
||||
pub recursive: Option<bool>,
|
||||
pub page_size: Option<u32>,
|
||||
}
|
||||
|
||||
/// List tree contents
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/tree",
|
||||
tag = "Git",
|
||||
operation_id = "gitListTree",
|
||||
params(PathParams, QueryParams),
|
||||
responses(
|
||||
(status = 200, description = "Tree listed successfully", body = ApiResponse<crate::pb::repo::ListTreeResponse>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 500, description = "Internal server error", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_tree(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
query: web::Query<QueryParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_list_tree(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
&query.revision,
|
||||
query.path.clone(),
|
||||
query.recursive.unwrap_or(false),
|
||||
query.page_size.unwrap_or(30),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
use actix_web::{HttpResponse, web};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::api::response::{ApiErrorResponse, 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,
|
||||
pub tag_name: String,
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/api/v1/workspaces/{workspace_name}/repos/{repo_name}/git/tags/{tag_name}/verify",
|
||||
tag = "Git",
|
||||
operation_id = "gitVerifyTag",
|
||||
params(PathParams),
|
||||
responses(
|
||||
(status = 200, description = "Tag signature verification result", body = ApiResponse<crate::pb::repo::VerifiedSignature>),
|
||||
(status = 401, description = "Unauthorized", body = ApiErrorResponse),
|
||||
(status = 404, description = "Not found", body = ApiErrorResponse),
|
||||
),
|
||||
security(("session_cookie" = []))
|
||||
)]
|
||||
pub async fn git_verify_tag(
|
||||
service: web::Data<AppService>,
|
||||
session: Session,
|
||||
path: web::Path<PathParams>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
let result = service
|
||||
.repo
|
||||
.git_verify_tag(
|
||||
&session,
|
||||
&path.workspace_name,
|
||||
&path.repo_name,
|
||||
&path.tag_name,
|
||||
)
|
||||
.await?;
|
||||
Ok(HttpResponse::Ok().json(ApiResponse::new(result)))
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
pub mod git_archive;
|
||||
pub mod git_blame;
|
||||
pub mod git_blob;
|
||||
pub mod git_cherry_pick;
|
||||
pub mod git_commit_extras2;
|
||||
pub mod git_commit_stats;
|
||||
pub mod git_compare;
|
||||
pub mod git_compare_branch;
|
||||
pub mod git_conflicts;
|
||||
pub mod git_count_commits;
|
||||
pub mod git_count_diverging;
|
||||
pub mod git_create_branch;
|
||||
pub mod git_create_commit;
|
||||
pub mod git_create_tag;
|
||||
pub mod git_delete_branch;
|
||||
pub mod git_delete_tag;
|
||||
pub mod git_diff;
|
||||
pub mod git_diff_extras;
|
||||
pub mod git_diff_stats;
|
||||
pub mod git_exists;
|
||||
pub mod git_gc;
|
||||
pub mod git_get_branch;
|
||||
pub mod git_get_commit;
|
||||
pub mod git_get_tag;
|
||||
pub mod git_health;
|
||||
pub mod git_info;
|
||||
pub mod git_license;
|
||||
pub mod git_list_branches;
|
||||
pub mod git_list_commits;
|
||||
pub mod git_merge;
|
||||
pub mod git_merge_check;
|
||||
pub mod git_rebase;
|
||||
pub mod git_rename_branch;
|
||||
pub mod git_repository_extras;
|
||||
pub mod git_revert;
|
||||
pub mod git_search;
|
||||
pub mod git_stats;
|
||||
pub mod git_tags;
|
||||
pub mod git_tree;
|
||||
pub mod git_tree_extras;
|
||||
pub mod git_verify_tag;
|
||||
|
||||
use actix_web::web;
|
||||
|
||||
pub fn configure(cfg: &mut web::ServiceConfig) {
|
||||
cfg.service(
|
||||
web::scope("/git")
|
||||
.route(
|
||||
"/commits",
|
||||
web::get().to(git_list_commits::git_list_commits),
|
||||
)
|
||||
.route(
|
||||
"/commits/{revision}",
|
||||
web::get().to(git_get_commit::git_get_commit),
|
||||
)
|
||||
.route(
|
||||
"/commits/{revision}/stats",
|
||||
web::get().to(git_commit_stats::git_commit_stats),
|
||||
)
|
||||
.route(
|
||||
"/commits",
|
||||
web::post().to(git_create_commit::git_create_commit),
|
||||
)
|
||||
.route(
|
||||
"/commits/count",
|
||||
web::get().to(git_count_commits::git_count_commits),
|
||||
)
|
||||
.route("/diff", web::get().to(git_diff::git_diff))
|
||||
.route("/diff-stats", web::get().to(git_diff_stats::git_diff_stats))
|
||||
.route("/compare", web::get().to(git_compare::git_compare))
|
||||
.route(
|
||||
"/compare/diverging",
|
||||
web::get().to(git_count_diverging::git_count_diverging),
|
||||
)
|
||||
.route("/archive", web::get().to(git_archive::git_archive))
|
||||
.route("/license", web::get().to(git_license::git_license))
|
||||
.route(
|
||||
"/search/content",
|
||||
web::get().to(git_search::git_search_content),
|
||||
)
|
||||
.route("/search/files", web::get().to(git_search::git_search_files))
|
||||
.route(
|
||||
"/branches",
|
||||
web::get().to(git_list_branches::git_list_branches),
|
||||
)
|
||||
.route(
|
||||
"/branches/{branch_name}",
|
||||
web::get().to(git_get_branch::git_get_branch),
|
||||
)
|
||||
.route(
|
||||
"/branches/{branch_name}/compare",
|
||||
web::get().to(git_compare_branch::git_compare_branch),
|
||||
)
|
||||
.route(
|
||||
"/branches/{branch_name}/rename",
|
||||
web::post().to(git_rename_branch::git_rename_branch),
|
||||
)
|
||||
.route(
|
||||
"/branches",
|
||||
web::post().to(git_create_branch::git_create_branch),
|
||||
)
|
||||
.route(
|
||||
"/branches/{branch_name}",
|
||||
web::delete().to(git_delete_branch::git_delete_branch),
|
||||
)
|
||||
.route(
|
||||
"/merge-check",
|
||||
web::get().to(git_merge_check::git_merge_check),
|
||||
)
|
||||
.route("/merge", web::post().to(git_merge::git_merge))
|
||||
.route("/rebase", web::post().to(git_rebase::git_rebase))
|
||||
.route(
|
||||
"/cherry-pick",
|
||||
web::post().to(git_cherry_pick::git_cherry_pick),
|
||||
)
|
||||
.route("/revert", web::post().to(git_revert::git_revert))
|
||||
.route("/conflicts", web::get().to(git_conflicts::git_conflicts))
|
||||
.route("/tree", web::get().to(git_tree::git_tree))
|
||||
.route("/blobs", web::get().to(git_blob::git_blob))
|
||||
.route("/blame", web::get().to(git_blame::git_blame))
|
||||
.route("/tags", web::get().to(git_tags::git_tags))
|
||||
.route("/tags", web::post().to(git_create_tag::git_create_tag))
|
||||
.route("/tags/{tag_name}", web::get().to(git_get_tag::git_get_tag))
|
||||
.route(
|
||||
"/tags/{tag_name}/verify",
|
||||
web::post().to(git_verify_tag::git_verify_tag),
|
||||
)
|
||||
.route(
|
||||
"/tags/{tag_name}",
|
||||
web::delete().to(git_delete_tag::git_delete_tag),
|
||||
)
|
||||
.route("/info", web::get().to(git_info::git_info))
|
||||
.route("/exists", web::get().to(git_exists::git_exists))
|
||||
.route("/stats", web::get().to(git_stats::git_stats))
|
||||
.route("/health", web::get().to(git_health::git_health))
|
||||
.route("/garbage-collect", web::post().to(git_gc::git_gc))
|
||||
.route(
|
||||
"/default-branch",
|
||||
web::get().to(git_repository_extras::git_default_branch),
|
||||
)
|
||||
.route(
|
||||
"/object-format",
|
||||
web::get().to(git_repository_extras::git_object_format),
|
||||
)
|
||||
.route(
|
||||
"/size",
|
||||
web::get().to(git_repository_extras::git_repository_size),
|
||||
)
|
||||
.route(
|
||||
"/objects-size",
|
||||
web::post().to(git_repository_extras::git_objects_size),
|
||||
)
|
||||
.route(
|
||||
"/check-objects",
|
||||
web::post().to(git_repository_extras::git_check_objects),
|
||||
)
|
||||
.route(
|
||||
"/merge-base",
|
||||
web::get().to(git_repository_extras::git_merge_base),
|
||||
)
|
||||
.route(
|
||||
"/archive/entries",
|
||||
web::get().to(git_repository_extras::git_archive_entries),
|
||||
)
|
||||
.route(
|
||||
"/commits/{revision}/ancestors",
|
||||
web::get().to(git_repository_extras::git_commit_ancestors),
|
||||
)
|
||||
.route(
|
||||
"/find-commit",
|
||||
web::get().to(git_commit_extras2::git_find_commit),
|
||||
)
|
||||
.route(
|
||||
"/commits/by-oid",
|
||||
web::post().to(git_commit_extras2::git_commits_by_oid),
|
||||
)
|
||||
.route(
|
||||
"/commit-is-ancestor",
|
||||
web::get().to(git_commit_extras2::git_commit_is_ancestor),
|
||||
)
|
||||
.route(
|
||||
"/last-commit",
|
||||
web::get().to(git_commit_extras2::git_last_commit),
|
||||
)
|
||||
.route(
|
||||
"/commits/search",
|
||||
web::get().to(git_commit_extras2::git_commits_by_message),
|
||||
)
|
||||
.route("/raw-blob", web::get().to(git_tree_extras::git_raw_blob))
|
||||
.route(
|
||||
"/file-metadata",
|
||||
web::get().to(git_tree_extras::git_file_metadata),
|
||||
)
|
||||
.route(
|
||||
"/find-files",
|
||||
web::get().to(git_tree_extras::git_find_files),
|
||||
)
|
||||
.route("/get-tree", web::get().to(git_tree_extras::git_get_tree))
|
||||
.route(
|
||||
"/commit-diff/{revision}",
|
||||
web::get().to(git_diff_extras::git_commit_diff),
|
||||
)
|
||||
.route("/patch", web::get().to(git_diff_extras::git_patch))
|
||||
.route("/raw-diff", web::get().to(git_diff_extras::git_raw_diff))
|
||||
.route(
|
||||
"/changed-paths",
|
||||
web::get().to(git_diff_extras::git_changed_paths),
|
||||
)
|
||||
.route(
|
||||
"/stream-blame",
|
||||
web::get().to(git_diff_extras::git_stream_blame),
|
||||
)
|
||||
.route(
|
||||
"/resolve-conflicts",
|
||||
web::post().to(git_diff_extras::git_resolve_conflicts),
|
||||
),
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user