diff --git a/ceres/src/api_service/import_api_service.rs b/ceres/src/api_service/import_api_service.rs index f1436eafb..87525b847 100644 --- a/ceres/src/api_service/import_api_service.rs +++ b/ceres/src/api_service/import_api_service.rs @@ -17,6 +17,7 @@ use venus::import_repo::repo::Repo; use crate::api_service::ApiHandler; use crate::model::create_file::CreateFileInfo; +use crate::model::publish_path::PublishPathInfo; #[derive(Clone)] pub struct ImportApiService { @@ -32,6 +33,12 @@ impl ApiHandler for ImportApiService { )); } + async fn publish_path(&self, _: PublishPathInfo) -> Result<(), GitError> { + return Err(GitError::CustomError( + "Publish operation only support in mono directory".to_string(), + )); + } + async fn get_raw_blob_by_hash(&self, hash: &str) -> Result, MegaError> { self.context .services diff --git a/ceres/src/api_service/mod.rs b/ceres/src/api_service/mod.rs index 631cfda6e..b326b8f61 100644 --- a/ceres/src/api_service/mod.rs +++ b/ceres/src/api_service/mod.rs @@ -17,8 +17,7 @@ use mercury::{ use venus::monorepo::converter; use crate::model::{ - create_file::CreateFileInfo, - tree::{LatestCommitInfo, TreeBriefItem, TreeCommitItem, UserInfo}, + create_file::CreateFileInfo, publish_path::PublishPathInfo, tree::{LatestCommitInfo, TreeBriefItem, TreeCommitItem, UserInfo} }; pub mod import_api_service; @@ -28,6 +27,8 @@ pub mod mono_api_service; pub trait ApiHandler: Send + Sync { async fn create_monorepo_file(&self, file_info: CreateFileInfo) -> Result<(), GitError>; + async fn publish_path(&self, publish_info: PublishPathInfo) -> Result<(), GitError>; + async fn get_raw_blob_by_hash(&self, hash: &str) -> Result, MegaError>; fn strip_relative(&self, path: &Path) -> Result; @@ -63,9 +64,9 @@ pub trait ApiHandler: Send + Sync { async fn get_blob_as_string(&self, file_path: PathBuf) -> Result { let filename = file_path.file_name().unwrap().to_str().unwrap(); - let path = file_path.parent().unwrap(); + let parent = file_path.parent().unwrap(); let mut plain_text = String::new(); - if let Some(tree) = self.search_tree_by_path(path).await? { + if let Some(tree) = self.search_tree_by_path(parent).await? { if let Some(item) = tree.tree_items.into_iter().find(|x| x.name == filename) { plain_text = match self.get_raw_blob_by_hash(&item.id.to_plain_str()).await { Ok(Some(model)) => String::from_utf8(model.data.unwrap()).unwrap(), @@ -187,18 +188,21 @@ pub trait ApiHandler: Send + Sync { Ok(res) } - /// Searches for a tree and affected parent by path. - /// - /// This function asynchronously searches for a tree by the provided path. + /// Searches for a tree in the Git repository by its path and returns the trees involved in the update and the target tree. /// /// # Arguments /// - /// * `path` - A reference to the path to search. + /// * `path` - A reference to the path to search for. /// /// # Returns /// - /// Returns a tuple containing a vector of parent trees to be updated and - /// the target tree if found, or an error of type `GitError`. + /// A tuple containing: + /// - A vector of trees involved in the update process. + /// - The target tree found at the end of the search. + /// + /// # Errors + /// + /// Returns a `GitError` if the path does not exist. async fn search_tree_for_update(&self, path: &Path) -> Result<(Vec, Tree), GitError> { let relative_path = self.strip_relative(path)?; let root_tree = self.get_root_tree().await; @@ -224,7 +228,7 @@ pub trait ApiHandler: Send + Sync { } } else { return Err(GitError::CustomError( - "can't find target parent tree under latest commit".to_string(), + "Path not exist, please create path first!".to_string(), )); } } @@ -232,6 +236,20 @@ pub trait ApiHandler: Send + Sync { Ok((update_tree, search_tree)) } + /// Searches for a tree by a given path. + /// + /// This function takes a `path` and searches for the corresponding tree + /// in the repository. It returns a `Result` containing an `Option`. + /// If the tree is found, it returns `Some(Tree)`. If the path does not + /// exist, it returns `None`. In case of an error, it returns a `GitError`. + /// + /// # Arguments + /// + /// * `path` - A reference to the `Path` to search for the tree. + /// + /// # Returns + /// + /// * `Result, GitError>` - A result containing an optional tree or a Git error. async fn search_tree_by_path(&self, path: &Path) -> Result, GitError> { let relative_path = self.strip_relative(path)?; let root_tree = self.get_root_tree().await; @@ -255,41 +273,54 @@ pub trait ApiHandler: Send + Sync { Ok(Some(search_tree)) } - // move to monorepo. - async fn search_and_create_tree(&self, path: &Path) -> Result, GitError> { + /// Searches for a tree in the Git repository by its path, creating intermediate trees if necessary, + /// and returns the trees involved in the update process. + /// + /// # Arguments + /// + /// * `path` - A reference to the path to search for. + /// + /// # Returns + /// + /// A vector of trees involved in the update process. + /// + /// # Errors + /// + /// Returns a `GitError` if an error occurs during the search or tree creation process. + async fn search_and_create_tree(&self, path: &Path) -> Result, GitError> { let relative_path = self.strip_relative(path)?; let root_tree = self.get_root_tree().await; let mut search_tree = root_tree.clone(); let mut update_item_tree = VecDeque::new(); update_item_tree.push_back((root_tree, Component::RootDir)); - let mut result = vec![]; + let mut saving_trees = VecDeque::new(); let mut stack: VecDeque<_> = VecDeque::new(); for component in relative_path.components() { - // skip rootdir - if component != Component::RootDir { - let target_name = component.as_os_str().to_str().unwrap(); - let search_res = search_tree - .tree_items - .iter() - .find(|x| x.name == target_name); - if let Some(search_res) = search_res { - let res = self.get_tree_by_hash(&search_res.id.to_plain_str()).await; - search_tree = res.clone(); - update_item_tree.push_back((res, component)); - } else { - stack.push_back(component) - } + if component == Component::RootDir { + continue; + } + + let target_name = component.as_os_str().to_str().unwrap(); + if let Some(search_res) = search_tree + .tree_items + .iter() + .find(|x| x.name == target_name) + { + search_tree = self.get_tree_by_hash(&search_res.id.to_plain_str()).await; + update_item_tree.push_back((search_tree.clone(), component)); + } else { + stack.push_back(component); } } let blob = converter::generate_git_keep_with_timestamp(); - let new_item = TreeItem { + let mut last_tree = Tree::from_tree_items(vec![TreeItem { mode: TreeItemMode::Blob, id: blob.id, name: String::from(".gitkeep"), - }; - let mut last_tree = Tree::from_tree_items(vec![new_item]).unwrap(); + }]) + .unwrap(); let mut last_tree_name = ""; let mut first_element = true; @@ -297,43 +328,40 @@ pub trait ApiHandler: Send + Sync { if first_element { first_element = false; } else { - let new_item = TreeItem { + last_tree = Tree::from_tree_items(vec![TreeItem { mode: TreeItemMode::Tree, id: last_tree.id, name: last_tree_name.to_owned(), - }; - last_tree = Tree::from_tree_items(vec![new_item]).unwrap(); + }]) + .unwrap(); } - result.push(last_tree.clone()); + saving_trees.push_back(last_tree.clone()); last_tree_name = component.as_os_str().to_str().unwrap(); } - let (new_item_tree, search_name) = update_item_tree.pop_back().unwrap(); - let new_item = TreeItem { - mode: TreeItemMode::Tree, - id: last_tree.id, - name: last_tree_name.to_owned(), - }; - let mut items = new_item_tree.tree_items.clone(); - items.push(new_item); - last_tree = Tree::from_tree_items(items).unwrap(); - result.push(last_tree.clone()); - - let mut replace_hash = last_tree.id; - let mut search_name = search_name.as_os_str().to_str().unwrap(); - while let Some((mut tree, component)) = update_item_tree.pop_back() { - let index = tree - .tree_items - .iter() - .position(|x| x.name == search_name) - .unwrap(); - tree.tree_items[index].id = replace_hash; - let new_tree = Tree::from_tree_items(tree.tree_items).unwrap(); - replace_hash = new_tree.id; - search_name = component.as_os_str().to_str().unwrap(); - result.push(new_tree) + if let Some((mut new_item_tree, search_name_component)) = update_item_tree.pop_back() { + new_item_tree.tree_items.push(TreeItem { + mode: TreeItemMode::Tree, + id: last_tree.id, + name: last_tree_name.to_owned(), + }); + last_tree = Tree::from_tree_items(new_item_tree.tree_items).unwrap(); + saving_trees.push_back(last_tree.clone()); + + let mut replace_hash = last_tree.id; + let mut search_name = search_name_component.as_os_str().to_str().unwrap(); + while let Some((mut tree, component)) = update_item_tree.pop_back() { + if let Some(index) = tree.tree_items.iter().position(|x| x.name == search_name) { + tree.tree_items[index].id = replace_hash; + let new_tree = Tree::from_tree_items(tree.tree_items).unwrap(); + replace_hash = new_tree.id; + search_name = component.as_os_str().to_str().unwrap(); + saving_trees.push_back(new_tree); + } + } } - Ok(result) + + Ok(saving_trees) } async fn reachable_in_tree( diff --git a/ceres/src/api_service/mono_api_service.rs b/ceres/src/api_service/mono_api_service.rs index 4e7270bc3..9c29d3b88 100644 --- a/ceres/src/api_service/mono_api_service.rs +++ b/ceres/src/api_service/mono_api_service.rs @@ -14,11 +14,13 @@ use mercury::hash::SHA1; use mercury::internal::object::blob::Blob; use mercury::internal::object::commit::Commit; use mercury::internal::object::tree::{Tree, TreeItem, TreeItemMode}; +use venus::import_repo::repo::Repo; use venus::monorepo::converter; use crate::api_service::ApiHandler; use crate::model::create_file::CreateFileInfo; use crate::model::mr::{MRDetail, MrInfoItem}; +use crate::model::publish_path::PublishPathInfo; #[derive(Clone)] pub struct MonoApiService { @@ -27,14 +29,25 @@ pub struct MonoApiService { #[async_trait] impl ApiHandler for MonoApiService { + /// Creates a new file or directory in the monorepo based on the provided file information. + /// + /// # Arguments + /// + /// * `file_info` - Information about the file or directory to create. + /// + /// # Returns + /// + /// Returns `Ok(())` on success, or a `GitError` on failure. async fn create_monorepo_file(&self, file_info: CreateFileInfo) -> Result<(), GitError> { let storage = self.context.services.mega_storage.clone(); let path = PathBuf::from(file_info.path); let mut save_trees = vec![]; - let (update_trees, search_tree) = self.search_tree_for_update(&path).await.unwrap(); + // Search for the tree to update and get its tree items + let (update_trees, search_tree) = self.search_tree_for_update(&path).await?; let mut t_items = search_tree.tree_items; + // Create a new tree item based on whether it's a directory or file let new_item = if file_info.is_directory { if t_items .iter() @@ -56,26 +69,26 @@ impl ApiHandler for MonoApiService { name: file_info.name.clone(), } } else { - let blob = Blob::from_content(&file_info.content.unwrap()); - let mega_blob: mega_blob::Model = (&blob).into(); - let mega_blob: mega_blob::ActiveModel = mega_blob.into(); - let raw_blob: raw_blob::Model = blob.clone().into(); - let raw_blob: raw_blob::ActiveModel = raw_blob.into(); - batch_save_model(storage.get_connection(), vec![mega_blob]) - .await - .unwrap(); - batch_save_model(storage.get_connection(), vec![raw_blob]) - .await - .unwrap(); + let content = file_info.content.unwrap(); + let blob = Blob::from_content(&content); + let mega_blob: mega_blob::ActiveModel = Into::::into(&blob).into(); + let raw_blob: raw_blob::ActiveModel = + Into::::into(blob.clone()).into(); + + let conn = storage.get_connection(); + batch_save_model(conn, vec![mega_blob]).await.unwrap(); + batch_save_model(conn, vec![raw_blob]).await.unwrap(); TreeItem { mode: TreeItemMode::Blob, id: blob.id, name: file_info.name.clone(), } }; + // Add the new item to the tree items and create a new tree t_items.push(new_item); let p_tree = Tree::from_tree_items(t_items).unwrap(); + // Create a commit for the new tree let refs = storage.get_ref("/").await.unwrap().unwrap(); let commit = Commit::from_tree_id( p_tree.id, @@ -83,19 +96,16 @@ impl ApiHandler for MonoApiService { &format!("create file {} commit", file_info.name), ); - let commit_id = self - .update_parent_tree(path, update_trees, commit) - .await - .unwrap(); + // Update the parent tree with the new commit + let commit_id = self.update_parent_tree(path, update_trees, commit).await?; save_trees.push(p_tree); - let save_trees = save_trees + let save_trees: Vec = save_trees .into_iter() .map(|save_t| { let mut tree_model: mega_tree::Model = save_t.into(); tree_model.commit_id.clone_from(&commit_id); - let tree_model: mega_tree::ActiveModel = tree_model.into(); - tree_model + tree_model.into() }) .collect(); batch_save_model(storage.get_connection(), save_trees) @@ -104,6 +114,13 @@ impl ApiHandler for MonoApiService { Ok(()) } + async fn publish_path(&self, publish_info: PublishPathInfo) -> Result<(), GitError> { + let storage = self.context.services.git_db_storage.clone(); + let repo: Repo = publish_info.into(); + storage.save_git_repo(repo.clone()).await.unwrap(); + Ok(()) + } + async fn get_raw_blob_by_hash(&self, hash: &str) -> Result, MegaError> { self.context .services diff --git a/ceres/src/model/mod.rs b/ceres/src/model/mod.rs index bf7c74ccb..5fdd343ae 100644 --- a/ceres/src/model/mod.rs +++ b/ceres/src/model/mod.rs @@ -4,6 +4,7 @@ pub mod create_file; pub mod mr; pub mod query; pub mod tree; +pub mod publish_path; #[derive(PartialEq, Eq, Debug, Clone, Default, Serialize, Deserialize)] diff --git a/ceres/src/model/publish_path.rs b/ceres/src/model/publish_path.rs new file mode 100644 index 000000000..6f1c516a5 --- /dev/null +++ b/ceres/src/model/publish_path.rs @@ -0,0 +1,20 @@ +use common::utils::generate_id; +use serde::{Deserialize, Serialize}; +use venus::import_repo::repo::Repo; + +#[derive(PartialEq, Eq, Debug, Clone, Default, Serialize, Deserialize)] +pub struct PublishPathInfo { + pub repo_name: String, + pub path: String, +} + +impl From for Repo { + fn from(value: PublishPathInfo) -> Self { + Self { + repo_id: generate_id(), + repo_path: value.path, + repo_name: value.repo_name, + is_monorepo: true, + } + } +} diff --git a/ceres/src/pack/import_repo.rs b/ceres/src/pack/import_repo.rs index e7a6cae55..abf5782ad 100644 --- a/ceres/src/pack/import_repo.rs +++ b/ceres/src/pack/import_repo.rs @@ -332,7 +332,7 @@ impl ImportRepo { let mut root_ref = storage.get_ref("/").await.unwrap().unwrap(); let new_commit = Commit::from_tree_id( - save_trees[save_trees.len() - 1].id, + save_trees.back().unwrap().id, vec![SHA1::from_str(&root_ref.ref_commit_hash).unwrap()], &format!( "push thrid-part crates {:?} commit", diff --git a/ceres/src/protocol/mod.rs b/ceres/src/protocol/mod.rs index 255295fc9..739daee3b 100644 --- a/ceres/src/protocol/mod.rs +++ b/ceres/src/protocol/mod.rs @@ -2,10 +2,7 @@ use core::fmt; use std::{path::PathBuf, str::FromStr, sync::Arc}; use callisto::db_enums::RefType; -use common::{ - errors::MegaError, - utils::{generate_id, ZERO_ID}, -}; +use common::{errors::MegaError, utils::ZERO_ID}; use jupiter::context::Context; use venus::{import_repo::import_refs::RefCommand, import_repo::repo::Repo}; @@ -151,16 +148,11 @@ impl SmartProtocol { let storage = self.context.services.git_db_storage.clone(); let path_str = self.path.to_str().unwrap(); - let model = storage.find_git_repo(path_str).await.unwrap(); + let model = storage.find_git_repo_exact_match(path_str).await.unwrap(); let repo = if let Some(repo) = model { repo.into() } else { - let repo_name = self.path.file_name().unwrap().to_str().unwrap().to_owned(); - let repo = Repo { - repo_id: generate_id(), - repo_path: self.path.to_str().unwrap().to_owned(), - repo_name, - }; + let repo = Repo::new(self.path.clone(), false); storage.save_git_repo(repo.clone()).await.unwrap(); repo }; diff --git a/gateway/src/api/api_router.rs b/gateway/src/api/api_router.rs index 0b99fb769..47d473af6 100644 --- a/gateway/src/api/api_router.rs +++ b/gateway/src/api/api_router.rs @@ -9,10 +9,7 @@ use axum::{ use crate::api::mr_router; use crate::api::ApiServiceState; use ceres::model::{ - create_file::CreateFileInfo, - query::{BlobContentQuery, CodePreviewQuery}, - tree::{LatestCommitInfo, TreeBriefItem, TreeCommitItem}, - CommonResult, + create_file::CreateFileInfo, publish_path::PublishPathInfo, query::{BlobContentQuery, CodePreviewQuery}, tree::{LatestCommitInfo, TreeBriefItem, TreeCommitItem}, CommonResult }; pub fn routers() -> Router { @@ -20,9 +17,10 @@ pub fn routers() -> Router { .route("/status", get(life_cycle_check)) .route("/create-file", post(create_file)) .route("/latest-commit", get(get_latest_commit)) - .route("/tree-commit-info", get(get_tree_commit_info)) + .route("/tree/commit-info", get(get_tree_commit_info)) .route("/tree", get(get_tree_info)) - .route("/blob", get(get_blob_object)); + .route("/blob", get(get_blob_object)) + .route("/publish", post(publish_path_to_repo)); Router::new().merge(router).merge(mr_router::routers()) } @@ -128,3 +126,19 @@ async fn get_tree_commit_info( }; Ok(Json(res)) } + +async fn publish_path_to_repo( + state: State, + Json(json): Json, +) -> Result>, (StatusCode, String)> { + let res = state + .api_handler(json.path.clone().into()) + .await + .publish_path(json) + .await; + let res = match res { + Ok(_) => CommonResult::success(None), + Err(err) => CommonResult::failed(&err.to_string()), + }; + Ok(Json(res)) +} diff --git a/gateway/src/api/mod.rs b/gateway/src/api/mod.rs index a314e072c..ce262680b 100644 --- a/gateway/src/api/mod.rs +++ b/gateway/src/api/mod.rs @@ -28,7 +28,7 @@ impl ApiServiceState { .context .services .git_db_storage - .find_git_repo(path.to_str().unwrap()) + .find_git_repo_like_path(path.to_str().unwrap()) .await .unwrap() { diff --git a/gateway/src/api/mr_router.rs b/gateway/src/api/mr_router.rs index 65feab742..8098d6499 100644 --- a/gateway/src/api/mr_router.rs +++ b/gateway/src/api/mr_router.rs @@ -15,10 +15,10 @@ use ceres::model::{ pub fn routers() -> Router { Router::new() - .route("/mr-list", get(get_mr_list)) - .route("/mr-detail/:mr_id", get(mr_detail)) - .route("/merge/:mr_id", post(merge)) - .route("/mr-files/:mr_id", get(get_mr_files)) + .route("/mr/list", get(get_mr_list)) + .route("/mr/:mr_id/detail", get(mr_detail)) + .route("/mr/:mr_id/merge", post(merge)) + .route("/mr/:mr_id/files", get(get_mr_files)) } async fn merge( diff --git a/jupiter/src/storage/git_db_storage.rs b/jupiter/src/storage/git_db_storage.rs index 8f13949f8..08e9e639b 100644 --- a/jupiter/src/storage/git_db_storage.rs +++ b/jupiter/src/storage/git_db_storage.rs @@ -176,12 +176,44 @@ impl GitDbStorage { Ok(()) } - pub async fn find_git_repo( + /// Finds a Git repository with an exact match on the repository path. + /// + /// # Arguments + /// + /// * `repo_path` - A string slice that holds the path of the repository to search for. + /// + /// # Returns + /// + /// A `Result` containing an `Option` with the Git repository model if found, or `None` if not found. + /// Returns a `MegaError` if an error occurs during the search. + pub async fn find_git_repo_exact_match( + &self, + repo_path: &str, + ) -> Result, MegaError> { + let result = git_repo::Entity::find() + .filter(git_repo::Column::RepoPath.eq(repo_path)) + .one(self.get_connection()) + .await?; + Ok(result) + } + + /// Finds a Git repository with a path that matches the beginning of the provided repository path using a LIKE query. + /// + /// # Arguments + /// + /// * `repo_path` - A string slice that holds the beginning of the path of the repository to search for. + /// + /// # Returns + /// + /// A `Result` containing an `Option` with the Git repository model if found, or `None` if not found. + /// Returns a `MegaError` if an error occurs during the search. + pub async fn find_git_repo_like_path( &self, repo_path: &str, ) -> Result, MegaError> { let query = git_repo::Entity::find() - .filter(Expr::cust(format!("'{}' LIKE repo_path || '%'", repo_path))); + .filter(Expr::cust(format!("'{}' LIKE repo_path || '%'", repo_path))) + .order_by_desc(Expr::cust("LENGTH(repo_path)")); tracing::debug!("{}", query.build(DbBackend::Postgres).to_string()); let result = query.one(self.get_connection()).await?; Ok(result) @@ -197,17 +229,6 @@ impl GitDbStorage { Ok(()) } - // #[allow(unused)] - // pub async fn update_git_repo(&self, repo: Repo) -> Result<(), MegaError> { - // let git_repo = git_repo::Entity::find_by_id(repo.repo_id) - // .one(self.get_connection()) - // .await - // .unwrap(); - // let git_repo: git_repo::ActiveModel = git_repo.unwrap().into(); - // git_repo.update(self.get_connection()).await.unwrap(); - // Ok(()) - // } - pub async fn get_commit_by_hash( &self, repo: &Repo, diff --git a/jupiter/src/storage/mega_storage.rs b/jupiter/src/storage/mega_storage.rs index d029fe23e..e721a8c39 100644 --- a/jupiter/src/storage/mega_storage.rs +++ b/jupiter/src/storage/mega_storage.rs @@ -333,7 +333,6 @@ impl MegaStorage { ) -> Result, MegaError> { Ok(mega_commit::Entity::find() .filter(mega_commit::Column::CommitId.is_in(hashes)) - .distinct() .all(self.get_connection()) .await .unwrap()) diff --git a/moon/src/app/api/blob/route.ts b/moon/src/app/api/blob/route.ts index e25cc0fe0..bad4089e0 100644 --- a/moon/src/app/api/blob/route.ts +++ b/moon/src/app/api/blob/route.ts @@ -1,6 +1,7 @@ import { type NextRequest } from 'next/server' export const dynamic = 'force-dynamic' // defaults to auto +export const revalidate = 0 const endpoint = process.env.NEXT_MEGA_API_URL; diff --git a/moon/src/app/blob/[...path]/page.tsx b/moon/src/app/blob/[...path]/page.tsx index 52197aa22..866cd41b5 100644 --- a/moon/src/app/blob/[...path]/page.tsx +++ b/moon/src/app/blob/[...path]/page.tsx @@ -27,7 +27,7 @@ export default function BlobPage({ params }: { params: { path: string[] } }) { } export async function getReadmeContent(pathname: string) { - const res = await fetch(`http://localhost:3000/api/blob/?path=/${pathname}`); + const res = await fetch(`http://localhost:3000/api/blob?path=${pathname}`); const response = await res.json(); const directory = response.data.data; return directory diff --git a/venus/src/import_repo/repo.rs b/venus/src/import_repo/repo.rs index 6addc4fc5..76c99faad 100644 --- a/venus/src/import_repo/repo.rs +++ b/venus/src/import_repo/repo.rs @@ -1,4 +1,7 @@ +use std::path::PathBuf; + use callisto::git_repo; +use common::utils::generate_id; /// The `repo` struct maintains the relationship between `repo_id` and `repo_path`. #[derive(PartialEq, Eq, Debug, Clone)] @@ -6,20 +9,18 @@ pub struct Repo { pub repo_id: i64, pub repo_path: String, pub repo_name: String, + pub is_monorepo: bool, } impl Repo { - pub fn from_path(path: &str) -> Self { + pub fn new(path: PathBuf, is_monorepo: bool) -> Self { Self { - repo_id: 0, - repo_path: path.to_owned(), - repo_name: String::new(), + repo_id: generate_id(), + repo_path: path.to_str().unwrap().to_owned(), + repo_name: path.file_name().unwrap().to_str().unwrap().to_owned(), + is_monorepo, } } - - pub fn monorepo(&self) -> bool { - self.repo_id == 0 - } } impl From for Repo { @@ -28,6 +29,7 @@ impl From for Repo { repo_id: value.id, repo_path: value.repo_path, repo_name: value.repo_name, + is_monorepo: false, } } } @@ -40,7 +42,6 @@ impl From for git_repo::Model { repo_name: value.repo_name, created_at: chrono::Utc::now().naive_utc(), updated_at: chrono::Utc::now().naive_utc(), - } } }