From 3e8903a54667f24dd8e7f1b74d97ee772c032e64 Mon Sep 17 00:00:00 2001 From: Rosyid Haryadi Date: Sun, 16 Mar 2025 02:34:56 +0700 Subject: upd: git object & refactor: core -> repository --- src/core.rs | 73 ------------------------------------------------------- src/main.rs | 5 ++-- src/object.rs | 12 +++++++++ src/repository.rs | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/utilities.rs | 2 +- 5 files changed, 89 insertions(+), 76 deletions(-) delete mode 100644 src/core.rs create mode 100644 src/object.rs create mode 100644 src/repository.rs (limited to 'src') diff --git a/src/core.rs b/src/core.rs deleted file mode 100644 index 0b7065f..0000000 --- a/src/core.rs +++ /dev/null @@ -1,73 +0,0 @@ -use crate::utilities::{path_should_exist, path_should_not_exist, ConfigHashMap}; -use crate::{create_path_or_die, die}; -use configparser::ini::Ini; -use ini::ini; -use std::collections::HashMap; -use std::io::Write; -use std::path::PathBuf; - -pub struct GitRepository { - pub worktree: PathBuf, - gitdir: PathBuf, - conf: HashMap>> -} - -impl GitRepository { - pub fn new(worktree: PathBuf) -> Self { - let gitdir = worktree.join(".git"); - let conf: ConfigHashMap = HashMap::new(); - Self { worktree, gitdir, conf } - } - - pub fn from_dir(worktree: PathBuf) -> Self { - path_should_exist(&worktree, "Worktree does not exist"); - let gitdir = worktree.join(".git"); - path_should_exist(&gitdir, "Not a valid git repository"); - let conf_file = gitdir.join("config"); - path_should_exist(&conf_file, "Configuration file not found"); - let conf = ini!(conf_file.to_str().unwrap()); - let repo_format_version = conf["core"]["repositoryformatversion"].clone(); - if let Some(version) = repo_format_version { - if version != "0" { - die!("Unsupported format version"); - } - } else { - die!("Could not determine repository format version"); - } - - Self { - worktree, - gitdir, - conf - } - } - - pub fn create_new_repo(worktree: PathBuf) { - let repo = GitRepository::new(worktree); - path_should_not_exist(&repo.gitdir, "Already a git repository"); - - if !repo.worktree.exists() { - create_path_or_die!(dir: repo.worktree.clone(), "Could not create worktree"); - } - create_path_or_die!(dir: repo.gitdir.clone(), "Failed to initialize repository"); - create_path_or_die!(dir: repo.gitdir.clone().join("objects"), "Failed to create objects directory"); - create_path_or_die!(dir: repo.gitdir.clone().join("refs"), "Failed to create refs directory"); - create_path_or_die!(dir: repo.gitdir.clone().join("refs").join("heads"), "Failed to create git refs/head directory"); - create_path_or_die!(dir: repo.gitdir.clone().join("refs").join("tags"), "Failed to create git refs/tags directory"); - create_path_or_die!(file: repo.gitdir.clone().join("HEAD"), &"ref: refs/heads/master\n", "Failed to write HEAD file"); - create_path_or_die!( - file: repo.gitdir.clone().join("HEAD"), - "ref: refs/heads/master\n", - "Failed to write description file"); - - let mut config = Ini::new(); - config.set("core", "repositoryformatversion", Some("0".to_owned())); - config.set("core", "filemode", Some("false".to_owned())); - config.set("core", "bare", Some("false".to_owned())); - - if let Err(_) = config.write(repo.gitdir.join("config")) { - die!("Failed to write config file"); - } - println!("Git repository initialized in {}", repo.worktree.display()); - } -} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 8958192..a1c911c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,10 @@ -mod core; +mod repository; mod utilities; +mod object; use std::path::PathBuf; use clap::{Parser, Subcommand}; -use crate::core::GitRepository; +use crate::repository::GitRepository; #[derive(Parser)] #[command(version, about, long_about = None)] diff --git a/src/object.rs b/src/object.rs new file mode 100644 index 0000000..6374911 --- /dev/null +++ b/src/object.rs @@ -0,0 +1,12 @@ +enum GitObjectType { + Blob, + Commit, + Tag, + Tree, +} + +struct GitObject { + object_type: GitObjectType, + size: usize, + data: Vec, +} \ No newline at end of file diff --git a/src/repository.rs b/src/repository.rs new file mode 100644 index 0000000..6816d74 --- /dev/null +++ b/src/repository.rs @@ -0,0 +1,73 @@ +use crate::utilities::{path_should_exist, path_should_not_exist, ConfigHashMap}; +use crate::{create_path_or_die, die}; +use configparser::ini::Ini; +use ini::ini; +use std::collections::HashMap; +use std::io::Write; +use std::path::PathBuf; + +pub struct GitRepository { + pub worktree: PathBuf, + gitdir: PathBuf, + conf: HashMap>> +} + +impl GitRepository { + pub fn new(worktree: PathBuf) -> Self { + let gitdir = worktree.join(".git"); + let conf: ConfigHashMap = HashMap::new(); + Self { worktree, gitdir, conf } + } + + pub fn from_dir(worktree: PathBuf) -> Self { + path_should_exist(&worktree, "Worktree does not exist"); + let gitdir = worktree.join(".git"); + path_should_exist(&gitdir, "Not a valid git repository"); + let conf_file = gitdir.join("config"); + path_should_exist(&conf_file, "Configuration file not found"); + let conf = ini!(conf_file.to_str().unwrap()); + let repo_format_version = conf["core"]["repositoryformatversion"].clone(); + if let Some(version) = repo_format_version { + if version != "0" { + die!("Unsupported format version"); + } + } else { + die!("Could not determine repository format version"); + } + + Self { + worktree, + gitdir, + conf + } + } + + pub fn create_new_repo(worktree: PathBuf) { + let repo = GitRepository::new(worktree); + path_should_not_exist(&repo.gitdir, "Already a git repository"); + + if !repo.worktree.exists() { + create_path_or_die!(dir: repo.worktree.clone(), "Could not create worktree"); + } + create_path_or_die!(dir: repo.gitdir.clone(), "Failed to initialize repository"); + create_path_or_die!(dir: repo.gitdir.clone().join("objects"), "Failed to create objects directory"); + create_path_or_die!(dir: repo.gitdir.clone().join("refs"), "Failed to create refs directory"); + create_path_or_die!(dir: repo.gitdir.clone().join("refs").join("heads"), "Failed to create git refs/head directory"); + create_path_or_die!(dir: repo.gitdir.clone().join("refs").join("tags"), "Failed to create git refs/tags directory"); + create_path_or_die!(file: repo.gitdir.clone().join("HEAD"), "ref: refs/heads/master\n", "Failed to write HEAD file"); + create_path_or_die!( + file: repo.gitdir.clone().join("HEAD"), + "ref: refs/heads/master\n", + "Failed to write description file"); + + let mut config = Ini::new(); + config.set("core", "repositoryformatversion", Some("0".to_owned())); + config.set("core", "filemode", Some("false".to_owned())); + config.set("core", "bare", Some("false".to_owned())); + + if let Err(_) = config.write(repo.gitdir.join("config")) { + die!("Failed to write config file"); + } + println!("Git repository initialized in {}", repo.worktree.display()); + } +} \ No newline at end of file diff --git a/src/utilities.rs b/src/utilities.rs index 1357cdf..bc78495 100644 --- a/src/utilities.rs +++ b/src/utilities.rs @@ -21,7 +21,7 @@ macro_rules! create_path_or_die { (file: $path:expr, $content:expr, $message:expr) => { if let Ok(mut file) = std::fs::File::create($path) { - if let Err(e) = file.write_all($content.as_ref()) { + if let Err(e) = write!(file, $content) { die!(format!("{}\nError: {}", $message, e.to_string())); } } else { -- cgit v1.2.3-70-g09d2