mirror of
https://github.com/nushell/nushell.git
synced 2025-01-22 14:18:55 +01:00
Add exit code argument (#3132)
This commit is contained in:
parent
983de8974b
commit
d43489a6a0
@ -1,6 +1,6 @@
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{CommandAction, ReturnSuccess, Signature};
|
use nu_protocol::{CommandAction, ReturnSuccess, Signature, SyntaxShape};
|
||||||
|
|
||||||
pub struct Exit;
|
pub struct Exit;
|
||||||
|
|
||||||
@ -11,7 +11,13 @@ impl WholeStreamCommand for Exit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("exit").switch("now", "exit out of the shell immediately", Some('n'))
|
Signature::build("exit")
|
||||||
|
.optional(
|
||||||
|
"code",
|
||||||
|
SyntaxShape::Number,
|
||||||
|
"Status code to return if this was the last shell or --now was specified",
|
||||||
|
)
|
||||||
|
.switch("now", "Exit out of the shell immediately", Some('n'))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
@ -41,10 +47,16 @@ impl WholeStreamCommand for Exit {
|
|||||||
pub async fn exit(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
pub async fn exit(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||||
let args = args.evaluate_once().await?;
|
let args = args.evaluate_once().await?;
|
||||||
|
|
||||||
let command_action = if args.call_info.args.has("now") {
|
let code = if let Some(value) = args.call_info.args.nth(0) {
|
||||||
CommandAction::Exit
|
value.as_i32()?
|
||||||
} else {
|
} else {
|
||||||
CommandAction::LeaveShell
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
let command_action = if args.call_info.args.has("now") {
|
||||||
|
CommandAction::Exit(code)
|
||||||
|
} else {
|
||||||
|
CommandAction::LeaveShell(code)
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(OutputStream::one(ReturnSuccess::action(command_action)))
|
Ok(OutputStream::one(ReturnSuccess::action(command_action)))
|
||||||
|
@ -62,7 +62,7 @@ pub(crate) async fn run_internal_command(
|
|||||||
context.shell_manager.set_path(path);
|
context.shell_manager.set_path(path);
|
||||||
InputStream::empty()
|
InputStream::empty()
|
||||||
}
|
}
|
||||||
CommandAction::Exit => std::process::exit(0), // TODO: save history.txt
|
CommandAction::Exit(code) => std::process::exit(code), // TODO: save history.txt
|
||||||
CommandAction::Error(err) => {
|
CommandAction::Error(err) => {
|
||||||
context.error(err);
|
context.error(err);
|
||||||
InputStream::empty()
|
InputStream::empty()
|
||||||
@ -213,10 +213,10 @@ pub(crate) async fn run_internal_command(
|
|||||||
context.shell_manager.next();
|
context.shell_manager.next();
|
||||||
InputStream::empty()
|
InputStream::empty()
|
||||||
}
|
}
|
||||||
CommandAction::LeaveShell => {
|
CommandAction::LeaveShell(code) => {
|
||||||
context.shell_manager.remove_at_current();
|
context.shell_manager.remove_at_current();
|
||||||
if context.shell_manager.is_empty() {
|
if context.shell_manager.is_empty() {
|
||||||
std::process::exit(0); // TODO: save history.txt
|
std::process::exit(code); // TODO: save history.txt
|
||||||
}
|
}
|
||||||
InputStream::empty()
|
InputStream::empty()
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ pub enum CommandAction {
|
|||||||
/// Change to a new directory or path (in non-filesystem situations)
|
/// Change to a new directory or path (in non-filesystem situations)
|
||||||
ChangePath(String),
|
ChangePath(String),
|
||||||
/// Exit out of Nu
|
/// Exit out of Nu
|
||||||
Exit,
|
Exit(i32),
|
||||||
/// Display an error
|
/// Display an error
|
||||||
Error(ShellError),
|
Error(ShellError),
|
||||||
/// Enter a new shell at the given path
|
/// Enter a new shell at the given path
|
||||||
@ -27,7 +27,7 @@ pub enum CommandAction {
|
|||||||
/// Go to the next shell in the shell ring buffer
|
/// Go to the next shell in the shell ring buffer
|
||||||
NextShell,
|
NextShell,
|
||||||
/// Leave the current shell. If it's the last shell, exit out of Nu
|
/// Leave the current shell. If it's the last shell, exit out of Nu
|
||||||
LeaveShell,
|
LeaveShell(i32),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PrettyDebug for CommandAction {
|
impl PrettyDebug for CommandAction {
|
||||||
@ -37,7 +37,7 @@ impl PrettyDebug for CommandAction {
|
|||||||
CommandAction::ChangePath(path) => {
|
CommandAction::ChangePath(path) => {
|
||||||
DbgDocBldr::typed("change path", DbgDocBldr::description(path))
|
DbgDocBldr::typed("change path", DbgDocBldr::description(path))
|
||||||
}
|
}
|
||||||
CommandAction::Exit => DbgDocBldr::description("exit"),
|
CommandAction::Exit(_) => DbgDocBldr::description("exit"),
|
||||||
CommandAction::Error(_) => DbgDocBldr::error("error"),
|
CommandAction::Error(_) => DbgDocBldr::error("error"),
|
||||||
CommandAction::AutoConvert(_, extension) => {
|
CommandAction::AutoConvert(_, extension) => {
|
||||||
DbgDocBldr::typed("auto convert", DbgDocBldr::description(extension))
|
DbgDocBldr::typed("auto convert", DbgDocBldr::description(extension))
|
||||||
@ -50,7 +50,7 @@ impl PrettyDebug for CommandAction {
|
|||||||
CommandAction::AddPlugins(..) => DbgDocBldr::description("add plugins"),
|
CommandAction::AddPlugins(..) => DbgDocBldr::description("add plugins"),
|
||||||
CommandAction::PreviousShell => DbgDocBldr::description("previous shell"),
|
CommandAction::PreviousShell => DbgDocBldr::description("previous shell"),
|
||||||
CommandAction::NextShell => DbgDocBldr::description("next shell"),
|
CommandAction::NextShell => DbgDocBldr::description("next shell"),
|
||||||
CommandAction::LeaveShell => DbgDocBldr::description("leave shell"),
|
CommandAction::LeaveShell(_) => DbgDocBldr::description("leave shell"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -445,6 +445,14 @@ impl Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// View the Value as signed 64-bit, if possible
|
||||||
|
pub fn as_i32(&self) -> Result<i32, ShellError> {
|
||||||
|
match &self.value {
|
||||||
|
UntaggedValue::Primitive(primitive) => primitive.as_i32(self.tag.span),
|
||||||
|
_ => Err(ShellError::type_error("integer", self.spanned_type_name())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// View the Value as boolean, if possible
|
/// View the Value as boolean, if possible
|
||||||
pub fn as_bool(&self) -> Result<bool, ShellError> {
|
pub fn as_bool(&self) -> Result<bool, ShellError> {
|
||||||
match &self.value {
|
match &self.value {
|
||||||
|
@ -107,6 +107,29 @@ impl Primitive {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn as_i32(&self, span: Span) -> Result<i32, ShellError> {
|
||||||
|
match self {
|
||||||
|
Primitive::Int(int) => int.to_i32().ok_or_else(|| {
|
||||||
|
ShellError::range_error(
|
||||||
|
ExpectedRange::I32,
|
||||||
|
&format!("{}", int).spanned(span),
|
||||||
|
"converting an integer into a signed 32-bit integer",
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
Primitive::Decimal(decimal) => decimal.to_i32().ok_or_else(|| {
|
||||||
|
ShellError::range_error(
|
||||||
|
ExpectedRange::I32,
|
||||||
|
&format!("{}", decimal).spanned(span),
|
||||||
|
"converting a decimal into a signed 32-bit integer",
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
other => Err(ShellError::type_error(
|
||||||
|
"number",
|
||||||
|
other.type_name().spanned(span),
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: This is a bad name, but no other way to differentiate with our own Duration.
|
// FIXME: This is a bad name, but no other way to differentiate with our own Duration.
|
||||||
pub fn into_chrono_duration(self, span: Span) -> Result<chrono::Duration, ShellError> {
|
pub fn into_chrono_duration(self, span: Span) -> Result<chrono::Duration, ShellError> {
|
||||||
match self {
|
match self {
|
||||||
|
Loading…
Reference in New Issue
Block a user