From 34e2b49c3bd3a3ca9ac7fdebeade4aa97c048d38 Mon Sep 17 00:00:00 2001
From: prsabahrami
Date: Fri, 14 Feb 2025 10:38:47 -0500
Subject: [PATCH 1/5] exit shell upon exit command
---
crates/deno_task_shell/src/shell/types.rs | 7 +++++++
crates/shell/src/execute.rs | 19 ++++++++-----------
crates/shell/src/main.rs | 19 +++++++++----------
3 files changed, 24 insertions(+), 21 deletions(-)
diff --git a/crates/deno_task_shell/src/shell/types.rs b/crates/deno_task_shell/src/shell/types.rs
index f56d199..472b365 100644
--- a/crates/deno_task_shell/src/shell/types.rs
+++ b/crates/deno_task_shell/src/shell/types.rs
@@ -428,6 +428,13 @@ impl ExecuteResult {
ExecuteResult::Continue(_, changes, handles) => (handles, changes),
}
}
+
+ pub fn exit_code(&self) -> i32 {
+ match self {
+ ExecuteResult::Exit(code, _) => *code,
+ ExecuteResult::Continue(code, _, _) => *code,
+ }
+ }
}
/// Reader side of a pipe.
diff --git a/crates/shell/src/execute.rs b/crates/shell/src/execute.rs
index 2683615..f45209a 100644
--- a/crates/shell/src/execute.rs
+++ b/crates/shell/src/execute.rs
@@ -41,18 +41,15 @@ pub async fn execute(
text: &str,
filename: Option,
state: &mut ShellState,
-) -> miette::Result {
+) -> miette::Result {
let result = execute_inner(text, filename, state.clone()).await?;
- match result {
- ExecuteResult::Continue(exit_code, changes, _) => {
- // set CWD to the last command's CWD
- state.apply_changes(&changes);
- std::env::set_current_dir(state.cwd())
- .into_diagnostic()
- .context("Failed to set CWD")?;
- Ok(exit_code)
- }
- ExecuteResult::Exit(exit_code, _) => Ok(exit_code),
+ if let ExecuteResult::Continue(_, changes, _) = &result {
+ // set CWD to the last command's CWD
+ state.apply_changes(changes);
+ std::env::set_current_dir(state.cwd())
+ .into_diagnostic()
+ .context("Failed to set CWD")?;
}
+ Ok(result)
}
diff --git a/crates/shell/src/main.rs b/crates/shell/src/main.rs
index 502b438..6439e7d 100644
--- a/crates/shell/src/main.rs
+++ b/crates/shell/src/main.rs
@@ -4,6 +4,7 @@ use std::path::PathBuf;
use clap::Parser;
use deno_task_shell::parser::debug_parse;
+use deno_task_shell::ExecuteResult;
use deno_task_shell::ShellState;
use miette::Context;
use miette::IntoDiagnostic;
@@ -73,14 +74,14 @@ async fn init_state(norc: bool, var_args: &[String]) -> miette::Result, norc: bool, args: &[String]) ->
rl.add_history_entry(line.as_str()).into_diagnostic()?;
// Process the input (here we just echo it back)
- let prev_exit_code = execute(&line, None, &mut state)
+ let result = execute(&line, None, &mut state)
.await
.context("Failed to execute")?;
- state.set_last_command_exit_code(prev_exit_code);
+ state.set_last_command_exit_code(result.exit_code());
- // Check for exit command
- if line.trim().eq_ignore_ascii_case("exit") {
- println!("Exiting...");
- break;
+ if let ExecuteResult::Exit(exit_code, _) = result {
+ std::process::exit(exit_code);
}
}
Err(ReadlineError::Interrupted) => {
@@ -235,13 +234,13 @@ async fn main() -> miette::Result<()> {
return Ok(());
}
- let exit_code = execute(&script_text, filename, &mut state).await?;
+ let result = execute(&script_text, filename, &mut state).await?;
if options.interact {
interactive(Some(state), options.norc, &options.args).await?;
}
- std::process::exit(exit_code);
+ std::process::exit(result.exit_code());
}
}
}
From b0155bd00400aeeae526420e972826451c84b981 Mon Sep 17 00:00:00 2001
From: prsabahrami
Date: Fri, 14 Feb 2025 12:06:24 -0500
Subject: [PATCH 2/5] fix source issue with exit
---
.../src/shell/commands/exit.rs | 4 +-
crates/deno_task_shell/src/shell/execute.rs | 51 ++++++++++++-------
crates/deno_task_shell/src/shell/types.rs | 12 ++---
crates/shell/src/commands/set.rs | 2 +-
crates/shell/src/execute.rs | 19 ++++---
crates/shell/src/main.rs | 2 +-
scripts/exit.sh | 2 +
7 files changed, 55 insertions(+), 37 deletions(-)
create mode 100644 scripts/exit.sh
diff --git a/crates/deno_task_shell/src/shell/commands/exit.rs b/crates/deno_task_shell/src/shell/commands/exit.rs
index 44ab7fb..004f416 100644
--- a/crates/deno_task_shell/src/shell/commands/exit.rs
+++ b/crates/deno_task_shell/src/shell/commands/exit.rs
@@ -19,10 +19,10 @@ impl ShellCommand for ExitCommand {
mut context: ShellCommandContext,
) -> LocalBoxFuture<'static, ExecuteResult> {
let result = match execute_exit(context.args) {
- Ok(code) => ExecuteResult::Exit(code, Vec::new()),
+ Ok(code) => ExecuteResult::Exit(code, Vec::new(), Vec::new()),
Err(err) => {
context.stderr.write_line(&format!("exit: {err}")).unwrap();
- ExecuteResult::Exit(2, Vec::new())
+ ExecuteResult::Exit(2, Vec::new(), Vec::new())
}
};
Box::pin(futures::future::ready(result))
diff --git a/crates/deno_task_shell/src/shell/execute.rs b/crates/deno_task_shell/src/shell/execute.rs
index b13bf82..7db3330 100644
--- a/crates/deno_task_shell/src/shell/execute.rs
+++ b/crates/deno_task_shell/src/shell/execute.rs
@@ -135,7 +135,7 @@ pub async fn execute_with_pipes(
.await;
match result {
- ExecuteResult::Exit(code, _) => code,
+ ExecuteResult::Exit(code, _, _) => code,
ExecuteResult::Continue(exit_code, _, _) => exit_code,
}
}
@@ -183,7 +183,10 @@ pub fn execute_sequential_list(
)
.await;
match result {
- ExecuteResult::Exit(exit_code, handles) => {
+ ExecuteResult::Exit(exit_code, changes, handles) => {
+ state.apply_changes(&changes);
+ state.set_shell_var("?", &exit_code.to_string());
+ final_changes.extend(changes);
async_handles.extend(handles);
final_exit_code = exit_code;
was_exit = true;
@@ -215,7 +218,7 @@ pub fn execute_sequential_list(
}
if was_exit {
- ExecuteResult::Exit(final_exit_code, async_handles)
+ ExecuteResult::Exit(final_exit_code, final_changes, async_handles)
} else {
ExecuteResult::Continue(final_exit_code, final_changes, async_handles)
}
@@ -287,7 +290,7 @@ fn execute_sequence(
)
.await;
let (exit_code, mut async_handles) = match first_result {
- ExecuteResult::Exit(_, _) => return first_result,
+ ExecuteResult::Exit(_, _, _) => return first_result,
ExecuteResult::Continue(exit_code, sub_changes, async_handles) => {
changes.extend(sub_changes);
(exit_code, async_handles)
@@ -317,9 +320,10 @@ fn execute_sequence(
let next_result =
execute_sequence(next, state, stdin, stdout, stderr).await;
match next_result {
- ExecuteResult::Exit(code, sub_handles) => {
+ ExecuteResult::Exit(code, sub_changes, sub_handles) => {
+ changes.extend(sub_changes);
async_handles.extend(sub_handles);
- ExecuteResult::Exit(code, async_handles)
+ ExecuteResult::Exit(code, changes, async_handles)
}
ExecuteResult::Continue(exit_code, sub_changes, sub_handles) => {
changes.extend(sub_changes);
@@ -350,7 +354,9 @@ async fn execute_pipeline(
execute_pipeline_inner(pipeline.inner, state, stdin, stdout, stderr).await;
if pipeline.negated {
match result {
- ExecuteResult::Exit(code, handles) => ExecuteResult::Exit(code, handles),
+ ExecuteResult::Exit(code, changes, handles) => {
+ ExecuteResult::Exit(code, changes, handles)
+ }
ExecuteResult::Continue(code, changes, handles) => {
let new_code = if code == 0 { 1 } else { 0 };
ExecuteResult::Continue(new_code, changes, handles)
@@ -570,8 +576,8 @@ async fn execute_command(
CommandInner::Subshell(list) => {
// Here the state can be changed but we can not pass by reference
match execute_subshell(list, state, stdin, stdout, stderr).await {
- ExecuteResult::Exit(code, handles) => {
- ExecuteResult::Exit(code, handles)
+ ExecuteResult::Exit(code, _, handles) => {
+ ExecuteResult::Exit(code, changes, handles)
}
ExecuteResult::Continue(code, _, handles) => {
ExecuteResult::Continue(code, changes, handles)
@@ -642,7 +648,8 @@ async fn execute_for_clause(
.await;
match result {
- ExecuteResult::Exit(code, handles) => {
+ ExecuteResult::Exit(code, env_changes, handles) => {
+ changes.extend(env_changes);
async_handles.extend(handles);
last_exit_code = code;
break;
@@ -658,7 +665,7 @@ async fn execute_for_clause(
state.apply_changes(&changes);
if state.exit_on_error() && last_exit_code != 0 {
- ExecuteResult::Exit(last_exit_code, async_handles)
+ ExecuteResult::Exit(last_exit_code, changes, async_handles)
} else {
ExecuteResult::Continue(last_exit_code, changes, async_handles)
}
@@ -910,7 +917,8 @@ async fn execute_pipe_sequence(
let mut changes: Vec = changes.into_iter().flatten().collect();
match last_result {
- ExecuteResult::Exit(code, mut handles) => {
+ ExecuteResult::Exit(code, env_changes, mut handles) => {
+ changes.extend(env_changes);
handles.extend(all_handles);
ExecuteResult::Continue(code, changes, handles)
}
@@ -941,9 +949,9 @@ async fn execute_subshell(
.await;
match result {
- ExecuteResult::Exit(code, handles) => {
+ ExecuteResult::Exit(code, env_changes, handles) => {
// sub shells do not cause an exit
- ExecuteResult::Continue(code, Vec::new(), handles)
+ ExecuteResult::Continue(code, env_changes, handles)
}
ExecuteResult::Continue(code, env_changes, handles) => {
// env changes are not propagated
@@ -988,8 +996,9 @@ async fn execute_if_clause(
)
.await;
match exec_result {
- ExecuteResult::Exit(code, handles) => {
- return ExecuteResult::Exit(code, handles);
+ ExecuteResult::Exit(code, env_changes, handles) => {
+ changes.extend(env_changes);
+ return ExecuteResult::Exit(code, changes, handles);
}
ExecuteResult::Continue(code, env_changes, handles) => {
changes.extend(env_changes);
@@ -1019,8 +1028,9 @@ async fn execute_if_clause(
)
.await;
match exec_result {
- ExecuteResult::Exit(code, handles) => {
- return ExecuteResult::Exit(code, handles);
+ ExecuteResult::Exit(code, env_changes, handles) => {
+ changes.extend(env_changes);
+ return ExecuteResult::Exit(code, changes, handles);
}
ExecuteResult::Continue(code, env_changes, handles) => {
changes.extend(env_changes);
@@ -1216,7 +1226,10 @@ async fn execute_simple_command(
let result = execute_command_args(args, state, stdin, stdout, stderr).await;
match result {
- ExecuteResult::Exit(code, handles) => ExecuteResult::Exit(code, handles),
+ ExecuteResult::Exit(code, env_changes, handles) => {
+ changes.extend(env_changes);
+ ExecuteResult::Exit(code, changes, handles)
+ }
ExecuteResult::Continue(code, env_changes, handles) => {
changes.extend(env_changes);
ExecuteResult::Continue(code, changes, handles)
diff --git a/crates/deno_task_shell/src/shell/types.rs b/crates/deno_task_shell/src/shell/types.rs
index 472b365..e9b45cc 100644
--- a/crates/deno_task_shell/src/shell/types.rs
+++ b/crates/deno_task_shell/src/shell/types.rs
@@ -389,13 +389,13 @@ pub const CANCELLATION_EXIT_CODE: i32 = 130;
#[derive(Debug)]
pub enum ExecuteResult {
- Exit(i32, Vec>),
+ Exit(i32, Vec, Vec>),
Continue(i32, Vec, Vec>),
}
impl ExecuteResult {
pub fn for_cancellation() -> ExecuteResult {
- ExecuteResult::Exit(CANCELLATION_EXIT_CODE, Vec::new())
+ ExecuteResult::Exit(CANCELLATION_EXIT_CODE, Vec::new(), Vec::new())
}
pub fn from_exit_code(exit_code: i32) -> ExecuteResult {
@@ -404,7 +404,7 @@ impl ExecuteResult {
pub fn into_exit_code_and_handles(self) -> (i32, Vec>) {
match self {
- ExecuteResult::Exit(code, handles) => (code, handles),
+ ExecuteResult::Exit(code, _, handles) => (code, handles),
ExecuteResult::Continue(code, _, handles) => (code, handles),
}
}
@@ -415,7 +415,7 @@ impl ExecuteResult {
pub fn into_changes(self) -> Vec {
match self {
- ExecuteResult::Exit(_, _) => Vec::new(),
+ ExecuteResult::Exit(_, changes, _) => changes,
ExecuteResult::Continue(_, changes, _) => changes,
}
}
@@ -424,14 +424,14 @@ impl ExecuteResult {
self,
) -> (Vec>, Vec) {
match self {
- ExecuteResult::Exit(_, handles) => (handles, Vec::new()),
+ ExecuteResult::Exit(_, changes, handles) => (handles, changes),
ExecuteResult::Continue(_, changes, handles) => (handles, changes),
}
}
pub fn exit_code(&self) -> i32 {
match self {
- ExecuteResult::Exit(code, _) => *code,
+ ExecuteResult::Exit(code, _, _) => *code,
ExecuteResult::Continue(code, _, _) => *code,
}
}
diff --git a/crates/shell/src/commands/set.rs b/crates/shell/src/commands/set.rs
index b6ffb09..0e01fb0 100644
--- a/crates/shell/src/commands/set.rs
+++ b/crates/shell/src/commands/set.rs
@@ -17,7 +17,7 @@ impl ShellCommand for SetCommand {
Ok((code, env_changes)) => ExecuteResult::Continue(code, env_changes, Vec::new()),
Err(err) => {
context.stderr.write_line(&format!("set: {err}")).unwrap();
- ExecuteResult::Exit(2, Vec::new())
+ ExecuteResult::Exit(2, Vec::new(), Vec::new())
}
};
Box::pin(futures::future::ready(result))
diff --git a/crates/shell/src/execute.rs b/crates/shell/src/execute.rs
index f45209a..5bbda7e 100644
--- a/crates/shell/src/execute.rs
+++ b/crates/shell/src/execute.rs
@@ -20,7 +20,7 @@ pub async fn execute_inner(
stderr.write_all(format!("Filename: {:?}\n", filename).as_bytes())?;
}
stderr.write_all(format!("Syntax error: {:?}", e).as_bytes())?;
- return Ok(ExecuteResult::Exit(1, vec![]));
+ return Ok(ExecuteResult::Exit(1, vec![], vec![]));
}
// spawn a sequential list and pipe its output to the environment
@@ -44,12 +44,15 @@ pub async fn execute(
) -> miette::Result {
let result = execute_inner(text, filename, state.clone()).await?;
- if let ExecuteResult::Continue(_, changes, _) = &result {
- // set CWD to the last command's CWD
- state.apply_changes(changes);
- std::env::set_current_dir(state.cwd())
- .into_diagnostic()
- .context("Failed to set CWD")?;
- }
+ let changes = match &result {
+ ExecuteResult::Exit(_, changes, _) => changes,
+ ExecuteResult::Continue(_, changes, _) => changes,
+ };
+ // set CWD to the last command's CWD
+ state.apply_changes(changes);
+ std::env::set_current_dir(state.cwd())
+ .into_diagnostic()
+ .context("Failed to set CWD")?;
+
Ok(result)
}
diff --git a/crates/shell/src/main.rs b/crates/shell/src/main.rs
index 6439e7d..336fa86 100644
--- a/crates/shell/src/main.rs
+++ b/crates/shell/src/main.rs
@@ -189,7 +189,7 @@ async fn interactive(state: Option, norc: bool, args: &[String]) ->
.context("Failed to execute")?;
state.set_last_command_exit_code(result.exit_code());
- if let ExecuteResult::Exit(exit_code, _) = result {
+ if let ExecuteResult::Exit(exit_code, _, _) = result {
std::process::exit(exit_code);
}
}
diff --git a/scripts/exit.sh b/scripts/exit.sh
new file mode 100644
index 0000000..80517f1
--- /dev/null
+++ b/scripts/exit.sh
@@ -0,0 +1,2 @@
+echo "Hello World"
+exit
\ No newline at end of file
From 42e9240353798e4129785d409611c66b3255198b Mon Sep 17 00:00:00 2001
From: prsabahrami
Date: Fri, 14 Feb 2025 22:56:02 -0500
Subject: [PATCH 3/5] update subshell behaviour
---
crates/deno_task_shell/src/shell/execute.rs | 2 +-
crates/tests/test-data/source.sh | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
create mode 100644 crates/tests/test-data/source.sh
diff --git a/crates/deno_task_shell/src/shell/execute.rs b/crates/deno_task_shell/src/shell/execute.rs
index 7db3330..8f27d24 100644
--- a/crates/deno_task_shell/src/shell/execute.rs
+++ b/crates/deno_task_shell/src/shell/execute.rs
@@ -577,7 +577,7 @@ async fn execute_command(
// Here the state can be changed but we can not pass by reference
match execute_subshell(list, state, stdin, stdout, stderr).await {
ExecuteResult::Exit(code, _, handles) => {
- ExecuteResult::Exit(code, changes, handles)
+ ExecuteResult::Continue(code, changes, handles)
}
ExecuteResult::Continue(code, _, handles) => {
ExecuteResult::Continue(code, changes, handles)
diff --git a/crates/tests/test-data/source.sh b/crates/tests/test-data/source.sh
new file mode 100644
index 0000000..64205e5
--- /dev/null
+++ b/crates/tests/test-data/source.sh
@@ -0,0 +1,2 @@
+> export FOO='TESTVALUE' && source $CARGO_MANIFEST_DIR/../../scripts/exit.sh && echo $FOO
+
From 97516cf0e9ae4a9bf1806996ea23a6c5cc79b641 Mon Sep 17 00:00:00 2001
From: prsabahrami
Date: Fri, 14 Feb 2025 23:08:25 -0500
Subject: [PATCH 4/5] fix: update ExecuteResult handling in while loop and
subshell execution
---
crates/deno_task_shell/src/shell/execute.rs | 81 +--------------------
1 file changed, 4 insertions(+), 77 deletions(-)
diff --git a/crates/deno_task_shell/src/shell/execute.rs b/crates/deno_task_shell/src/shell/execute.rs
index 6eb35ac..197eae2 100644
--- a/crates/deno_task_shell/src/shell/execute.rs
+++ b/crates/deno_task_shell/src/shell/execute.rs
@@ -617,8 +617,8 @@ async fn execute_command(
CommandInner::Subshell(list) => {
// Here the state can be changed but we can not pass by reference
match execute_subshell(list, state, stdin, stdout, stderr).await {
- ExecuteResult::Exit(code, handles) => {
- ExecuteResult::Exit(code, handles)
+ ExecuteResult::Exit(code, _, handles) => {
+ ExecuteResult::Exit(code, changes, handles)
}
ExecuteResult::Continue(code, _, handles) => {
ExecuteResult::Continue(code, changes, handles)
@@ -703,84 +703,11 @@ async fn execute_while_clause(
.await;
match exec_result {
- ExecuteResult::Exit(code, handles) => {
- async_handles.extend(handles);
- last_exit_code = code;
- break;
- }
- ExecuteResult::Continue(code, env_changes, handles) => {
+ ExecuteResult::Exit(code, env_changes, handles) => {
state.apply_changes(&env_changes);
changes.extend(env_changes);
async_handles.extend(handles);
last_exit_code = code;
- }
- }
- } else {
- break;
- }
- }
- Err(err) => {
- return err.into_exit_code(&mut stderr);
- }
- }
- }
-
- state.apply_changes(&changes);
-
- if state.exit_on_error() && last_exit_code != 0 {
- ExecuteResult::Exit(last_exit_code, async_handles)
- } else {
- ExecuteResult::Continue(last_exit_code, changes, async_handles)
- }
-}
-
-async fn execute_while_clause(
- while_clause: WhileLoop,
- state: &mut ShellState,
- stdin: ShellPipeReader,
- stdout: ShellPipeWriter,
- mut stderr: ShellPipeWriter,
-) -> ExecuteResult {
- let mut changes = Vec::new();
- let mut last_exit_code = 0;
- let mut async_handles = Vec::new();
-
- loop {
- let condition_result = evaluate_condition(
- while_clause.condition.clone(),
- state,
- stdin.clone(),
- stderr.clone(),
- )
- .await;
-
- match condition_result {
- Ok(ConditionalResult {
- value,
- changes: env_changes,
- }) => {
- state.apply_changes(&env_changes);
- changes.extend(env_changes);
-
- // For until loops, we invert the condition
- let should_execute_body =
- if while_clause.is_until { !value } else { value };
-
- if should_execute_body {
- let exec_result = execute_sequential_list(
- while_clause.body.clone(),
- state.clone(),
- stdin.clone(),
- stdout.clone(),
- stderr.clone(),
- AsyncCommandBehavior::Yield,
- )
- .await;
-
- match exec_result {
- ExecuteResult::Exit(code, handles) => {
- async_handles.extend(handles);
- last_exit_code = code;
break;
}
ExecuteResult::Continue(code, env_changes, handles) => {
@@ -803,7 +730,7 @@ async fn execute_while_clause(
state.apply_changes(&changes);
if state.exit_on_error() && last_exit_code != 0 {
- ExecuteResult::Exit(last_exit_code, async_handles)
+ ExecuteResult::Exit(last_exit_code, changes, async_handles)
} else {
ExecuteResult::Continue(last_exit_code, changes, async_handles)
}
From 6505739118d60f5f330ba269c4f2539a2362b026 Mon Sep 17 00:00:00 2001
From: prsabahrami
Date: Fri, 14 Feb 2025 23:08:44 -0500
Subject: [PATCH 5/5] run fmt
---
.../src/shell/commands/exit.rs | 26 +--
crates/deno_task_shell/src/shell/execute.rs | 194 +++++++++---------
crates/deno_task_shell/src/shell/types.rs | 54 ++---
3 files changed, 141 insertions(+), 133 deletions(-)
diff --git a/crates/deno_task_shell/src/shell/commands/exit.rs b/crates/deno_task_shell/src/shell/commands/exit.rs
index b4d9a9a..f8f0ee1 100644
--- a/crates/deno_task_shell/src/shell/commands/exit.rs
+++ b/crates/deno_task_shell/src/shell/commands/exit.rs
@@ -14,19 +14,19 @@ use super::ShellCommandContext;
pub struct ExitCommand;
impl ShellCommand for ExitCommand {
- fn execute(
- &self,
- mut context: ShellCommandContext,
- ) -> LocalBoxFuture<'static, ExecuteResult> {
- let result = match execute_exit(context.args) {
- Ok(code) => ExecuteResult::Exit(code, Vec::new(), Vec::new()),
- Err(err) => {
- context.stderr.write_line(&format!("exit: {err}")).unwrap();
- ExecuteResult::Exit(2, Vec::new(), Vec::new())
- }
- };
- Box::pin(futures::future::ready(result))
- }
+ fn execute(
+ &self,
+ mut context: ShellCommandContext,
+ ) -> LocalBoxFuture<'static, ExecuteResult> {
+ let result = match execute_exit(context.args) {
+ Ok(code) => ExecuteResult::Exit(code, Vec::new(), Vec::new()),
+ Err(err) => {
+ context.stderr.write_line(&format!("exit: {err}")).unwrap();
+ ExecuteResult::Exit(2, Vec::new(), Vec::new())
+ }
+ };
+ Box::pin(futures::future::ready(result))
+ }
}
fn execute_exit(args: Vec) -> Result {
diff --git a/crates/deno_task_shell/src/shell/execute.rs b/crates/deno_task_shell/src/shell/execute.rs
index 197eae2..7f1aece 100644
--- a/crates/deno_task_shell/src/shell/execute.rs
+++ b/crates/deno_task_shell/src/shell/execute.rs
@@ -135,10 +135,10 @@ pub async fn execute_with_pipes(
)
.await;
- match result {
- ExecuteResult::Exit(code, _, _) => code,
- ExecuteResult::Continue(exit_code, _, _) => exit_code,
- }
+ match result {
+ ExecuteResult::Exit(code, _, _) => code,
+ ExecuteResult::Continue(exit_code, _, _) => exit_code,
+ }
}
#[derive(Debug, PartialEq)]
@@ -192,9 +192,9 @@ pub fn execute_sequential_list(
.await;
match result {
ExecuteResult::Exit(exit_code, changes, handles) => {
- state.apply_changes(&changes);
- state.set_shell_var("?", &exit_code.to_string());
- final_changes.extend(changes);
+ state.apply_changes(&changes);
+ state.set_shell_var("?", &exit_code.to_string());
+ final_changes.extend(changes);
async_handles.extend(handles);
final_exit_code = exit_code;
was_exit = true;
@@ -344,7 +344,7 @@ fn execute_sequence(
.await;
match next_result {
ExecuteResult::Exit(code, sub_changes, sub_handles) => {
- changes.extend(sub_changes);
+ changes.extend(sub_changes);
async_handles.extend(sub_handles);
ExecuteResult::Exit(code, changes, async_handles)
}
@@ -381,21 +381,22 @@ async fn execute_pipeline(
stdout: ShellPipeWriter,
stderr: ShellPipeWriter,
) -> ExecuteResult {
- let result =
- execute_pipeline_inner(pipeline.inner, state, stdin, stdout, stderr).await;
- if pipeline.negated {
- match result {
- ExecuteResult::Exit(code, changes, handles) => {
- ExecuteResult::Exit(code, changes, handles)
- }
- ExecuteResult::Continue(code, changes, handles) => {
- let new_code = if code == 0 { 1 } else { 0 };
- ExecuteResult::Continue(new_code, changes, handles)
- }
+ let result =
+ execute_pipeline_inner(pipeline.inner, state, stdin, stdout, stderr)
+ .await;
+ if pipeline.negated {
+ match result {
+ ExecuteResult::Exit(code, changes, handles) => {
+ ExecuteResult::Exit(code, changes, handles)
+ }
+ ExecuteResult::Continue(code, changes, handles) => {
+ let new_code = if code == 0 { 1 } else { 0 };
+ ExecuteResult::Continue(new_code, changes, handles)
+ }
+ }
+ } else {
+ result
}
- } else {
- result
- }
}
async fn execute_pipeline_inner(
@@ -595,68 +596,73 @@ async fn execute_command(
let _ = stderr.write_line(
"only redirecting to stdout (1) and stderr (2) is supported",
);
- return ExecuteResult::from_exit_code(1);
+ return ExecuteResult::from_exit_code(1);
+ }
+ Some(RedirectFd::StdoutStderr) => {
+ (stdin, pipe.clone(), pipe, changes)
+ }
+ },
}
- Some(RedirectFd::StdoutStderr) => (stdin, pipe.clone(), pipe, changes),
- },
- }
- } else {
- (stdin, stdout, stderr, None)
- };
- let mut changes = if let Some(changes) = changes {
- state.apply_changes(&changes);
- changes
- } else {
- Vec::new()
- };
- match command.inner {
- CommandInner::Simple(command) => {
- // This can change the state, so we need to pass it by mutable reference
- execute_simple_command(command, &mut state, stdin, stdout, stderr).await
- }
- CommandInner::Subshell(list) => {
- // Here the state can be changed but we can not pass by reference
- match execute_subshell(list, state, stdin, stdout, stderr).await {
- ExecuteResult::Exit(code, _, handles) => {
- ExecuteResult::Exit(code, changes, handles)
+ } else {
+ (stdin, stdout, stderr, None)
+ };
+ let mut changes = if let Some(changes) = changes {
+ state.apply_changes(&changes);
+ changes
+ } else {
+ Vec::new()
+ };
+ match command.inner {
+ CommandInner::Simple(command) => {
+ // This can change the state, so we need to pass it by mutable reference
+ execute_simple_command(command, &mut state, stdin, stdout, stderr)
+ .await
}
- ExecuteResult::Continue(code, _, handles) => {
- ExecuteResult::Continue(code, changes, handles)
+ CommandInner::Subshell(list) => {
+ // Here the state can be changed but we can not pass by reference
+ match execute_subshell(list, state, stdin, stdout, stderr).await {
+ ExecuteResult::Exit(code, _, handles) => {
+ ExecuteResult::Exit(code, changes, handles)
+ }
+ ExecuteResult::Continue(code, _, handles) => {
+ ExecuteResult::Continue(code, changes, handles)
+ }
+ }
}
- }
- }
- CommandInner::If(if_clause) => {
- // The state can be changed
- execute_if_clause(if_clause, &mut state, stdin, stdout, stderr).await
- }
- CommandInner::For(for_clause) => {
- // The state can be changed
- execute_for_clause(for_clause, &mut state, stdin, stdout, stderr).await
- }
- CommandInner::While(while_clause) => {
- execute_while_clause(
- while_clause,
- &mut state,
- stdin,
- stdout,
- stderr,
- )
- .await
- }
- CommandInner::ArithmeticExpression(arithmetic) => {
- // The state can be changed
- match execute_arithmetic_expression(arithmetic, &mut state).await {
- Ok(result) => {
- changes.extend(result.changes);
- ExecuteResult::Continue(0, changes, Vec::new())
+ CommandInner::If(if_clause) => {
+ // The state can be changed
+ execute_if_clause(if_clause, &mut state, stdin, stdout, stderr)
+ .await
+ }
+ CommandInner::For(for_clause) => {
+ // The state can be changed
+ execute_for_clause(for_clause, &mut state, stdin, stdout, stderr)
+ .await
+ }
+ CommandInner::While(while_clause) => {
+ execute_while_clause(
+ while_clause,
+ &mut state,
+ stdin,
+ stdout,
+ stderr,
+ )
+ .await
}
- Err(e) => {
- let _ = stderr.write_line(&e.to_string());
- ExecuteResult::Continue(2, changes, Vec::new())
+ CommandInner::ArithmeticExpression(arithmetic) => {
+ // The state can be changed
+ match execute_arithmetic_expression(arithmetic, &mut state).await {
+ Ok(result) => {
+ changes.extend(result.changes);
+ ExecuteResult::Continue(0, changes, Vec::new())
+ }
+ Err(e) => {
+ let _ = stderr.write_line(&e.to_string());
+ ExecuteResult::Continue(2, changes, Vec::new())
+ }
+ }
}
- }
}
- }
}
async fn execute_while_clause(
@@ -777,7 +783,7 @@ async fn execute_for_clause(
match result {
ExecuteResult::Exit(code, env_changes, handles) => {
- changes.extend(env_changes);
+ changes.extend(env_changes);
async_handles.extend(handles);
last_exit_code = code;
break;
@@ -1079,7 +1085,7 @@ async fn execute_pipe_sequence(
match last_result {
ExecuteResult::Exit(code, env_changes, mut handles) => {
- changes.extend(env_changes);
+ changes.extend(env_changes);
handles.extend(all_handles);
ExecuteResult::Continue(code, changes, handles)
}
@@ -1158,7 +1164,7 @@ async fn execute_if_clause(
.await;
match exec_result {
ExecuteResult::Exit(code, env_changes, handles) => {
- changes.extend(env_changes);
+ changes.extend(env_changes);
return ExecuteResult::Exit(code, changes, handles);
}
ExecuteResult::Continue(code, env_changes, handles) => {
@@ -1190,8 +1196,10 @@ async fn execute_if_clause(
.await;
match exec_result {
ExecuteResult::Exit(code, env_changes, handles) => {
- changes.extend(env_changes);
- return ExecuteResult::Exit(code, changes, handles);
+ changes.extend(env_changes);
+ return ExecuteResult::Exit(
+ code, changes, handles,
+ );
}
ExecuteResult::Continue(
code,
@@ -1440,17 +1448,17 @@ async fn execute_simple_command(
let _ = stdout.write_line(&format!("+ {:}", args.join(" ")));
}
- let result = execute_command_args(args, state, stdin, stdout, stderr).await;
- match result {
- ExecuteResult::Exit(code, env_changes, handles) => {
- changes.extend(env_changes);
- ExecuteResult::Exit(code, changes, handles)
- }
- ExecuteResult::Continue(code, env_changes, handles) => {
- changes.extend(env_changes);
- ExecuteResult::Continue(code, changes, handles)
+ let result = execute_command_args(args, state, stdin, stdout, stderr).await;
+ match result {
+ ExecuteResult::Exit(code, env_changes, handles) => {
+ changes.extend(env_changes);
+ ExecuteResult::Exit(code, changes, handles)
+ }
+ ExecuteResult::Continue(code, env_changes, handles) => {
+ changes.extend(env_changes);
+ ExecuteResult::Continue(code, changes, handles)
+ }
}
- }
}
fn execute_command_args(
diff --git a/crates/deno_task_shell/src/shell/types.rs b/crates/deno_task_shell/src/shell/types.rs
index 457c81c..aa4eb95 100644
--- a/crates/deno_task_shell/src/shell/types.rs
+++ b/crates/deno_task_shell/src/shell/types.rs
@@ -389,52 +389,52 @@ pub const CANCELLATION_EXIT_CODE: i32 = 130;
#[derive(Debug)]
pub enum ExecuteResult {
- Exit(i32, Vec, Vec>),
- Continue(i32, Vec, Vec>),
+ Exit(i32, Vec, Vec>),
+ Continue(i32, Vec, Vec>),
}
impl ExecuteResult {
- pub fn for_cancellation() -> ExecuteResult {
- ExecuteResult::Exit(CANCELLATION_EXIT_CODE, Vec::new(), Vec::new())
- }
+ pub fn for_cancellation() -> ExecuteResult {
+ ExecuteResult::Exit(CANCELLATION_EXIT_CODE, Vec::new(), Vec::new())
+ }
pub fn from_exit_code(exit_code: i32) -> ExecuteResult {
ExecuteResult::Continue(exit_code, Vec::new(), Vec::new())
}
- pub fn into_exit_code_and_handles(self) -> (i32, Vec>) {
- match self {
- ExecuteResult::Exit(code, _, handles) => (code, handles),
- ExecuteResult::Continue(code, _, handles) => (code, handles),
+ pub fn into_exit_code_and_handles(self) -> (i32, Vec>) {
+ match self {
+ ExecuteResult::Exit(code, _, handles) => (code, handles),
+ ExecuteResult::Continue(code, _, handles) => (code, handles),
+ }
}
- }
pub fn into_handles(self) -> Vec> {
self.into_exit_code_and_handles().1
}
- pub fn into_changes(self) -> Vec {
- match self {
- ExecuteResult::Exit(_, changes, _) => changes,
- ExecuteResult::Continue(_, changes, _) => changes,
+ pub fn into_changes(self) -> Vec {
+ match self {
+ ExecuteResult::Exit(_, changes, _) => changes,
+ ExecuteResult::Continue(_, changes, _) => changes,
+ }
}
- }
- pub fn into_handles_and_changes(
- self,
- ) -> (Vec>, Vec) {
- match self {
- ExecuteResult::Exit(_, changes, handles) => (handles, changes),
- ExecuteResult::Continue(_, changes, handles) => (handles, changes),
+ pub fn into_handles_and_changes(
+ self,
+ ) -> (Vec>, Vec) {
+ match self {
+ ExecuteResult::Exit(_, changes, handles) => (handles, changes),
+ ExecuteResult::Continue(_, changes, handles) => (handles, changes),
+ }
}
- }
- pub fn exit_code(&self) -> i32 {
- match self {
- ExecuteResult::Exit(code, _, _) => *code,
- ExecuteResult::Continue(code, _, _) => *code,
+ pub fn exit_code(&self) -> i32 {
+ match self {
+ ExecuteResult::Exit(code, _, _) => *code,
+ ExecuteResult::Continue(code, _, _) => *code,
+ }
}
- }
}
/// Reader side of a pipe.