From 601c08b20bfb806d78fe92d9830960d1a333d5cf Mon Sep 17 00:00:00 2001 From: Justin Wernick Date: Wed, 29 Mar 2023 15:55:43 +0200 Subject: Initial implementation of --init group As the todo list indicates, it needs some security refinement. --- src/git.rs | 49 +++++++++++++++++++++++++++++++++++++------------ src/lib.rs | 4 ++-- src/parser.rs | 2 ++ 3 files changed, 41 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/git.rs b/src/git.rs index b4eb3b2..c61bec1 100644 --- a/src/git.rs +++ b/src/git.rs @@ -2,7 +2,7 @@ use crate::{ parser::{GitReceivePackArgs, GitUploadPackArgs}, ShackleError, }; -use git2::{Repository, RepositoryInitOptions}; +use git2::{Repository, RepositoryInitMode, RepositoryInitOptions}; use std::{ path::{Path, PathBuf}, process::Command, @@ -18,6 +18,10 @@ fn personal_git_dir() -> Result { Ok(Path::new("git").join(username)) } +fn group_git_dir(group: &str) -> PathBuf { + Path::new("git").join(group) +} + fn is_valid_personal_git_repo(path: &PathBuf) -> Result { let valid_dir = personal_git_dir()?; let relative_path = match path.strip_prefix(&valid_dir) { @@ -36,17 +40,38 @@ fn is_valid_personal_git_repo(path: &PathBuf) -> Result { Ok(true) } -pub fn init(repo_name: &str) -> Result { - let path = personal_git_dir()?.join(repo_name).with_extension("git"); - - Repository::init_opts( - &path, - &RepositoryInitOptions::new() - .bare(true) - .mkdir(true) - .no_reinit(true), - )?; - Ok(GitInitResult { path }) +pub fn init(repo_name: &str, group: &Option) -> Result { + fn init_group(repo_name: &str, group: &str) -> Result { + let path = group_git_dir(group).join(repo_name).with_extension("git"); + + Repository::init_opts( + &path, + &RepositoryInitOptions::new() + .bare(true) + .mode(RepositoryInitMode::SHARED_GROUP) + .mkdir(true) + .no_reinit(true), + )?; + Ok(GitInitResult { path }) + } + + fn init_personal(repo_name: &str) -> Result { + let path = personal_git_dir()?.join(repo_name).with_extension("git"); + + Repository::init_opts( + &path, + &RepositoryInitOptions::new() + .bare(true) + .mkdir(true) + .no_reinit(true), + )?; + Ok(GitInitResult { path }) + } + + match group { + Some(group) => init_group(repo_name, group), + None => init_personal(repo_name), + } } pub fn upload_pack(upload_pack_args: &GitUploadPackArgs) -> Result<(), ShackleError> { diff --git a/src/lib.rs b/src/lib.rs index 5e33302..c2eccbf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,8 +15,8 @@ pub fn run_command(user_input: String) -> Result, ShackleErr Ok(ShackleCommand::Exit) => { return Ok(ControlFlow::Break(())); } - Ok(ShackleCommand::GitInit(GitInitArgs { repo_name })) => { - let init_result = git::init(&repo_name)?; + Ok(ShackleCommand::GitInit(GitInitArgs { repo_name, group })) => { + let init_result = git::init(&repo_name, &group)?; println!("Successfully created \"{}\"", init_result.path.display()); } Ok(ShackleCommand::GitUploadPack(upload_pack_args)) => { diff --git a/src/parser.rs b/src/parser.rs index 55a2be9..700414c 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -18,6 +18,8 @@ pub enum ShackleCommand { #[derive(Parser, Clone, Debug, PartialEq, Eq)] pub struct GitInitArgs { + #[arg(long)] + pub group: Option, pub repo_name: String, } -- cgit v1.2.3