From d9ca75a38b090142dae51efa966fa156b18b75c7 Mon Sep 17 00:00:00 2001 From: jiahao6635 Date: Mon, 22 Jan 2024 01:27:45 +0800 Subject: [PATCH 1/5] folder get return Vec,add folder tree --- Cargo.lock | 8 ++++---- Cargo.toml | 4 ++-- src/handlers/folder.rs | 28 +++++++++++++++++++++++++--- src/routes.rs | 1 + src/services/folder.rs | 25 ++++++++++++++++--------- src/swagger.rs | 2 ++ 6 files changed, 50 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ff39e49..5007f7e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -62,8 +62,8 @@ checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "amp-client" -version = "0.7.4" -source = "git+https://github.com/amphitheatre-app/amp-client-rust?tag=v0.7.4#44813d305ffed8951dad053327d56538fca96bb3" +version = "0.7.6" +source = "git+https://github.com/amphitheatre-app/amp-client-rust?tag=v0.7.6#082f4db7d0668b8249e1cb7f3e744149711e9ee3" dependencies = [ "amp-common", "futures", @@ -75,8 +75,8 @@ dependencies = [ [[package]] name = "amp-common" -version = "0.7.4" -source = "git+https://github.com/amphitheatre-app/common?tag=v0.7.4#d4f8b4b6cfee8766a2d19bcc96291d09db6d0228" +version = "0.7.7" +source = "git+https://github.com/amphitheatre-app/common?tag=v0.7.7#663f18822f1a3cad634ef38396698c9add0e2f22" dependencies = [ "anyhow", "chrono", diff --git a/Cargo.toml b/Cargo.toml index cfc6148..0591e40 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,8 +14,8 @@ name = "playground" path = "src/lib.rs" [dependencies] -amp-client = { git = "https://github.com/amphitheatre-app/amp-client-rust", tag = "v0.7.4" } -amp-common = { git = "https://github.com/amphitheatre-app/common", tag = "v0.7.4" } +amp-client = { git = "https://github.com/amphitheatre-app/amp-client-rust", tag = "v0.7.6" } +amp-common = { git = "https://github.com/amphitheatre-app/common", tag = "v0.7.7" } anyhow = "1.0" axum = { version = "0.7.4" } clap = { version = "4.4.12", features = ["derive", "env"] } diff --git a/src/handlers/folder.rs b/src/handlers/folder.rs index 8b308f2..5126894 100644 --- a/src/handlers/folder.rs +++ b/src/handlers/folder.rs @@ -28,7 +28,7 @@ use crate::services::FolderService; // The Folders Service Handlers. -/// Returns a folder's tree. +/// Gets the file list of a directory in a repository. #[utoipa::path( get, path = "/v1/playbooks/{id}/folders/{reference}/{path}", params( @@ -37,7 +37,7 @@ use crate::services::FolderService; ("path" = String, description = "The file path relative to the root of the repository."), ), responses( - (status = 200, description = "The folder tree", body = Tree), + (status = 200, description = "The folder tree", body = Vec), (status = 404, description = "Playbook not found"), (status = 404, description = "Folder not found"), (status = 500, description = "Internal Server Error"), @@ -47,9 +47,31 @@ use crate::services::FolderService; pub async fn get( State(ctx): State>, Path((id, reference, path)): Path<(Uuid, String, Option)>, +) -> Result { + Ok(Json(FolderService::get(ctx, id, reference, path).await?)) +} + +/// Returns a folder's tree. + +#[utoipa::path( + get, path = "/v1/playbooks/{id}/tree", + params( + ("id" = Uuid, description = "The id of playbook"), + ), + responses( + (status = 200, description = "The folder tree", body = Tree), + (status = 404, description = "Playbook not found"), + (status = 404, description = "Folder not found"), + (status = 500, description = "Internal Server Error"), + ), + tag = "Folders" +)] +pub async fn tree( + State(ctx): State>, + Path(id): Path, Query(params): Query>, ) -> Result { - Ok(Json(FolderService::get(ctx, id, reference, path, params.get("recursive")).await?)) + Ok(Json(FolderService::tree(ctx, id, params.get("recursive")).await?)) } /// Create a folder diff --git a/src/routes.rs b/src/routes.rs index ca84cbc..dc1441d 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -40,6 +40,7 @@ pub fn build() -> Router> { // // folders .route("/v1/playbooks/:id/folders/:reference/:path", get(folder::get)) + .route("/v1/playbooks/:id/tree", get(folder::tree)) .route("/v1/playbooks/:id/folders/:reference/:path", post(folder::create)) .route("/v1/playbooks/:id/folders/:reference/:path", delete(folder::delete)) .route("/v1/playbooks/:id/folders/:reference/:path/actions/copy", post(folder::copy)) diff --git a/src/services/folder.rs b/src/services/folder.rs index e26cd9a..2a463f4 100644 --- a/src/services/folder.rs +++ b/src/services/folder.rs @@ -12,11 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -use amp_common::scm::git::Tree; use std::sync::Arc; use uuid::Uuid; -use amp_common::scm::content::Content; +use amp_common::scm::content::{Content, File}; +use amp_common::scm::git::Tree; use crate::context::Context; use crate::errors::{ApiError, Result}; @@ -30,20 +30,27 @@ impl FolderService { id: Uuid, _reference: String, path: Option, - recursive: Option<&String>, - ) -> Result { + ) -> Result, ApiError> { let playbook = ctx.client.playbooks().get(&id.to_string()).map_err(ApiError::NotFoundPlaybook)?; let source = playbook.preface.repository.unwrap(); - let content = ctx - .github_client + ctx.github_client .contents() - .find(&utils::repo(&source.repo)?, &path.unwrap_or_default(), &source.branch.unwrap_or_default()) - .map_err(|e| ApiError::NotFoundContent(e.to_string()))?; + .list(&utils::repo(&source.repo)?, &path.unwrap_or_default(), &source.branch.unwrap_or_default()) + .map_err(|e| ApiError::NotFoundContent(e.to_string())) + } + + pub async fn tree(ctx: Arc, id: Uuid, recursive: Option<&String>) -> Result { + let playbook = ctx.client.playbooks().get(&id.to_string()).map_err(ApiError::NotFoundPlaybook)?; + let source = playbook.preface.repository.unwrap(); ctx.github_client .git() - .get_tree(&utils::repo(&source.repo)?, &content.sha, Option::from(recursive.is_some())) + .get_tree( + &utils::repo(&source.repo)?, + &source.branch.unwrap_or_default(), + Option::from(recursive.is_some()), + ) .map_err(|e| ApiError::NotFoundFolder(e.to_string()))? .ok_or(ApiError::NotFoundFolder("The folder is none".to_string())) } diff --git a/src/swagger.rs b/src/swagger.rs index b82d8ec..5a14407 100644 --- a/src/swagger.rs +++ b/src/swagger.rs @@ -34,6 +34,7 @@ use crate::{handlers, requests}; handlers::file::rename, handlers::folder::get, + handlers::folder::tree, handlers::folder::create, handlers::folder::delete, handlers::folder::copy, @@ -63,6 +64,7 @@ use crate::{handlers, requests}; amp_common::schema::Service, amp_common::scm::content::Content, + amp_common::scm::content::File, amp_common::scm::git::Tree, amp_common::scm::git::TreeEntry, ) From 4e37bf8abf47e2a895fd67e91d792211063b843d Mon Sep 17 00:00:00 2001 From: jiahao6635 Date: Mon, 22 Jan 2024 01:41:27 +0800 Subject: [PATCH 2/5] remove fo file and folder reference filed --- src/handlers/file.rs | 37 +++++++++++++------------------------ src/handlers/folder.rs | 31 +++++++++++-------------------- src/routes.rs | 22 +++++++++++----------- src/services/file.rs | 10 +++------- src/services/folder.rs | 7 ++----- 5 files changed, 40 insertions(+), 67 deletions(-) diff --git a/src/handlers/file.rs b/src/handlers/file.rs index ab4a68e..f8e3b15 100644 --- a/src/handlers/file.rs +++ b/src/handlers/file.rs @@ -29,10 +29,9 @@ use crate::services::FileService; /// Returns a file's content. #[utoipa::path( - get, path = "/v1/playbooks/{id}/files/{reference}/{path}", + get, path = "/v1/playbooks/{id}/files/{path}", params( ("id" = Uuid, description = "The id of playbook"), - ("reference" = String, description = "The name of the commit/branch/tag."), ("path" = String, description = "The file path relative to the root of the repository."), ), responses( @@ -45,17 +44,16 @@ use crate::services::FileService; )] pub async fn get( State(ctx): State>, - Path((id, reference, path)): Path<(Uuid, String, String)>, + Path((id, path)): Path<(Uuid, String)>, ) -> Result { - Ok(Json(FileService::get(ctx, id, reference, path).await?)) + Ok(Json(FileService::get(ctx, id, path).await?)) } /// Create a file #[utoipa::path( - post, path = "/v1/playbooks/{id}/files/{reference}/{path}", + post, path = "/v1/playbooks/{id}/files/{path}", params( ("id" = Uuid, description = "The id of playbook"), - ("reference" = String, description = "The name of the commit/branch/tag."), ("path" = String, description = "The file path relative to the root of the repository."), ), request_body( @@ -74,20 +72,18 @@ pub async fn create( State(ctx): State>, Path(id): Path, - Path(reference): Path, Path(path): Path, Json(req): Json, ) -> Result { - Ok((StatusCode::CREATED, Json(FileService::create(ctx, id, reference, path, req.content).await?))) + Ok((StatusCode::CREATED, Json(FileService::create(ctx, id, path, req.content).await?))) } /// Update a file #[utoipa::path( - put, path = "/v1/playbooks/{id}/files/{reference}/{path}", + put, path = "/v1/playbooks/{id}/files/{path}", params( ("id" = Uuid, description = "The id of playbook"), - ("reference" = String, description = "The name of the commit/branch/tag. Default: default branch."), ("path" = String, description = "The file path relative to the root of the repository."), ), request_body( @@ -107,20 +103,18 @@ pub async fn update( State(ctx): State>, Path(id): Path, - Path(reference): Path, Path(path): Path, Json(req): Json, ) -> Result { - Ok(Json(FileService::update(ctx, id, reference, path, req.content).await?)) + Ok(Json(FileService::update(ctx, id, path, req.content).await?)) } /// Delete a file #[utoipa::path( - delete, path = "/v1/playbooks/{id}/files/{reference}/{path}", + delete, path = "/v1/playbooks/{id}/files/{path}", params( ("id" = Uuid, description = "The id of playbook"), - ("reference" = String, description = "The name of the commit/branch/tag."), ("path" = String, description = "The file path relative to the root of the repository."), ), responses( @@ -135,20 +129,18 @@ pub async fn delete( State(ctx): State>, Path(id): Path, - Path(reference): Path, Path(path): Path, ) -> Result { - FileService::delete(ctx, id, reference, path).await?; + FileService::delete(ctx, id, path).await?; Ok(StatusCode::NO_CONTENT) } /// Copy a file #[utoipa::path( - post, path = "/v1/playbooks/{id}/files/{reference}/{path}/actions/copy", + post, path = "/v1/playbooks/{id}/files/{path}/actions/copy", params( ("id" = Uuid, description = "The id of playbook"), - ("reference" = String, description = "The name of the commit/branch/tag. Default: default branch."), ("path" = String, description = "The file path relative to the root of the repository."), ), request_body( @@ -168,20 +160,18 @@ pub async fn copy( State(ctx): State>, Path(id): Path, - Path(reference): Path, Path(path): Path, Json(req): Json, ) -> Result { - Ok(Json(FileService::copy(ctx, id, reference, path, req.destination).await?)) + Ok(Json(FileService::copy(ctx, id, path, req.destination).await?)) } /// Move a file #[utoipa::path( - post, path = "/v1/playbooks/{id}/files/{reference}/{path}/actions/move", + post, path = "/v1/playbooks/{id}/files/{path}/actions/move", params( ("id" = Uuid, description = "The id of playbook"), - ("reference" = String, description = "The name of the commit/branch/tag. Default: default branch."), ("path" = String, description = "The file path relative to the root of the repository."), ), request_body( @@ -201,10 +191,9 @@ pub async fn rename( State(ctx): State>, Path(id): Path, - Path(reference): Path, Path(path): Path, Json(req): Json, ) -> Result { - Ok(Json(FileService::rename(ctx, id, reference, path, req.destination).await?)) + Ok(Json(FileService::rename(ctx, id, path, req.destination).await?)) } diff --git a/src/handlers/folder.rs b/src/handlers/folder.rs index 5126894..1fd3dc5 100644 --- a/src/handlers/folder.rs +++ b/src/handlers/folder.rs @@ -30,10 +30,9 @@ use crate::services::FolderService; /// Gets the file list of a directory in a repository. #[utoipa::path( - get, path = "/v1/playbooks/{id}/folders/{reference}/{path}", + get, path = "/v1/playbooks/{id}/folders/{path}", params( ("id" = Uuid, description = "The id of playbook"), - ("reference" = String, description = "The name of the commit/branch/tag."), ("path" = String, description = "The file path relative to the root of the repository."), ), responses( @@ -46,9 +45,9 @@ use crate::services::FolderService; )] pub async fn get( State(ctx): State>, - Path((id, reference, path)): Path<(Uuid, String, Option)>, + Path((id, path)): Path<(Uuid, Option)>, ) -> Result { - Ok(Json(FolderService::get(ctx, id, reference, path).await?)) + Ok(Json(FolderService::get(ctx, id, path).await?)) } /// Returns a folder's tree. @@ -76,10 +75,9 @@ pub async fn tree( /// Create a folder #[utoipa::path( - post, path = "/v1/playbooks/{id}/folders/{reference}/{path}", + post, path = "/v1/playbooks/{id}/folders/{path}", params( ("id" = Uuid, description = "The id of playbook"), - ("reference" = String, description = "The name of the commit/branch/tag."), ("path" = String, description = "The file path relative to the root of the repository."), ), responses( @@ -93,18 +91,16 @@ pub async fn create( State(ctx): State>, Path(id): Path, - Path(reference): Path, Path(path): Path, ) -> Result { - Ok((StatusCode::CREATED, Json(FolderService::create(ctx, id, reference, path).await?))) + Ok((StatusCode::CREATED, Json(FolderService::create(ctx, id, path).await?))) } /// Delete a folder #[utoipa::path( - delete, path = "/v1/playbooks/{id}/folders/{reference}/{path}", + delete, path = "/v1/playbooks/{id}/folders/{path}", params( ("id" = Uuid, description = "The id of playbook"), - ("reference" = String, description = "The name of the commit/branch/tag."), ("path" = String, description = "The file path relative to the root of the repository."), ), responses( @@ -119,20 +115,18 @@ pub async fn delete( State(ctx): State>, Path(id): Path, - Path(reference): Path, Path(path): Path, ) -> Result { - FolderService::delete(ctx, id, reference, path).await?; + FolderService::delete(ctx, id, path).await?; Ok(StatusCode::NO_CONTENT) } /// Copy a folder #[utoipa::path( - post, path = "/v1/playbooks/{id}/folders/{reference}/{path}/actions/copy", + post, path = "/v1/playbooks/{id}/folders/{path}/actions/copy", params( ("id" = Uuid, description = "The id of playbook"), - ("reference" = String, description = "The name of the commit/branch/tag. Default: default branch."), ("path" = String, description = "The file path relative to the root of the repository."), ), request_body( @@ -152,20 +146,18 @@ pub async fn copy( State(ctx): State>, Path(id): Path, - Path(reference): Path, Path(path): Path, Json(req): Json, ) -> Result { - Ok(Json(FolderService::copy(ctx, id, reference, path, req.destination).await?)) + Ok(Json(FolderService::copy(ctx, id, path, req.destination).await?)) } /// Move a folder #[utoipa::path( - post, path = "/v1/playbooks/{id}/folders/{reference}/{path}/actions/move", + post, path = "/v1/playbooks/{id}/folders/{path}/actions/move", params( ("id" = Uuid, description = "The id of playbook"), - ("reference" = String, description = "The name of the commit/branch/tag. Default: default branch."), ("path" = String, description = "The file path relative to the root of the repository."), ), request_body( @@ -185,10 +177,9 @@ pub async fn rename( State(ctx): State>, Path(id): Path, - Path(reference): Path, Path(path): Path, Json(req): Json, ) -> Result { - Ok(Json(FolderService::rename(ctx, id, reference, path, req.destination).await?)) + Ok(Json(FolderService::rename(ctx, id, path, req.destination).await?)) } diff --git a/src/routes.rs b/src/routes.rs index dc1441d..2fd1760 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -31,18 +31,18 @@ pub fn build() -> Router> { .route("/v1/playbooks/:id/logs", get(logger::logs)) // // files - .route("/v1/playbooks/:id/files/:reference/:path", get(file::get)) - .route("/v1/playbooks/:id/files/:reference/:path", post(file::create)) - .route("/v1/playbooks/:id/files/:reference/:path", put(file::update)) - .route("/v1/playbooks/:id/files/:reference/:path", delete(file::delete)) - .route("/v1/playbooks/:id/files/:reference/:path/actions/copy", post(file::copy)) - .route("/v1/playbooks/:id/files/:reference/:path/actions/move", post(file::rename)) + .route("/v1/playbooks/:id/files/:path", get(file::get)) + .route("/v1/playbooks/:id/files/:path", post(file::create)) + .route("/v1/playbooks/:id/files/:path", put(file::update)) + .route("/v1/playbooks/:id/files/:path", delete(file::delete)) + .route("/v1/playbooks/:id/files/:path/actions/copy", post(file::copy)) + .route("/v1/playbooks/:id/files/:path/actions/move", post(file::rename)) // // folders - .route("/v1/playbooks/:id/folders/:reference/:path", get(folder::get)) + .route("/v1/playbooks/:id/folders/:path", get(folder::get)) .route("/v1/playbooks/:id/tree", get(folder::tree)) - .route("/v1/playbooks/:id/folders/:reference/:path", post(folder::create)) - .route("/v1/playbooks/:id/folders/:reference/:path", delete(folder::delete)) - .route("/v1/playbooks/:id/folders/:reference/:path/actions/copy", post(folder::copy)) - .route("/v1/playbooks/:id/folders/:reference/:path/actions/move", post(folder::rename)) + .route("/v1/playbooks/:id/folders/:path", post(folder::create)) + .route("/v1/playbooks/:id/folders/:path", delete(folder::delete)) + .route("/v1/playbooks/:id/folders/:path/actions/copy", post(folder::copy)) + .route("/v1/playbooks/:id/folders/:path/actions/move", post(folder::rename)) } diff --git a/src/services/file.rs b/src/services/file.rs index f959380..6019ed0 100644 --- a/src/services/file.rs +++ b/src/services/file.rs @@ -27,13 +27,13 @@ pub struct FileService; impl FileService { /// Get a file content from the remote git repository. - pub async fn get(ctx: Arc, id: Uuid, reference: String, path: String) -> Result { + pub async fn get(ctx: Arc, id: Uuid, path: String) -> Result { let playbook = ctx.client.playbooks().get(&id.to_string()).map_err(ApiError::NotFoundPlaybook)?; let source = playbook.preface.repository.unwrap(); ctx.github_client .contents() - .find(&utils::repo(&source.repo)?, &path, &reference) + .find(&utils::repo(&source.repo)?, &path, &source.branch.unwrap_or_default()) .map_err(|e| ApiError::NotFoundContent(e.to_string())) } @@ -41,7 +41,6 @@ impl FileService { pub async fn create( ctx: Arc, id: Uuid, - _reference: String, path: String, content: String, ) -> Result { @@ -64,7 +63,6 @@ impl FileService { pub async fn update( _ctx: Arc, _id: Uuid, - _reference: String, _path: String, _content: String, ) -> Result { @@ -73,7 +71,7 @@ impl FileService { } /// Delete a file from the workspace. - pub async fn delete(_ctx: Arc, _id: Uuid, _reference: String, _path: String) -> Result<()> { + pub async fn delete(_ctx: Arc, _id: Uuid, _path: String) -> Result<()> { // refer to create() method. todo!() } @@ -82,7 +80,6 @@ impl FileService { pub async fn copy( _ctx: Arc, _id: Uuid, - _reference: String, _path: String, _destination: String, ) -> Result { @@ -94,7 +91,6 @@ impl FileService { pub async fn rename( _ctx: Arc, _id: Uuid, - _reference: String, _path: String, _destination: String, ) -> Result { diff --git a/src/services/folder.rs b/src/services/folder.rs index 2a463f4..62438b2 100644 --- a/src/services/folder.rs +++ b/src/services/folder.rs @@ -28,7 +28,6 @@ impl FolderService { pub async fn get( ctx: Arc, id: Uuid, - _reference: String, path: Option, ) -> Result, ApiError> { let playbook = ctx.client.playbooks().get(&id.to_string()).map_err(ApiError::NotFoundPlaybook)?; @@ -55,18 +54,17 @@ impl FolderService { .ok_or(ApiError::NotFoundFolder("The folder is none".to_string())) } - pub async fn create(_ctx: Arc, _id: Uuid, _reference: String, _path: String) -> Result { + pub async fn create(_ctx: Arc, _id: Uuid, _path: String) -> Result { todo!() } - pub async fn delete(_ctx: Arc, _id: Uuid, _reference: String, _path: String) -> Result<()> { + pub async fn delete(_ctx: Arc, _id: Uuid, _path: String) -> Result<()> { todo!() } pub async fn copy( _ctx: Arc, _id: Uuid, - _reference: String, _path: String, _destination: String, ) -> Result { @@ -76,7 +74,6 @@ impl FolderService { pub async fn rename( _ctx: Arc, _id: Uuid, - _reference: String, _path: String, _destination: String, ) -> Result { From 566d7fc60d648b44a709f0a4ddf8505c6bc4ecda Mon Sep 17 00:00:00 2001 From: jiahao6635 Date: Mon, 22 Jan 2024 01:44:59 +0800 Subject: [PATCH 3/5] remove fo file and folder reference filed --- src/handlers/file.rs | 5 +---- src/services/file.rs | 28 ++++------------------------ src/services/folder.rs | 20 +++----------------- 3 files changed, 8 insertions(+), 45 deletions(-) diff --git a/src/handlers/file.rs b/src/handlers/file.rs index f8e3b15..d4b5bcd 100644 --- a/src/handlers/file.rs +++ b/src/handlers/file.rs @@ -42,10 +42,7 @@ use crate::services::FileService; ), tag = "Files" )] -pub async fn get( - State(ctx): State>, - Path((id, path)): Path<(Uuid, String)>, -) -> Result { +pub async fn get(State(ctx): State>, Path((id, path)): Path<(Uuid, String)>) -> Result { Ok(Json(FileService::get(ctx, id, path).await?)) } diff --git a/src/services/file.rs b/src/services/file.rs index 6019ed0..0ec6fb3 100644 --- a/src/services/file.rs +++ b/src/services/file.rs @@ -38,12 +38,7 @@ impl FileService { } /// Create a file to the workspace. - pub async fn create( - ctx: Arc, - id: Uuid, - path: String, - content: String, - ) -> Result { + pub async fn create(ctx: Arc, id: Uuid, path: String, content: String) -> Result { let data = content.into_bytes(); let req = Synchronization { kind: EventKinds::Create, @@ -60,12 +55,7 @@ impl FileService { } /// Update a file to the workspace. - pub async fn update( - _ctx: Arc, - _id: Uuid, - _path: String, - _content: String, - ) -> Result { + pub async fn update(_ctx: Arc, _id: Uuid, _path: String, _content: String) -> Result { // refer to create() method. todo!() } @@ -77,23 +67,13 @@ impl FileService { } /// Copy a file to the destination path on the workspace. - pub async fn copy( - _ctx: Arc, - _id: Uuid, - _path: String, - _destination: String, - ) -> Result { + pub async fn copy(_ctx: Arc, _id: Uuid, _path: String, _destination: String) -> Result { // refer to create() method. todo!() } /// Move a file to the destination path on the workspace. - pub async fn rename( - _ctx: Arc, - _id: Uuid, - _path: String, - _destination: String, - ) -> Result { + pub async fn rename(_ctx: Arc, _id: Uuid, _path: String, _destination: String) -> Result { // refer to create() method. todo!() } diff --git a/src/services/folder.rs b/src/services/folder.rs index 62438b2..b9dea82 100644 --- a/src/services/folder.rs +++ b/src/services/folder.rs @@ -25,11 +25,7 @@ use crate::utils; pub struct FolderService; impl FolderService { - pub async fn get( - ctx: Arc, - id: Uuid, - path: Option, - ) -> Result, ApiError> { + pub async fn get(ctx: Arc, id: Uuid, path: Option) -> Result, ApiError> { let playbook = ctx.client.playbooks().get(&id.to_string()).map_err(ApiError::NotFoundPlaybook)?; let source = playbook.preface.repository.unwrap(); @@ -62,21 +58,11 @@ impl FolderService { todo!() } - pub async fn copy( - _ctx: Arc, - _id: Uuid, - _path: String, - _destination: String, - ) -> Result { + pub async fn copy(_ctx: Arc, _id: Uuid, _path: String, _destination: String) -> Result { todo!() } - pub async fn rename( - _ctx: Arc, - _id: Uuid, - _path: String, - _destination: String, - ) -> Result { + pub async fn rename(_ctx: Arc, _id: Uuid, _path: String, _destination: String) -> Result { todo!() } } From 7c95dd45c526d8052227a2394b587b800aa081c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=98=89=E8=B1=AA?= Date: Mon, 22 Jan 2024 15:25:11 +0800 Subject: [PATCH 4/5] CreatePlaybookRequest segmentation --- src/errors.rs | 4 ++++ src/requests/playbook.rs | 14 +++++++++++++- src/services/folder.rs | 8 ++------ src/services/playbook.rs | 20 ++++++++++++-------- 4 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/errors.rs b/src/errors.rs index 44b55de..1cf1228 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -59,6 +59,9 @@ pub enum ApiError { #[error("Not Found Repo: {0}")] NotFoundRepo(anyhow::Error), + + #[error("Bad Playbook Request: {0}")] + BadPlaybookRequest(String), } impl IntoResponse for ApiError { @@ -76,6 +79,7 @@ impl IntoResponse for ApiError { Self::FailedToSynchronize(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), Self::BadPlaybook(e) => (StatusCode::BAD_REQUEST, e.to_string()), Self::NotFoundRepo(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + Self::BadPlaybookRequest(e) => (StatusCode::BAD_REQUEST, e.to_string()), }; error!("{} - {}", status, message); diff --git a/src/requests/playbook.rs b/src/requests/playbook.rs index 2828966..2b10d49 100644 --- a/src/requests/playbook.rs +++ b/src/requests/playbook.rs @@ -17,6 +17,18 @@ use utoipa::ToSchema; #[derive(Debug, Serialize, Deserialize, ToSchema)] pub struct CreatePlaybookRequest { + /// Source code repository the partner should be cloned from. + /// e.g. https://github.com/amphitheatre-app/amphitheatre.git. pub repo: String, - pub reference: Option, + /// Git branch the partner should be cloned from. eg. master or main + #[serde(skip_serializing_if = "Option::is_none")] + pub branch: Option, + /// Git tag the partner should be cloned from. eg. v1.0 + #[serde(skip_serializing_if = "Option::is_none")] + pub tag: Option, + /// A commit hash like rev = "4c59b707", or a named reference exposed by + /// the remote repository such as rev = "refs/pull/493/head". What references + /// are available varies by where the repo is hosted. + #[serde(skip_serializing_if = "Option::is_none")] + pub rev: Option, } diff --git a/src/services/folder.rs b/src/services/folder.rs index b9dea82..cb1dfa9 100644 --- a/src/services/folder.rs +++ b/src/services/folder.rs @@ -31,7 +31,7 @@ impl FolderService { ctx.github_client .contents() - .list(&utils::repo(&source.repo)?, &path.unwrap_or_default(), &source.branch.unwrap_or_default()) + .list(&utils::repo(&source.repo)?, &path.unwrap_or_default(), &source.reference().unwrap()) .map_err(|e| ApiError::NotFoundContent(e.to_string())) } @@ -41,11 +41,7 @@ impl FolderService { ctx.github_client .git() - .get_tree( - &utils::repo(&source.repo)?, - &source.branch.unwrap_or_default(), - Option::from(recursive.is_some()), - ) + .get_tree(&utils::repo(&source.repo)?, &source.reference().unwrap(), Option::from(recursive.is_some())) .map_err(|e| ApiError::NotFoundFolder(e.to_string()))? .ok_or(ApiError::NotFoundFolder("The folder is none".to_string())) } diff --git a/src/services/playbook.rs b/src/services/playbook.rs index 978321a..19a3e25 100644 --- a/src/services/playbook.rs +++ b/src/services/playbook.rs @@ -33,15 +33,19 @@ impl PlaybookService { let repo = repo(&req.repo)?; let repository = ctx.github_client.repositories().find(&repo).map_err(ApiError::NotFoundRepo)?; let description = repository.and_then(|r| r.description).unwrap_or_default(); - let preface = Preface { - name: req.repo.clone(), - repository: Some(GitReference { - repo: req.repo.clone(), - branch: req.reference.clone(), - ..GitReference::default() - }), - ..Preface::default() + let repository = GitReference { + repo: req.repo.clone(), + branch: req.branch.clone(), + tag: req.tag.clone(), + rev: req.rev.clone(), + ..GitReference::default() }; + if repository.reference().is_none() { + return Err(ApiError::BadPlaybookRequest( + "branch tag rev All three fields cannot be empty, as long as one of them has a value".to_string(), + )); + } + let preface = Preface { name: req.repo.clone(), repository: Some(repository), ..Preface::default() }; let payload = PlaybookPayload { title: repo, description, preface }; ctx.client.playbooks().create(payload).map_err(ApiError::FailedToCreatePlaybook) From f9900f326b7a85980624dbdbe146439b2845bfd1 Mon Sep 17 00:00:00 2001 From: jiahao6635 Date: Mon, 22 Jan 2024 20:23:37 +0800 Subject: [PATCH 5/5] Optimize the unwrap mode --- src/handlers/folder.rs | 5 +---- src/services/folder.rs | 15 ++++++++++----- src/services/playbook.rs | 4 +--- src/utils.rs | 6 ++++++ 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/handlers/folder.rs b/src/handlers/folder.rs index 1fd3dc5..8db8714 100644 --- a/src/handlers/folder.rs +++ b/src/handlers/folder.rs @@ -43,10 +43,7 @@ use crate::services::FolderService; ), tag = "Folders" )] -pub async fn get( - State(ctx): State>, - Path((id, path)): Path<(Uuid, Option)>, -) -> Result { +pub async fn get(State(ctx): State>, Path((id, path)): Path<(Uuid, String)>) -> Result { Ok(Json(FolderService::get(ctx, id, path).await?)) } diff --git a/src/services/folder.rs b/src/services/folder.rs index cb1dfa9..a84b38d 100644 --- a/src/services/folder.rs +++ b/src/services/folder.rs @@ -21,27 +21,32 @@ use amp_common::scm::git::Tree; use crate::context::Context; use crate::errors::{ApiError, Result}; use crate::utils; +use crate::utils::unwrap_or_error; pub struct FolderService; impl FolderService { - pub async fn get(ctx: Arc, id: Uuid, path: Option) -> Result, ApiError> { + pub async fn get(ctx: Arc, id: Uuid, path: String) -> Result, ApiError> { let playbook = ctx.client.playbooks().get(&id.to_string()).map_err(ApiError::NotFoundPlaybook)?; - let source = playbook.preface.repository.unwrap(); + + let source = unwrap_or_error(playbook.preface.repository, "The repository is none")?; + let reference = unwrap_or_error(source.reference(), "The reference is none")?; ctx.github_client .contents() - .list(&utils::repo(&source.repo)?, &path.unwrap_or_default(), &source.reference().unwrap()) + .list(&utils::repo(&source.repo)?, &path, &reference) .map_err(|e| ApiError::NotFoundContent(e.to_string())) } pub async fn tree(ctx: Arc, id: Uuid, recursive: Option<&String>) -> Result { let playbook = ctx.client.playbooks().get(&id.to_string()).map_err(ApiError::NotFoundPlaybook)?; - let source = playbook.preface.repository.unwrap(); + + let source = unwrap_or_error(playbook.preface.repository, "The repository is none")?; + let reference = unwrap_or_error(source.reference(), "The reference is none")?; ctx.github_client .git() - .get_tree(&utils::repo(&source.repo)?, &source.reference().unwrap(), Option::from(recursive.is_some())) + .get_tree(&utils::repo(&source.repo)?, &reference, Option::from(recursive.is_some())) .map_err(|e| ApiError::NotFoundFolder(e.to_string()))? .ok_or(ApiError::NotFoundFolder("The folder is none".to_string())) } diff --git a/src/services/playbook.rs b/src/services/playbook.rs index 19a3e25..b260714 100644 --- a/src/services/playbook.rs +++ b/src/services/playbook.rs @@ -41,9 +41,7 @@ impl PlaybookService { ..GitReference::default() }; if repository.reference().is_none() { - return Err(ApiError::BadPlaybookRequest( - "branch tag rev All three fields cannot be empty, as long as one of them has a value".to_string(), - )); + return Err(ApiError::BadPlaybookRequest("Requires either branch, tag or rev".to_string())); } let preface = Preface { name: req.repo.clone(), repository: Some(repository), ..Preface::default() }; let payload = PlaybookPayload { title: repo, description, preface }; diff --git a/src/utils.rs b/src/utils.rs index a0c4081..b04ac5f 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -24,3 +24,9 @@ pub fn repo(url: &str) -> Result { Ok(repo) } +pub fn unwrap_or_error(option: Option, error_message: &str) -> Result { + match option { + Some(value) => Ok(value), + None => Err(ApiError::BadPlaybookRequest(error_message.to_string())), + } +}