diff --git a/crates/gitnow/src/commands/root.rs b/crates/gitnow/src/commands/root.rs index 3434dd9..e1ee289 100644 --- a/crates/gitnow/src/commands/root.rs +++ b/crates/gitnow/src/commands/root.rs @@ -111,18 +111,23 @@ impl RootCommand { } else { eprintln!("cloning repository..."); git_clone.clone_repo(&repo, force_refresh).await?; + + self.app + .custom_command() + .execute_post_update_command(&project_path) + .await?; } } else { tracing::info!("skipping clone for repo: {}", &repo.to_rel_path().display()); } } else { tracing::info!("repository already exists"); - } - self.app - .custom_command() - .execute_post_update_command(&project_path) - .await?; + self.app + .custom_command() + .execute_post_update_command(&project_path) + .await?; + } if shell { self.app.shell().spawn_shell(&repo).await?; diff --git a/crates/gitnow/src/config.rs b/crates/gitnow/src/config.rs index e796999..eabbfed 100644 --- a/crates/gitnow/src/config.rs +++ b/crates/gitnow/src/config.rs @@ -20,6 +20,7 @@ pub struct Settings { #[serde(default)] pub cache: Cache, + pub post_clone_command: Option, pub post_update_command: Option, } @@ -39,6 +40,22 @@ impl PostUpdateCommand { } } +#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)] +#[serde(untagged)] +pub enum PostCloneCommand { + Single(String), + Multiple(Vec), +} + +impl PostCloneCommand { + pub fn get_commands(&self) -> Vec { + match self.clone() { + PostCloneCommand::Single(item) => vec![item], + PostCloneCommand::Multiple(items) => items, + } + } +} + #[derive(Debug, Default, Serialize, Deserialize, PartialEq, Clone)] pub struct Projects { pub directory: ProjectLocation, diff --git a/crates/gitnow/src/custom_command.rs b/crates/gitnow/src/custom_command.rs index b47f07b..36d6e0d 100644 --- a/crates/gitnow/src/custom_command.rs +++ b/crates/gitnow/src/custom_command.rs @@ -11,6 +11,36 @@ impl CustomCommand { Self { config } } + pub async fn execute_post_clone_command(&self, path: &Path) -> anyhow::Result<()> { + if let Some(post_clone_command) = &self.config.settings.post_clone_command { + for command in post_clone_command.get_commands() { + let command_parts = command.split(' ').collect::>(); + let Some((first, rest)) = command_parts.split_first() else { + return Ok(()); + }; + + let mut cmd = tokio::process::Command::new(first); + cmd.args(rest).current_dir(path); + + eprintln!("running command: {}", command); + + tracing::info!( + path = path.display().to_string(), + cmd = command, + "running custom post clone command" + ); + let output = cmd.output().await?; + let stdout = std::str::from_utf8(&output.stdout)?; + tracing::info!( + stdout = stdout, + "finished running custom post clone command" + ); + } + } + + Ok(()) + } + pub async fn execute_post_update_command(&self, path: &Path) -> anyhow::Result<()> { if let Some(post_update_command) = &self.config.settings.post_update_command { for command in post_update_command.get_commands() {