diff --git a/atlas/README.md b/atlas/README.md new file mode 100644 index 00000000..aa83442e --- /dev/null +++ b/atlas/README.md @@ -0,0 +1 @@ +## Atlas Module diff --git a/jupiter/Cargo.toml b/jupiter/Cargo.toml index 2eafd277..cad0c26e 100644 --- a/jupiter/Cargo.toml +++ b/jupiter/Cargo.toml @@ -14,6 +14,7 @@ path = "src/lib.rs" callisto = { workspace = true } common = { workspace = true } mercury = { workspace = true } + sea-orm = { workspace = true, features = [ "sqlx-postgres", "sqlx-mysql", diff --git a/jupiter/README.md b/jupiter/README.md index e695256b..01cee69f 100644 --- a/jupiter/README.md +++ b/jupiter/README.md @@ -1 +1 @@ -## Jupiter Module \ No newline at end of file +## Jupiter Module - Monorepo and Mega Database Storage Engine diff --git a/jupiter/callisto/Cargo.toml b/jupiter/callisto/Cargo.toml index ee7fb1e9..3cad4c41 100644 --- a/jupiter/callisto/Cargo.toml +++ b/jupiter/callisto/Cargo.toml @@ -9,8 +9,6 @@ name = "callisto" path = "src/lib.rs" [dependencies] -common = { workspace = true } - serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } chrono = { workspace = true } diff --git a/jupiter/callisto/README.md b/jupiter/callisto/README.md new file mode 100644 index 00000000..dd6dc52a --- /dev/null +++ b/jupiter/callisto/README.md @@ -0,0 +1 @@ +### Callisto - ORM Model for Mega diff --git a/jupiter/src/lfs_storage/mod.rs b/jupiter/src/lfs_storage/mod.rs index a6e3bba7..a40dc8c3 100644 --- a/jupiter/src/lfs_storage/mod.rs +++ b/jupiter/src/lfs_storage/mod.rs @@ -22,15 +22,9 @@ pub struct BlobLink { #[async_trait] pub trait LfsStorage: Sync + Send { - async fn get_ref(&self, repo_id: i64, ref_name: &str) -> Result; - async fn put_ref( - &self, - repo_id: i64, - ref_name: &str, - ref_hash: &str, - ) -> Result<(), MegaError>; + async fn put_ref(&self, repo_id: i64, ref_name: &str, ref_hash: &str) -> Result<(), MegaError>; async fn delete_ref(&self, repo_id: i64, ref_name: &str) -> Result<(), MegaError>; @@ -43,57 +37,7 @@ pub trait LfsStorage: Sync + Send { async fn get_object(&self, object_id: &str) -> Result; - async fn put_object( - &self, - object_id: &str, - body_content: &[u8], - ) -> Result; - - // async fn parse_blob_link(&self, data: Vec) -> Result { - // let mut reader = BufReader::new(data.as_slice()); - // let mut blink = BlobLink::default(); - // // for line in reader.lines() { - // // let str = line.unwrap(); - // // } - // let mut buf = String::new(); - // reader.read_line(&mut buf).unwrap(); - // blink.version = buf.split_whitespace().next(); - // let result = self.get_by_path(&blink.storge_location).await.unwrap(); - // Ok(blink) - // } - - // save a entry and return the b_link file - // async fn convert_blink(&self, entry: &Entry) -> Result, MegaError> { - // let location = self - // .put_object( &entry.hash.to_plain_str(), &entry.data) - // .await - // .unwrap(); - // let handlebars = Handlebars::new(); - - // let path = env::current_dir().unwrap().join("b_link.txt"); - // let mut file = File::open(path).unwrap(); - // let mut template = String::new(); - // file.read_to_string(&mut template).unwrap(); - - // let mut context = serde_json::Map::new(); - // context.insert( - // "objectType".to_string(), - // serde_json::json!(entry.obj_type.to_string()), - // ); - // context.insert( - // "sha1".to_string(), - // serde_json::json!(entry.hash.to_plain_str()), - // ); - // context.insert( - // "type".to_string(), - // serde_json::json!(self.get_storage_type().to_string()), - // ); - // context.insert("location".to_string(), serde_json::json!(location)); - - // let rendered = handlebars.render_template(&template, &context).unwrap(); - - // Ok(rendered.into_bytes()) - // } + async fn put_object(&self, object_id: &str, body_content: &[u8]) -> Result; fn exist_object(&self, object_id: &str) -> bool; @@ -113,9 +57,7 @@ pub trait LfsStorage: Sync + Send { pub async fn init(storage_type: String, base_path: PathBuf) -> Arc { match storage_type.as_str() { - "LOCAL" => { - Arc::new(LocalStorage::init(base_path)) - } + "LOCAL" => Arc::new(LocalStorage::init(base_path)), // "REMOTE" => Arc::new(RemoteStorage::init(path).await), _ => unreachable!( "Not supported config, MEGA_OBJ_STORAGE_TYPE should be 'LOCAL' or 'REMOTE'" diff --git a/mega/Cargo.toml b/mega/Cargo.toml index 29241623..b4a47efc 100644 --- a/mega/Cargo.toml +++ b/mega/Cargo.toml @@ -19,6 +19,7 @@ gateway = { workspace = true } common = { workspace = true } ceres = { workspace = true } taurus = { workspace = true } + serde = { workspace = true, features = ["derive"] } tokio = { workspace = true, features = ["macros"] } clap = { workspace = true, features = ["derive"] } diff --git a/mercury/Cargo.toml b/mercury/Cargo.toml index 01eabf62..0ce83935 100644 --- a/mercury/Cargo.toml +++ b/mercury/Cargo.toml @@ -9,6 +9,7 @@ edition = "2021" delta = { path = "delta" } common = { workspace = true } callisto = { workspace = true } + flate2 = { workspace = true, features = [ "zlib", ] } # enable linking against the libz(C lib); better performance diff --git a/mercury/README.md b/mercury/README.md index 713d8838..e072f9f2 100644 --- a/mercury/README.md +++ b/mercury/README.md @@ -1 +1 @@ -## Mercury Module \ No newline at end of file +## Mercury Module - Git Internal Module diff --git a/mercury/src/internal/object/mod.rs b/mercury/src/internal/object/mod.rs index 01c9d7b7..e79d5117 100644 --- a/mercury/src/internal/object/mod.rs +++ b/mercury/src/internal/object/mod.rs @@ -12,9 +12,12 @@ use std::{ str::FromStr, }; -use callisto::{git_blob, git_commit, git_tag, git_tree, mega_blob, mega_commit, mega_tag, mega_tree, raw_blob}; use sha1::Digest; +use callisto::{ + git_blob, git_commit, git_tag, git_tree, mega_blob, mega_commit, mega_tag, mega_tree, raw_blob, +}; + use crate::internal::object::types::ObjectType; use crate::internal::object::{blob::Blob, commit::Commit, tag::Tag, tree::Tree}; use crate::internal::zlib::stream::inflate::ReadBoxed; @@ -37,7 +40,11 @@ pub trait ObjectTrait: Send + Sync + Display { read.read_to_end(&mut content).unwrap(); let h = read.hash.clone(); let hash_str = h.finalize(); - Self::from_bytes(&content, SHA1::from_str(&format!("{:x}", hash_str)).unwrap()).unwrap() + Self::from_bytes( + &content, + SHA1::from_str(&format!("{:x}", hash_str)).unwrap(), + ) + .unwrap() } /// Returns the type of the object. diff --git a/mercury/src/internal/pack/cache.rs b/mercury/src/internal/pack/cache.rs index 06344a4d..1d027882 100644 --- a/mercury/src/internal/pack/cache.rs +++ b/mercury/src/internal/pack/cache.rs @@ -1,4 +1,3 @@ - use std::path::Path; use std::path::PathBuf; use std::sync::atomic::{AtomicBool, Ordering}; @@ -6,15 +5,13 @@ use std::sync::{Arc, Mutex}; use std::thread::sleep; use std::{fs, io}; -use crate::internal::pack::cache_object::{ArcWrapper, CacheObject, MemSizeRecorder}; -use crate::time_it; use dashmap::{DashMap, DashSet}; use lru_mem::LruCache; use threadpool::ThreadPool; -use crate::hash::SHA1; - -use super::cache_object::FileLoadStore; +use crate::time_it; +use crate::hash::SHA1; +use crate::internal::pack::cache_object::{ArcWrapper, CacheObject, MemSizeRecorder, FileLoadStore}; pub trait _Cache { fn new(mem_size: Option, tmp_path: PathBuf, thread_num: usize) -> Self diff --git a/mercury/src/internal/pack/cache_object.rs b/mercury/src/internal/pack/cache_object.rs index 2e776666..ff8e1c01 100644 --- a/mercury/src/internal/pack/cache_object.rs +++ b/mercury/src/internal/pack/cache_object.rs @@ -5,10 +5,11 @@ use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use std::{fs, io}; use std::{ops::Deref, sync::Arc}; -use crate::internal::pack::utils; use lru_mem::{HeapSize, MemSize}; use serde::{Deserialize, Serialize}; use threadpool::ThreadPool; + +use crate::internal::pack::utils; use crate::{hash::SHA1, internal::object::types::ObjectType}; use crate::internal::pack::entry::Entry; diff --git a/mercury/src/internal/pack/decode.rs b/mercury/src/internal/pack/decode.rs index ab306024..c1f7e696 100644 --- a/mercury/src/internal/pack/decode.rs +++ b/mercury/src/internal/pack/decode.rs @@ -5,24 +5,24 @@ use std::sync::{Arc, mpsc}; use std::sync::mpsc::{Receiver, Sender}; use std::thread::{self, JoinHandle}; use std::time::Instant; + use axum::Error; use bytes::Bytes; - use flate2::bufread::ZlibDecoder; use futures_util::{Stream, StreamExt}; use threadpool::ThreadPool; +use uuid::Uuid; use crate::errors::GitError; use crate::hash::SHA1; use crate::internal::object::types::ObjectType; -use super::cache::_Cache; use crate::internal::pack::cache::Caches; +use crate::internal::pack::cache::_Cache; use crate::internal::pack::cache_object::{CacheObject, MemSizeRecorder}; use crate::internal::pack::waitlist::Waitlist; use crate::internal::pack::wrapper::Wrapper; use crate::internal::pack::{utils, Pack, DEFAULT_TMP_DIR}; -use uuid::Uuid; use crate::internal::pack::channel_reader::ChannelReader; use crate::internal::pack::entry::Entry; @@ -458,7 +458,7 @@ impl Pack { // if self.clean_tmp { // self.caches.remove_tmp_dir(); // } - + Ok(()) } diff --git a/mercury/src/internal/pack/entry.rs b/mercury/src/internal/pack/entry.rs index 6b2aa830..416ebaf6 100644 --- a/mercury/src/internal/pack/entry.rs +++ b/mercury/src/internal/pack/entry.rs @@ -1,4 +1,5 @@ use std::hash::{Hash, Hasher}; + use serde::{Deserialize, Serialize}; use crate::hash::SHA1; diff --git a/mercury/src/internal/pack/mod.rs b/mercury/src/internal/pack/mod.rs index 8b11af0e..aeab750a 100644 --- a/mercury/src/internal/pack/mod.rs +++ b/mercury/src/internal/pack/mod.rs @@ -1,4 +1,4 @@ -//! +//! //! ## Reference //! 1. Git Pack-Format [Introduce](https://git-scm.com/docs/pack-format) //! @@ -12,14 +12,14 @@ pub mod cache_object; pub mod entry; pub mod channel_reader; -use crate::hash::SHA1; use threadpool::ThreadPool; use std::sync::Arc; use std::sync::atomic::AtomicUsize; + +use crate::hash::SHA1; use crate::internal::object::ObjectTrait; use crate::internal::pack::waitlist::Waitlist; - -use self::cache::Caches; +use crate::internal::pack::cache::Caches; const DEFAULT_TMP_DIR: &str = "./.cache_temp"; pub struct Pack { @@ -36,4 +36,4 @@ pub struct Pack { #[cfg(test)] mod tests { -} \ No newline at end of file +} diff --git a/mercury/src/internal/pack/utils.rs b/mercury/src/internal/pack/utils.rs index daf45f5f..d2c6fb6b 100644 --- a/mercury/src/internal/pack/utils.rs +++ b/mercury/src/internal/pack/utils.rs @@ -2,26 +2,27 @@ use std::fs; use std::io::{self, Read}; use std::path::Path; use sha1::{Digest, Sha1}; + use crate::hash::SHA1; use crate::internal::object::types::ObjectType; /// Checks if the reader has reached EOF (end of file). -/// +/// /// It attempts to read a single byte from the reader into a buffer. -/// If `Ok(0)` is returned, it means no byte was read, indicating +/// If `Ok(0)` is returned, it means no byte was read, indicating /// that the end of the stream has been reached and there is no more /// data left to read. /// /// Any other return value means that data was successfully read, so -/// the reader has not reached the end yet. +/// the reader has not reached the end yet. /// /// # Arguments -/// -/// * `reader` - The reader to check for EOF state +/// +/// * `reader` - The reader to check for EOF state /// It must implement the `std::io::Read` trait /// -/// # Returns -/// +/// # Returns +/// /// true if the reader reached EOF, false otherwise #[allow(unused)] pub fn is_eof(reader: &mut dyn Read) -> bool { @@ -102,7 +103,7 @@ pub fn read_type_and_varint_size(stream: &mut R, offset: &mut usize) -> } /// Reads a variable-length integer (VarInt) encoded in little-endian format from a source implementing the Read trait. -/// +/// /// The VarInt encoding uses the most significant bit (MSB) of each byte as a continuation bit. /// The continuation bit being 1 indicates that there are following bytes. /// The actual integer value is encoded in the remaining 7 bits of each byte. @@ -122,7 +123,7 @@ pub fn read_varint_le(reader: &mut R) -> io::Result<(u64, usize)> { // Bit shift for the next byte let mut shift = 0; // Number of bytes read - let mut offset = 0; + let mut offset = 0; loop { // A buffer to read a single byte @@ -131,19 +132,19 @@ pub fn read_varint_le(reader: &mut R) -> io::Result<(u64, usize)> { reader.read_exact(&mut buf)?; // The byte just read - let byte = buf[0]; - if shift > 63 { + let byte = buf[0]; + if shift > 63 { // VarInt too long for u64 return Err(io::Error::new(io::ErrorKind::InvalidData, "VarInt too long")); } // Take the lower 7 bits of the byte - let byte_value = (byte & 0x7F) as u64; + let byte_value = (byte & 0x7F) as u64; // Add the byte value to the result, considering the shift - value |= byte_value << shift; + value |= byte_value << shift; // Increment the byte count - offset += 1; + offset += 1; // Check if the MSB is 0 (last byte) if byte & 0x80 == 0 { break; @@ -315,7 +316,7 @@ mod tests { assert!(is_eof(&mut reader)); } - #[test] + #[test] fn not_eof() { let mut reader = Cursor::new(&b"abc"[..]); assert!(!is_eof(&mut reader)); @@ -336,9 +337,9 @@ mod tests { Err(io::Error::new(io::ErrorKind::Other, "error")) } } - + let mut reader = BrokenReader; - assert!(!is_eof(&mut reader)); + assert!(!is_eof(&mut reader)); } // Test case for a byte without a continuation bit (most significant bit is 0) @@ -423,7 +424,7 @@ mod tests { assert_eq!(offset, 1); // Offset is 1 assert_eq!(type_bits, 1); // Expected type is 1 - // Expected size is 15 + // Expected size is 15 assert_eq!(size, 15); } @@ -483,7 +484,7 @@ mod tests { assert!(result.is_err()); } - + #[test] fn test_read_offset_encoding(){ let data:Vec = vec![0b_1101_0101,0b_0000_0101]; @@ -492,4 +493,4 @@ mod tests { assert!(result.is_ok()); assert_eq!(result.unwrap(), (11013, 2)); } -} \ No newline at end of file +} diff --git a/mono/src/main.rs b/mono/src/main.rs index 0d7c8ece..ee1a28e4 100644 --- a/mono/src/main.rs +++ b/mono/src/main.rs @@ -1,12 +1,15 @@ -//! Mega is an engine for managing a monorepo. It functions similarly to Google's Piper and helps to streamline Git -//! and trunk-based development for large-scale projects. And this is the main entry point for the application. +//! Mono is an engine for managing a monorepo. It functions similarly to Google's Piper and helps to streamline Git +//! and trunk-based development for large-scale projects. +//! +//! And this is the main entry point for the application. use shadow_rs::shadow; shadow!(build); -pub mod api; mod cli; mod commands; + +pub mod api; pub mod git_protocol; pub mod server; diff --git a/moon/package.json b/moon/package.json index bf0379a3..ea9f73b7 100644 --- a/moon/package.json +++ b/moon/package.json @@ -11,19 +11,20 @@ "dependencies": { "@ant-design/icons": "^5.4.0", "@ant-design/nextjs-registry": "^1.0.1", - "@headlessui/react": "^2.1.3", + "@headlessui/react": "^2.1.6", "@headlessui/tailwindcss": "^0.2.1", "@heroicons/react": "^2.1.5", - "@lexical/react": "^0.17.0", - "@tailwindcss/forms": "^0.5.7", + "@lexical/react": "^0.17.1", + "@tailwindcss/forms": "^0.5.9", "clsx": "^2.1.1", + "copy-to-clipboard": "^3.3.3", "date-fns": "^3.6.0", - "framer-motion": "^11.3.19", + "framer-motion": "^11.5.3", "github-markdown-css": "^5.6.1", "highlight.js": "^11.10.0", - "lexical": "^0.17.0", - "next": "^14.2.6", - "prism-react-renderer": "^2.3.1", + "lexical": "^0.17.1", + "next": "^14.2.9", + "prism-react-renderer": "^2.4.0", "react": "^18.3.1", "react-dom": "^18.3.1", "react-markdown": "^9.0.1" diff --git a/moon/src/app/(dashboard)/application-layout.tsx b/moon/src/app/(dashboard)/application-layout.tsx index 826c8a5e..8d903a0c 100644 --- a/moon/src/app/(dashboard)/application-layout.tsx +++ b/moon/src/app/(dashboard)/application-layout.tsx @@ -187,7 +187,7 @@ export function ApplicationLayout({ - + {user.name} diff --git a/moon/src/app/(dashboard)/tree/[...path]/page.tsx b/moon/src/app/(dashboard)/tree/[...path]/page.tsx index ce595323..52d7a514 100644 --- a/moon/src/app/(dashboard)/tree/[...path]/page.tsx +++ b/moon/src/app/(dashboard)/tree/[...path]/page.tsx @@ -3,6 +3,7 @@ import CodeTable from '@/components/CodeTable' import Bread from '@/components/BreadCrumb' import RepoTree from '@/components/RepoTree' +import CloneTabs from '@/components/CloneTabs' import { useEffect, useState } from 'react' import { Flex, Layout } from "antd/lib"; @@ -51,6 +52,9 @@ export default function Page({ params }: { params: { path: string[] } }) { + + + diff --git a/moon/src/components/CloneTabs.tsx b/moon/src/components/CloneTabs.tsx new file mode 100644 index 00000000..754a5cc6 --- /dev/null +++ b/moon/src/components/CloneTabs.tsx @@ -0,0 +1,70 @@ +import React, { useEffect, useState } from 'react'; +import { Tabs, TabsProps, Button, Space, Popover, Input } from 'antd'; +import { + CodeBracketIcon, +} from '@heroicons/react/16/solid' +import copy from 'copy-to-clipboard'; +import { CopyOutlined, CheckOutlined, DownloadOutlined } from '@ant-design/icons'; +import { usePathname } from 'next/navigation'; + + +const CloneTabs: React.FC = () => { + const pathname = usePathname(); + const [text, setText] = useState(pathname); + const [copied, setCopied] = useState(false); + const [active_tab, setActiveTab] = useState('1') + + const onChange = (key: string) => { + setActiveTab(key) + }; + + useEffect(() => { + if (typeof window !== 'undefined') { + const domain = window.location.origin; + if (active_tab === '1') { + setText(`${domain}${pathname.replace('/tree', '')}.git`); + } else { + setText(`ssh://git@${window.location.hostname}:${pathname.replace('/tree', '')}.git`); + } + } + }, [pathname, active_tab]); + + + + const handleCopy = () => { + copy(text); + setCopied(true); + setTimeout(() => setCopied(false), 2000); // Reset after 2 seconds + }; + + const tab_items: TabsProps['items'] = [ + { + key: '1', + label: 'HTTP', + children: + + + + + ) + +} + +export default CloneTabs; diff --git a/scripts/crates-sync/crates-sync.py b/scripts/crates-sync/crates-sync.py index c9e2a5d9..e710c656 100755 --- a/scripts/crates-sync/crates-sync.py +++ b/scripts/crates-sync/crates-sync.py @@ -1,12 +1,12 @@ -import os # For file and directory operations -import sys # For system-specific parameters and functions -import json # For JSON parsing -import urllib.request # For downloading files from URLs -import tarfile # For handling tar archives -import subprocess # For running system commands -import shutil # For high-level file operations -from collections import defaultdict # For creating dictionaries with default values -from packaging import version # For parsing and comparing version numbers +import os +import sys +import json +import urllib.request +import tarfile +import subprocess +import shutil +from collections import defaultdict +from packaging import version def ensure_directory(path): # Create a directory if it doesn't exist @@ -77,8 +77,20 @@ def filter_member(tarinfo, filterpath): print(f"Warning: Empty crate file {crate_path}. Skipping extraction.") return False - # Extract directly to the target directory - safe_extract(tar, extract_path) + # Create a temporary directory for extraction + temp_extract_path = extract_path + "_temp" + ensure_directory(temp_extract_path) + + # Extract to the temporary directory + safe_extract(tar, temp_extract_path) + + # Move contents from the nested directory to the target directory + nested_dir = os.path.join(temp_extract_path, os.listdir(temp_extract_path)[0]) + for item in os.listdir(nested_dir): + shutil.move(os.path.join(nested_dir, item), extract_path) + + # Remove the temporary directory + shutil.rmtree(temp_extract_path) print(f"Extracted version to {extract_path}") return True