Add exit code methods to Stack

This commit is contained in:
Ian Manske 2024-08-01 20:52:58 -07:00
parent d3e33a78b5
commit db1ec3a7b8
6 changed files with 37 additions and 28 deletions

View File

@ -97,7 +97,7 @@ pub fn evaluate_repl(
Value::string("0823", Span::unknown()), Value::string("0823", Span::unknown()),
); );
unique_stack.add_env_var("LAST_EXIT_CODE".into(), Value::int(0, Span::unknown())); unique_stack.set_last_exit_code(0, Span::unknown());
let mut line_editor = get_line_editor(engine_state, nushell_path, use_color)?; let mut line_editor = get_line_editor(engine_state, nushell_path, use_color)?;
let temp_file = temp_dir().join(format!("{}.nu", uuid::Uuid::new_v4())); let temp_file = temp_dir().join(format!("{}.nu", uuid::Uuid::new_v4()));
@ -837,7 +837,7 @@ fn do_auto_cd(
"NUSHELL_LAST_SHELL".into(), "NUSHELL_LAST_SHELL".into(),
Value::int(last_shell as i64, span), Value::int(last_shell as i64, span),
); );
stack.add_env_var("LAST_EXIT_CODE".into(), Value::int(0, Span::unknown())); stack.set_last_exit_code(0, Span::unknown());
} }
/// ///

View File

@ -211,17 +211,14 @@ pub fn eval_source(
let exit_code = match evaluate_source(engine_state, stack, source, fname, input, allow_return) { let exit_code = match evaluate_source(engine_state, stack, source, fname, input, allow_return) {
Ok(failed) => { Ok(failed) => {
let code = i32::from(failed); let code = failed.into();
stack.add_env_var( stack.set_last_exit_code(code, Span::unknown());
"LAST_EXIT_CODE".into(),
Value::int(code.into(), Span::unknown()),
);
code code
} }
Err(err) => { Err(err) => {
report_error_new(engine_state, &err); report_error_new(engine_state, &err);
let code = err.exit_code(); let code = err.exit_code();
stack.set_last_exit_code(&err); stack.set_last_error(&err);
code code
} }
}; };

View File

@ -490,7 +490,7 @@ pub fn eval_block_with_early_return<D: DebugContext>(
} }
} }
pub fn eval_block<D: DebugContext>( fn eval_block_inner<D: DebugContext>(
engine_state: &EngineState, engine_state: &EngineState,
stack: &mut Stack, stack: &mut Stack,
block: &Block, block: &Block,
@ -501,8 +501,6 @@ pub fn eval_block<D: DebugContext>(
return eval_ir_block::<D>(engine_state, stack, block, input); return eval_ir_block::<D>(engine_state, stack, block, input);
} }
D::enter_block(engine_state, block);
let num_pipelines = block.len(); let num_pipelines = block.len();
for (pipeline_idx, pipeline) in block.pipelines.iter().enumerate() { for (pipeline_idx, pipeline) in block.pipelines.iter().enumerate() {
@ -547,10 +545,10 @@ pub fn eval_block<D: DebugContext>(
PipelineData::ByteStream(stream, ..) => { PipelineData::ByteStream(stream, ..) => {
let span = stream.span(); let span = stream.span();
if let Err(err) = stream.drain() { if let Err(err) = stream.drain() {
stack.set_last_exit_code(&err); stack.set_last_error(&err);
return Err(err); return Err(err);
} else { } else {
stack.add_env_var("LAST_EXIT_CODE".into(), Value::int(0, span)); stack.set_last_exit_code(0, span);
} }
} }
PipelineData::ListStream(stream, ..) => stream.drain()?, PipelineData::ListStream(stream, ..) => stream.drain()?,
@ -560,11 +558,24 @@ pub fn eval_block<D: DebugContext>(
} }
} }
D::leave_block(engine_state, block);
Ok(input) Ok(input)
} }
pub fn eval_block<D: DebugContext>(
engine_state: &EngineState,
stack: &mut Stack,
block: &Block,
input: PipelineData,
) -> Result<PipelineData, ShellError> {
D::enter_block(engine_state, block);
let result = eval_block_inner::<D>(engine_state, stack, block, input);
D::leave_block(engine_state, block);
if let Err(err) = &result {
stack.set_last_error(err);
}
result
}
pub fn eval_collect<D: DebugContext>( pub fn eval_collect<D: DebugContext>(
engine_state: &EngineState, engine_state: &EngineState,
stack: &mut Stack, stack: &mut Stack,

View File

@ -1356,11 +1356,10 @@ fn drain(ctx: &mut EvalContext<'_>, data: PipelineData) -> Result<InstructionRes
PipelineData::ByteStream(stream, ..) => { PipelineData::ByteStream(stream, ..) => {
let span = stream.span(); let span = stream.span();
if let Err(err) = stream.drain() { if let Err(err) = stream.drain() {
ctx.stack.set_last_exit_code(&err); ctx.stack.set_last_error(&err);
return Err(err); return Err(err);
} else { } else {
ctx.stack ctx.stack.set_last_exit_code(0, span);
.add_env_var("LAST_EXIT_CODE".into(), Value::int(0, span));
} }
} }
PipelineData::ListStream(stream, ..) => stream.drain()?, PipelineData::ListStream(stream, ..) => stream.drain()?,

View File

@ -279,12 +279,14 @@ impl Stack {
} }
} }
pub fn set_last_exit_code(&mut self, error: &ShellError) { pub fn set_last_exit_code(&mut self, code: i32, span: Span) {
let code = error.exit_code_spanned(); self.add_env_var("LAST_EXIT_CODE".into(), Value::int(code.into(), span));
self.add_env_var( }
"LAST_EXIT_CODE".into(),
Value::int(code.item.into(), code.span), pub fn set_last_error(&mut self, error: &ShellError) {
); if let Some(code) = error.external_exit_code() {
self.set_last_exit_code(code.item, code.span);
}
} }
pub fn last_overlay_name(&self) -> Result<String, ShellError> { pub fn last_overlay_name(&self) -> Result<String, ShellError> {

View File

@ -1437,18 +1437,18 @@ On Windows, this would be %USERPROFILE%\AppData\Roaming"#
} }
impl ShellError { impl ShellError {
pub fn exit_code_spanned(&self) -> Spanned<i32> { pub fn external_exit_code(&self) -> Option<Spanned<i32>> {
let (item, span) = match *self { let (item, span) = match *self {
Self::NonZeroExitCode { exit_code, span } => (exit_code, span), Self::NonZeroExitCode { exit_code, span } => (exit_code, span),
Self::ProcessSignaled { signal, span, .. } Self::ProcessSignaled { signal, span, .. }
| Self::ProcessCoreDumped { signal, span, .. } => (-signal, span), | Self::ProcessCoreDumped { signal, span, .. } => (-signal, span),
_ => (1, Span::unknown()), // TODO: better span here _ => return None,
}; };
Spanned { item, span } Some(Spanned { item, span })
} }
pub fn exit_code(&self) -> i32 { pub fn exit_code(&self) -> i32 {
self.exit_code_spanned().item self.external_exit_code().map(|e| e.item).unwrap_or(1)
} }
// TODO: Implement as From trait // TODO: Implement as From trait