mirror of
https://github.com/nushell/nushell.git
synced 2024-11-22 08:23:24 +01:00
avoid freeze for table print (#6688)
* avoid freeze for table print * make failed_with_proper_exit_code work again * add test case for table * fix un-used import on windows
This commit is contained in:
parent
2f1711f783
commit
1998bce19f
@ -231,23 +231,18 @@ pub fn eval_source(
|
||||
}
|
||||
|
||||
match eval_block(engine_state, stack, &block, input, false, false) {
|
||||
Ok(mut pipeline_data) => {
|
||||
if let PipelineData::ExternalStream { exit_code, .. } = &mut pipeline_data {
|
||||
if let Some(exit_code) = exit_code.take().and_then(|it| it.last()) {
|
||||
stack.add_env_var("LAST_EXIT_CODE".to_string(), exit_code);
|
||||
} else {
|
||||
set_last_exit_code(stack, 0);
|
||||
Ok(pipeline_data) => {
|
||||
match pipeline_data.print(engine_state, stack, false, false) {
|
||||
Err(err) => {
|
||||
let working_set = StateWorkingSet::new(engine_state);
|
||||
|
||||
report_error(&working_set, &err);
|
||||
|
||||
return false;
|
||||
}
|
||||
Ok(exit_code) => {
|
||||
set_last_exit_code(stack, exit_code);
|
||||
}
|
||||
} else {
|
||||
set_last_exit_code(stack, 0);
|
||||
}
|
||||
|
||||
if let Err(err) = pipeline_data.print(engine_state, stack, false, false) {
|
||||
let working_set = StateWorkingSet::new(engine_state);
|
||||
|
||||
report_error(&working_set, &err);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// reset vt processing, aka ansi because illbehaved externals can break it
|
||||
|
@ -135,3 +135,28 @@ fn table_expand_flatten_and_deep_1() {
|
||||
╰───┴───┴───┴────────────────────────────────╯"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(windows))]
|
||||
fn external_with_too_much_stdout_should_not_hang_nu() {
|
||||
use nu_test_support::fs::Stub::FileWithContent;
|
||||
use nu_test_support::pipeline;
|
||||
use nu_test_support::playground::Playground;
|
||||
Playground::setup("external with too much stdout", |dirs, sandbox| {
|
||||
let bytes: usize = 81920;
|
||||
let mut large_file_body = String::with_capacity(bytes);
|
||||
for _ in 0..bytes {
|
||||
large_file_body.push_str("a");
|
||||
}
|
||||
sandbox.with_files(vec![FileWithContent("a_large_file.txt", &large_file_body)]);
|
||||
|
||||
let actual = nu!(
|
||||
cwd: dirs.test(), pipeline(
|
||||
r#"
|
||||
cat a_large_file.txt | table
|
||||
"#
|
||||
));
|
||||
|
||||
assert_eq!(actual.out, large_file_body);
|
||||
})
|
||||
}
|
||||
|
@ -424,7 +424,7 @@ impl PipelineData {
|
||||
stack: &mut Stack,
|
||||
no_newline: bool,
|
||||
to_stderr: bool,
|
||||
) -> Result<(), ShellError> {
|
||||
) -> Result<i64, ShellError> {
|
||||
// If the table function is in the declarations, then we can use it
|
||||
// to create the table value that will be printed in the terminal
|
||||
|
||||
@ -452,10 +452,13 @@ impl PipelineData {
|
||||
|
||||
// Make sure everything has finished
|
||||
if let Some(exit_code) = exit_code {
|
||||
let _: Vec<_> = exit_code.into_iter().collect();
|
||||
let mut exit_codes: Vec<_> = exit_code.into_iter().collect();
|
||||
if let Some(Value::Int { val, .. }) = exit_codes.pop() {
|
||||
return Ok(val);
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
match engine_state.find_decl("table".as_bytes(), &[]) {
|
||||
@ -474,7 +477,7 @@ impl PipelineData {
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn write_all_and_flush(
|
||||
@ -483,7 +486,7 @@ impl PipelineData {
|
||||
config: &Config,
|
||||
no_newline: bool,
|
||||
to_stderr: bool,
|
||||
) -> Result<(), ShellError> {
|
||||
) -> Result<i64, ShellError> {
|
||||
for item in self {
|
||||
let mut out = if let Value::Error { error } = item {
|
||||
let working_set = StateWorkingSet::new(engine_state);
|
||||
@ -506,7 +509,7 @@ impl PipelineData {
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(0)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -314,11 +314,10 @@ mod nu_commands {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "For now we have no way to check LAST_EXIT_CODE in tests, ignore it for now"]
|
||||
fn failed_with_proper_exit_code() {
|
||||
Playground::setup("external failed", |dirs, _sandbox| {
|
||||
let actual = nu!(cwd: dirs.test(), r#"
|
||||
nu -c "cargo build; print $env.LAST_EXIT_CODE"
|
||||
nu -c "cargo build | complete | get exit_code"
|
||||
"#);
|
||||
|
||||
// cargo for non rust project's exit code is 101.
|
||||
|
Loading…
Reference in New Issue
Block a user