diff options
author | Justin Wernick <justin@worthe-it.co.za> | 2023-03-29 15:55:43 +0200 |
---|---|---|
committer | Justin Wernick <justin@worthe-it.co.za> | 2023-03-29 15:55:43 +0200 |
commit | 601c08b20bfb806d78fe92d9830960d1a333d5cf (patch) | |
tree | 28daf075e057595fbd817bf22eef3640aac8bd49 | |
parent | ff2a4b09646a8a5949808bfadf31747751831963 (diff) |
Initial implementation of --init group
As the todo list indicates, it needs some security refinement.
-rw-r--r-- | readme.org | 5 | ||||
-rw-r--r-- | src/git.rs | 49 | ||||
-rw-r--r-- | src/lib.rs | 4 | ||||
-rw-r--r-- | src/parser.rs | 2 | ||||
-rw-r--r-- | tests/cli.rs | 3 |
5 files changed, 46 insertions, 17 deletions
@@ -30,7 +30,10 @@ Pijul. - [X] restrict repos to only acceptable paths - [X] clone / pull - [X] push -- [ ] git init of shared repos +- [-] git init of shared repos + - [X] create the shared repo in the right place + - [ ] use the right file permissions and config + - [ ] don't allow this to be a group the user isn't in - [ ] listing of repos - [ ] set repo descriptions - [ ] set the main branch of a repo @@ -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<PathBuf, ShackleError> { 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<bool, ShackleError> { 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<bool, ShackleError> { Ok(true) } -pub fn init(repo_name: &str) -> Result<GitInitResult, ShackleError> { - 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<String>) -> Result<GitInitResult, ShackleError> { + fn init_group(repo_name: &str, group: &str) -> Result<GitInitResult, ShackleError> { + 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<GitInitResult, ShackleError> { + 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> { @@ -15,8 +15,8 @@ pub fn run_command(user_input: String) -> Result<ControlFlow<(), ()>, 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<String>, pub repo_name: String, } diff --git a/tests/cli.rs b/tests/cli.rs index 872c2ce..85f9708 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -116,12 +116,11 @@ fn can_init_a_new_git_repo() -> Result<()> { } #[test] -#[ignore] fn can_init_a_new_shared_git_repo() -> Result<()> { let mut c = spawn_interactive_process()?; let group = get_user_groups().pop().unwrap(); let repo_name = "my-new-shared-repo"; - c.p.send_line(&format!("git-init --shared {} {}", group, repo_name))?; + c.p.send_line(&format!("git-init --group {} {}", group, repo_name))?; c.p.exp_string(&format!( "Successfully created \"git/{}/{}.git\"", group, repo_name |