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()),
);
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 temp_file = temp_dir().join(format!("{}.nu", uuid::Uuid::new_v4()));
@ -837,7 +837,7 @@ fn do_auto_cd(
"NUSHELL_LAST_SHELL".into(),
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) {
Ok(failed) => {
let code = i32::from(failed);
stack.add_env_var(
"LAST_EXIT_CODE".into(),
Value::int(code.into(), Span::unknown()),
);
let code = failed.into();
stack.set_last_exit_code(code, Span::unknown());
code
}
Err(err) => {
report_error_new(engine_state, &err);
let code = err.exit_code();
stack.set_last_exit_code(&err);
stack.set_last_error(&err);
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,
stack: &mut Stack,
block: &Block,
@ -501,8 +501,6 @@ pub fn eval_block<D: DebugContext>(
return eval_ir_block::<D>(engine_state, stack, block, input);
}
D::enter_block(engine_state, block);
let num_pipelines = block.len();
for (pipeline_idx, pipeline) in block.pipelines.iter().enumerate() {
@ -547,10 +545,10 @@ pub fn eval_block<D: DebugContext>(
PipelineData::ByteStream(stream, ..) => {
let span = stream.span();
if let Err(err) = stream.drain() {
stack.set_last_exit_code(&err);
stack.set_last_error(&err);
return Err(err);
} 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()?,
@ -560,11 +558,24 @@ pub fn eval_block<D: DebugContext>(
}
}
D::leave_block(engine_state, block);
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>(
engine_state: &EngineState,
stack: &mut Stack,

View File

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

View File

@ -279,12 +279,14 @@ impl Stack {
}
}
pub fn set_last_exit_code(&mut self, error: &ShellError) {
let code = error.exit_code_spanned();
self.add_env_var(
"LAST_EXIT_CODE".into(),
Value::int(code.item.into(), code.span),
);
pub fn set_last_exit_code(&mut self, code: i32, span: Span) {
self.add_env_var("LAST_EXIT_CODE".into(), Value::int(code.into(), 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> {

View File

@ -1437,18 +1437,18 @@ On Windows, this would be %USERPROFILE%\AppData\Roaming"#
}
impl ShellError {
pub fn exit_code_spanned(&self) -> Spanned<i32> {
pub fn external_exit_code(&self) -> Option<Spanned<i32>> {
let (item, span) = match *self {
Self::NonZeroExitCode { exit_code, span } => (exit_code, span),
Self::ProcessSignaled { 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 {
self.exit_code_spanned().item
self.external_exit_code().map(|e| e.item).unwrap_or(1)
}
// TODO: Implement as From trait