From b8bcff466bb9ed4bd7802ef74c97f89a79c284f1 Mon Sep 17 00:00:00 2001 From: prsabahrami Date: Mon, 9 Sep 2024 12:35:47 -0400 Subject: [PATCH] Added last cmd exit_code support --- crates/deno_task_shell/src/parser.rs | 4 +++- crates/deno_task_shell/src/shell/execute.rs | 5 +++++ crates/deno_task_shell/src/shell/types.rs | 10 ++++++++++ crates/shell/src/main.rs | 3 ++- scripts/exit_code.sh | 1 + 5 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 scripts/exit_code.sh diff --git a/crates/deno_task_shell/src/parser.rs b/crates/deno_task_shell/src/parser.rs index 9032f53..947cb2e 100644 --- a/crates/deno_task_shell/src/parser.rs +++ b/crates/deno_task_shell/src/parser.rs @@ -280,6 +280,8 @@ pub enum WordPart { Quoted(Vec), /// Tilde prefix (ex. `~user/path` or `~/bin`) Tilde(TildePrefix), + /// Exit status of the last command (ex. `$?`) + ExitStatus, } #[cfg_attr(feature = "serialization", derive(serde::Serialize))] @@ -704,7 +706,7 @@ fn parse_word(pair: Pair) -> Result { Rule::UNQUOTED_PENDING_WORD => { for part in pair.into_inner() { match part.as_rule() { - Rule::EXIT_STATUS => parts.push(WordPart::Variable("?".to_string())), + Rule::EXIT_STATUS => parts.push(WordPart::ExitStatus), Rule::UNQUOTED_CHAR => { if let Some(WordPart::Text(ref mut text)) = parts.last_mut() { text.push(part.as_str().chars().next().unwrap()); diff --git a/crates/deno_task_shell/src/shell/execute.rs b/crates/deno_task_shell/src/shell/execute.rs index 62daa5d..debbfcf 100644 --- a/crates/deno_task_shell/src/shell/execute.rs +++ b/crates/deno_task_shell/src/shell/execute.rs @@ -917,6 +917,11 @@ fn evaluate_word_parts( } continue; } + WordPart::ExitStatus => { + let exit_code = state.last_command_exit_code(); + current_text.push(TextPart::Text(exit_code.to_string())); + continue; + } }; // This text needs to be turned into a vector of strings. diff --git a/crates/deno_task_shell/src/shell/types.rs b/crates/deno_task_shell/src/shell/types.rs index ec21772..f69b977 100644 --- a/crates/deno_task_shell/src/shell/types.rs +++ b/crates/deno_task_shell/src/shell/types.rs @@ -36,6 +36,7 @@ pub struct ShellState { git_root: PathBuf, // Path to the root (`$git_root/.git/HEAD` exists) git_branch: String, // Contents of `$git_root/.git/HEAD` last_command_cd: bool, // Was last command a `cd` (thus git_branch is current)? + last_command_exit_code: i32, // Exit code of the last command } impl ShellState { @@ -57,6 +58,7 @@ impl ShellState { git_root: PathBuf::new(), git_branch: String::new(), last_command_cd: false, + last_command_exit_code: 0, }; // ensure the data is normalized for (name, value) in env_vars { @@ -86,6 +88,14 @@ impl ShellState { self.last_command_cd } + pub fn set_last_command_exit_code(&mut self, exit_code: i32) { + self.last_command_exit_code = exit_code; + } + + pub fn last_command_exit_code(&self) -> i32 { + self.last_command_exit_code + } + pub fn env_vars(&self) -> &HashMap { &self.env_vars } diff --git a/crates/shell/src/main.rs b/crates/shell/src/main.rs index 454c464..634e8f0 100644 --- a/crates/shell/src/main.rs +++ b/crates/shell/src/main.rs @@ -139,9 +139,10 @@ async fn interactive() -> anyhow::Result<()> { rl.add_history_entry(line.as_str())?; // Process the input (here we just echo it back) - _prev_exit_code = execute(&line, &mut state) + let prev_exit_code = execute(&line, &mut state) .await .context("Failed to execute")?; + state.set_last_command_exit_code(prev_exit_code); // Check for exit command if line.trim().eq_ignore_ascii_case("exit") { diff --git a/scripts/exit_code.sh b/scripts/exit_code.sh new file mode 100644 index 0000000..cc1464a --- /dev/null +++ b/scripts/exit_code.sh @@ -0,0 +1 @@ +echo $? \ No newline at end of file