Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

206 sourcing a file will lose the current path value #248

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crates/deno_task_shell/src/shell/commands/exit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
59 changes: 36 additions & 23 deletions crates/deno_task_shell/src/shell/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ pub async fn execute_with_pipes(
.await;

match result {
ExecuteResult::Exit(code, _) => code,
ExecuteResult::Exit(code, _, _) => code,
ExecuteResult::Continue(exit_code, _, _) => exit_code,
}
}
Expand Down Expand Up @@ -191,7 +191,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;
Expand Down Expand Up @@ -223,7 +226,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,
Expand Down Expand Up @@ -305,7 +308,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,
Expand Down Expand Up @@ -340,9 +343,10 @@ fn execute_sequence(
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,
Expand Down Expand Up @@ -382,8 +386,8 @@ async fn execute_pipeline(
.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 };
Expand Down Expand Up @@ -617,8 +621,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)
Expand Down Expand Up @@ -705,7 +709,9 @@ async fn execute_while_clause(
.await;

match exec_result {
ExecuteResult::Exit(code, handles) => {
ExecuteResult::Exit(code, env_changes, handles) => {
state.apply_changes(&env_changes);
changes.extend(env_changes);
async_handles.extend(handles);
last_exit_code = code;
break;
Expand All @@ -730,7 +736,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)
}
Expand Down Expand Up @@ -776,7 +782,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;
Expand All @@ -792,7 +799,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)
}
Expand Down Expand Up @@ -1077,7 +1084,8 @@ async fn execute_pipe_sequence(
let mut changes: Vec<EnvChange> = 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)
}
Expand Down Expand Up @@ -1108,9 +1116,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
Expand Down Expand Up @@ -1155,8 +1163,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);
Expand Down Expand Up @@ -1186,8 +1195,11 @@ 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,
Expand Down Expand Up @@ -1438,8 +1450,9 @@ 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);
Expand Down
17 changes: 12 additions & 5 deletions crates/deno_task_shell/src/shell/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,13 +389,13 @@ pub const CANCELLATION_EXIT_CODE: i32 = 130;

#[derive(Debug)]
pub enum ExecuteResult {
Exit(i32, Vec<JoinHandle<i32>>),
Exit(i32, Vec<EnvChange>, Vec<JoinHandle<i32>>),
Continue(i32, Vec<EnvChange>, Vec<JoinHandle<i32>>),
}

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 {
Expand All @@ -404,7 +404,7 @@ impl ExecuteResult {

pub fn into_exit_code_and_handles(self) -> (i32, Vec<JoinHandle<i32>>) {
match self {
ExecuteResult::Exit(code, handles) => (code, handles),
ExecuteResult::Exit(code, _, handles) => (code, handles),
ExecuteResult::Continue(code, _, handles) => (code, handles),
}
}
Expand All @@ -415,7 +415,7 @@ impl ExecuteResult {

pub fn into_changes(self) -> Vec<EnvChange> {
match self {
ExecuteResult::Exit(_, _) => Vec::new(),
ExecuteResult::Exit(_, changes, _) => changes,
ExecuteResult::Continue(_, changes, _) => changes,
}
}
Expand All @@ -424,10 +424,17 @@ impl ExecuteResult {
self,
) -> (Vec<JoinHandle<i32>>, Vec<EnvChange>) {
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::Continue(code, _, _) => *code,
}
}
}

/// Reader side of a pipe.
Expand Down
2 changes: 1 addition & 1 deletion crates/shell/src/commands/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
26 changes: 13 additions & 13 deletions crates/shell/src/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -41,18 +41,18 @@ pub async fn execute(
text: &str,
filename: Option<String>,
state: &mut ShellState,
) -> miette::Result<i32> {
) -> miette::Result<ExecuteResult> {
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),
}
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)
}
19 changes: 9 additions & 10 deletions crates/shell/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -73,14 +74,14 @@ async fn init_state(norc: bool, var_args: &[String]) -> miette::Result<ShellStat
let shellrc_file = home_dir.join(".shellrc");
if !norc && shellrc_file.exists() {
let line = format!("source '{}'", shellrc_file.to_string_lossy());
let prev_exit_code = execute(
let result = execute(
&line,
Some(shellrc_file.as_path().display().to_string()),
&mut state,
)
.await
.context("Failed to source ~/.shellrc")?;
state.set_last_command_exit_code(prev_exit_code);
state.set_last_command_exit_code(result.exit_code());
}
}

Expand Down Expand Up @@ -183,15 +184,13 @@ async fn interactive(state: Option<ShellState>, 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) => {
Expand Down Expand Up @@ -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());
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions crates/tests/test-data/source.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
> export FOO='TESTVALUE' && source $CARGO_MANIFEST_DIR/../../scripts/exit.sh && echo $FOO

2 changes: 2 additions & 0 deletions scripts/exit.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
echo "Hello World"
exit
Loading