summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--readme.org5
-rw-r--r--src/git.rs49
-rw-r--r--src/lib.rs4
-rw-r--r--src/parser.rs2
-rw-r--r--tests/cli.rs3
5 files changed, 46 insertions, 17 deletions
diff --git a/readme.org b/readme.org
index 4b66459..4a06cd0 100644
--- a/readme.org
+++ b/readme.org
@@ -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
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,
}
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