use crate::command::{CommandExecutor, GitCommand};
use crate::error::Result;
use crate::repo::Repository;
use async_trait::async_trait;
use std::path::PathBuf;
#[derive(Debug, Clone, Default)]
pub struct InitCommand {
pub executor: CommandExecutor,
pub directory: Option<PathBuf>,
pub bare: bool,
pub quiet: bool,
pub initial_branch: Option<String>,
pub shared: Option<String>,
pub template: Option<PathBuf>,
pub separate_git_dir: Option<PathBuf>,
}
impl InitCommand {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn in_directory(path: impl Into<PathBuf>) -> Self {
Self {
directory: Some(path.into()),
..Self::default()
}
}
pub fn bare(&mut self) -> &mut Self {
self.bare = true;
self
}
pub fn quiet(&mut self) -> &mut Self {
self.quiet = true;
self
}
pub fn initial_branch(&mut self, name: impl Into<String>) -> &mut Self {
self.initial_branch = Some(name.into());
self
}
pub fn shared(&mut self, mode: impl Into<String>) -> &mut Self {
self.shared = Some(mode.into());
self
}
pub fn template(&mut self, path: impl Into<PathBuf>) -> &mut Self {
self.template = Some(path.into());
self
}
pub fn separate_git_dir(&mut self, path: impl Into<PathBuf>) -> &mut Self {
self.separate_git_dir = Some(path.into());
self
}
}
#[async_trait]
impl GitCommand for InitCommand {
type Output = Repository;
fn get_executor(&self) -> &CommandExecutor {
&self.executor
}
fn get_executor_mut(&mut self) -> &mut CommandExecutor {
&mut self.executor
}
fn build_command_args(&self) -> Vec<String> {
let mut args = vec!["init".to_string()];
if self.bare {
args.push("--bare".into());
}
if self.quiet {
args.push("--quiet".into());
}
if let Some(branch) = &self.initial_branch {
args.push(format!("--initial-branch={branch}"));
}
if let Some(mode) = &self.shared {
args.push(format!("--shared={mode}"));
}
if let Some(t) = &self.template {
args.push(format!("--template={}", t.display()));
}
if let Some(g) = &self.separate_git_dir {
args.push(format!("--separate-git-dir={}", g.display()));
}
if let Some(d) = &self.directory {
args.push(d.display().to_string());
}
args
}
async fn execute(&self) -> Result<Repository> {
self.execute_raw().await?;
let path = self
.directory
.clone()
.or_else(|| self.executor.cwd.clone())
.unwrap_or_else(|| std::env::current_dir().unwrap_or_default());
Ok(Repository::new_unchecked(path))
}
}