summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin Wernick <justin@worthe-it.co.za>2023-03-29 15:55:43 +0200
committerJustin Wernick <justin@worthe-it.co.za>2023-03-29 15:55:43 +0200
commit601c08b20bfb806d78fe92d9830960d1a333d5cf (patch)
tree28daf075e057595fbd817bf22eef3640aac8bd49 /src
parentff2a4b09646a8a5949808bfadf31747751831963 (diff)
Initial implementation of --init group
As the todo list indicates, it needs some security refinement.
Diffstat (limited to 'src')
-rw-r--r--src/git.rs49
-rw-r--r--src/lib.rs4
-rw-r--r--src/parser.rs2
3 files changed, 41 insertions, 14 deletions
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<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> {
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<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,
}