diff --git a/sc.toml b/sc.toml index aa77a01..98db413 100644 --- a/sc.toml +++ b/sc.toml @@ -1,5 +1,9 @@ -# Generated automatically by CLI - [[scopes]] name = "core" description = "the core of the repo" + +[[scopes]] +name = "tools" + +[[scopes]] +name = "cli" diff --git a/src/config/cli.rs b/src/config/cli.rs index 8a5fdbc..243125b 100644 --- a/src/config/cli.rs +++ b/src/config/cli.rs @@ -13,9 +13,6 @@ pub struct CliConfig { #[clap(long, help = "set custom path to load config.")] pub(super) config: Option, - #[clap(short, long)] - pub(super) message: Option, - #[clap(flatten)] pub(super) sc_config: SimpleCommitsConfig, @@ -43,6 +40,10 @@ pub struct SimpleCommitsConfig { #[clap(skip)] pub config: PathBuf, + #[clap(short, long)] + #[serde(skip)] + pub message: Option, + #[clap(skip)] #[serde(flatten)] #[merge(strategy = swap_option)] diff --git a/src/tui/mod.rs b/src/tui/mod.rs index ba93261..9730260 100644 --- a/src/tui/mod.rs +++ b/src/tui/mod.rs @@ -30,7 +30,6 @@ pub fn init() { #[derive(Clone, Default, Debug)] pub struct AppData { pub commit: CommitBuilder, - pub action: Action, } #[allow(dead_code)] @@ -61,10 +60,10 @@ impl Action { pub type StepResult = Result<(), Error>; /// A trait to setup steps along the TUI app. -#[allow(dead_code)] + pub trait Step { fn before_run( - &self, + &mut self, _prompt: &mut Promptuity, _state: &mut AppData, _config: &mut SimpleCommitsConfig, @@ -73,7 +72,7 @@ pub trait Step { } fn after_run( - &self, + &mut self, _prompt: &mut Promptuity, _state: &mut AppData, _config: &mut SimpleCommitsConfig, @@ -82,7 +81,7 @@ pub trait Step { } fn run( - &self, + &mut self, prompt: &mut Promptuity, state: &mut AppData, config: &mut SimpleCommitsConfig, @@ -91,11 +90,11 @@ pub trait Step { #[macro_export] macro_rules! gen_steps { - ($($module:ident),*) => { + ($($struct:ty),*) => { { let steps: Vec> = vec![ $( - Box::new(self::$module::_Step), + Box::new(<$struct>::default()), )* ]; steps diff --git a/src/tui/steps/commit.rs b/src/tui/steps/commit.rs index 7fca0b3..4feb30d 100644 --- a/src/tui/steps/commit.rs +++ b/src/tui/steps/commit.rs @@ -9,11 +9,11 @@ use crate::{ }; #[derive(Default)] -pub struct _Step; +pub struct Definition; -impl Step for _Step { +impl Step for Definition { fn run( - &self, + &mut self, p: &mut Promptuity, state: &mut crate::tui::AppData, _: &mut SimpleCommitsConfig, diff --git a/src/tui/steps/emoji.rs b/src/tui/steps/emoji.rs index 70e5e66..399c541 100644 --- a/src/tui/steps/emoji.rs +++ b/src/tui/steps/emoji.rs @@ -6,18 +6,32 @@ use crate::tui::widgets::{Autocomplete, AutocompletePriority}; use crate::tui::{Step, StepResult}; #[derive(Default)] -pub struct _Step; +pub struct Emoji { + skip: bool, +} + +impl Step for Emoji { + fn before_run( + &mut self, + _: &mut promptuity::Promptuity, + _: &mut crate::tui::AppData, + config: &mut SimpleCommitsConfig, + ) -> StepResult { + self.skip = config.git.as_ref().is_some_and(|cfg| cfg.skip_emojis); + + Ok(()) + } -impl Step for _Step { fn run( - &self, + &mut self, p: &mut promptuity::Promptuity, state: &mut crate::tui::AppData, - config: &mut SimpleCommitsConfig, + _: &mut SimpleCommitsConfig, ) -> StepResult { - if config.git.as_ref().is_some_and(|cfg| cfg.skip_emojis) { + if self.skip { return Ok(()); } + let emojis_mapped = EMOJIS .map(|emoji| { SelectOption::new( diff --git a/src/tui/steps/exec.rs b/src/tui/steps/exec.rs index dda8bfd..31b3a84 100644 --- a/src/tui/steps/exec.rs +++ b/src/tui/steps/exec.rs @@ -11,44 +11,66 @@ use crate::{ }; #[derive(Default)] -pub struct _Step; +pub struct Execute { + skip: bool, + action: Action, + cmd: Vec, +} -impl Step for _Step { - fn run( - &self, - p: &mut Promptuity, +impl Step for Execute { + fn before_run( + &mut self, + _: &mut Promptuity, state: &mut crate::tui::AppData, config: &mut SimpleCommitsConfig, ) -> StepResult { + self.skip = config + .git + .as_ref() + .map(|cfg| cfg.skip_preview) + .unwrap_or(false); + let commit = state.commit.clone().build()?; - let mut command = vec![ - "git".to_string(), - "commit".to_string(), - "-m".to_string(), - format!("{0}", commit.0), - ]; - let cmd = command.first().expect("unreachable!").clone(); - if let Some(git) = &config.git { - command = git - .commit_template - .as_ref() - .map(|msg| { - msg.iter() - .map(|m| m.replace("{{message}}", &commit.0.to_string())) - .collect::>() - }) - .unwrap_or(command); - let cmd = command - .first() - .expect("The commit template cannot be empty"); - if git.skip_preview { - state.action = Action::Commit(cmd.clone(), (command[1..]).to_vec()); - state.action.execute_action(); - return Ok(()); + let command = { + let base = ["git", "commit", "-m", &commit.0] + .iter() + .map(|s| String::from(*s)) + .collect::>(); + + if let Some(cfg) = &config.git { + cfg.commit_template.as_ref().map_or_else( + || base, + |cfg| { + cfg.iter() + .map(|msg| msg.replace("{{message}}", &commit.0)) + .collect::>() + }, + ) + } else { + base } + }; + + self.cmd = command; + + Ok(()) + } + + fn run( + &mut self, + p: &mut Promptuity, + state: &mut crate::tui::AppData, + _: &mut SimpleCommitsConfig, + ) -> StepResult { + if self.skip { + let (head, tail) = self.cmd.split_first().unwrap(); + self.action = Action::Commit(head.clone(), tail.to_vec()); + return Ok(()); } + let commit = state.commit.clone().build()?; + let execute = p.prompt(Confirm::new("Do you want to execute this command?").with_default(true))?; if !execute { @@ -56,11 +78,20 @@ impl Step for _Step { p.log(commit.0)?; p.log(BLANK_CHARACTER)?; } else { - state.action = Action::Commit(cmd.clone(), (command[1..]).to_vec()); - - state.action.execute_action(); + let (head, tail) = self.cmd.split_first().unwrap(); + self.action = Action::Commit(head.clone(), tail.to_vec()); }; Ok(()) } + + fn after_run( + &mut self, + _: &mut Promptuity, + _: &mut crate::tui::AppData, + _config: &mut SimpleCommitsConfig, + ) -> StepResult { + self.action.execute_action(); + Ok(()) + } } diff --git a/src/tui/steps/message.rs b/src/tui/steps/message.rs index 293fb64..545ebb8 100644 --- a/src/tui/steps/message.rs +++ b/src/tui/steps/message.rs @@ -6,15 +6,33 @@ use crate::{ }; #[derive(Default)] -pub struct _Step; +pub struct Title { + skip: bool, + title: Option, +} + +impl Step for Title { + fn before_run( + &mut self, + _: &mut promptuity::Promptuity, + _: &mut crate::tui::AppData, + config: &mut SimpleCommitsConfig, + ) -> StepResult { + self.skip = config.message.as_ref().is_some(); + self.title = config.message.clone(); + Ok(()) + } -impl Step for _Step { fn run( - &self, + &mut self, p: &mut promptuity::Promptuity, - state: &mut crate::tui::AppData, + _: &mut crate::tui::AppData, _: &mut SimpleCommitsConfig, ) -> StepResult { + if self.skip { + return Ok(()); + } + let msg = p.prompt( Input::new("Enter a brief title of the commit").with_validator(|text: &String| { valid_length( @@ -24,7 +42,17 @@ impl Step for _Step { ) }), )?; - state.commit.set_title(Some(msg)); + self.title = Some(msg); + Ok(()) + } + + fn after_run( + &mut self, + _: &mut promptuity::Promptuity, + state: &mut crate::tui::AppData, + _: &mut SimpleCommitsConfig, + ) -> StepResult { + state.commit.set_title(self.title.clone()); Ok(()) } } diff --git a/src/tui/steps/mod.rs b/src/tui/steps/mod.rs index 84fd546..918f889 100644 --- a/src/tui/steps/mod.rs +++ b/src/tui/steps/mod.rs @@ -18,17 +18,25 @@ pub fn init( config: &mut SimpleCommitsConfig, ) -> Result<(), Error> { let mut state = AppData::default(); - let steps = gen_steps![commit, scopes, emoji, message, exec]; + let mut steps = gen_steps![ + commit::Definition, + scopes::Scope, + emoji::Emoji, + message::Title, + exec::Execute + ]; prompt.with_intro("Simple Commit").begin()?; - for step in steps { + for step in steps.iter_mut() { + let _before = step.before_run(prompt, &mut state, config); let res = step.run(prompt, &mut state, config); if let Err(err) = res { let msg = format!("❌ Error: {:?}", err); error!(target: "tui::steps", "{}", msg.bright_red()); return Err(Error::Prompt(String::from("Error"))); } + let _after = step.after_run(prompt, &mut state, config); info!(target: "tui::steps", "steps: {state:#?}"); } diff --git a/src/tui/steps/scopes.rs b/src/tui/steps/scopes.rs index 9a92981..9958e51 100644 --- a/src/tui/steps/scopes.rs +++ b/src/tui/steps/scopes.rs @@ -10,11 +10,11 @@ use crate::{ }; #[derive(Default)] -pub struct _Step; +pub struct Scope; -impl Step for _Step { +impl Step for Scope { fn run( - &self, + &mut self, p: &mut promptuity::Promptuity, state: &mut crate::tui::AppData, config: &mut SimpleCommitsConfig, @@ -38,11 +38,12 @@ impl Step for _Step { let scope = (!scope.is_empty()).then_some(scope); state.commit.set_scope(scope.clone()); + // FIX: Error on global path if let Some(scope) = scope { if let Some(scopes) = &mut config.scopes { if !scopes.exists(&scope) { debug!(target: "steps::scope", "This shit works"); - scopes.add_scope(scope.clone()); + scopes.add_scope(scope); if let Err(err) = config.update() { error!(target: "step::scope", "This shit aint work! {}", err); }