chore(core): fix command info (#30720)
<!-- Please make sure you have read the submission guidelines before posting an PR --> <!-- https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr --> <!-- Please make sure that your commit message follows our format --> <!-- Example: `fix(nx): must begin with lowercase` --> <!-- If this is a particularly complex change or feature addition, you can request a dedicated Nx release for this pull request branch. Mention someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they will confirm if the PR warrants its own release for testing purposes, and generate it for you if appropriate. --> ## Current Behavior <!-- This is the behavior we have today --> "Printing" the command info before output causes `run-script` to hang and not run. In addition, the screen was cleared. ## Expected Behavior <!-- This is the behavior we should expect with the changes in this PR --> The command in run-script runs without issues. The screen is not cleared. ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes #
This commit is contained in:
parent
9a60dec0de
commit
016e5fda2a
@ -64,6 +64,7 @@ async function ptyProcess(
|
|||||||
env: Record<string, string>
|
env: Record<string, string>
|
||||||
) {
|
) {
|
||||||
const terminal = createPseudoTerminal();
|
const terminal = createPseudoTerminal();
|
||||||
|
await terminal.init();
|
||||||
|
|
||||||
return new Promise<void>((res, rej) => {
|
return new Promise<void>((res, rej) => {
|
||||||
const cp = terminal.runCommand(command, { cwd, jsEnv: env });
|
const cp = terminal.runCommand(command, { cwd, jsEnv: env });
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use crossbeam_channel::{bounded, unbounded, Receiver};
|
use crossbeam_channel::{bounded, unbounded, Receiver, Sender};
|
||||||
use crossterm::{
|
use crossterm::{
|
||||||
terminal,
|
terminal,
|
||||||
terminal::{disable_raw_mode, enable_raw_mode},
|
terminal::{disable_raw_mode, enable_raw_mode},
|
||||||
tty::IsTty,
|
tty::IsTty,
|
||||||
};
|
};
|
||||||
|
use itertools::Itertools;
|
||||||
use napi::bindgen_prelude::*;
|
use napi::bindgen_prelude::*;
|
||||||
use portable_pty::{CommandBuilder, NativePtySystem, PtyPair, PtySize, PtySystem};
|
use portable_pty::{CommandBuilder, NativePtySystem, PtyPair, PtySize, PtySystem};
|
||||||
use std::io::stdout;
|
use std::io::stdout;
|
||||||
@ -27,7 +28,8 @@ use crate::native::pseudo_terminal::child_process::ChildProcess;
|
|||||||
|
|
||||||
pub struct PseudoTerminal {
|
pub struct PseudoTerminal {
|
||||||
pub pty_pair: PtyPair,
|
pub pty_pair: PtyPair,
|
||||||
pub message_rx: Receiver<String>,
|
pub stdout_tx: Sender<String>,
|
||||||
|
pub stdout_rx: Receiver<String>,
|
||||||
pub printing_rx: Receiver<()>,
|
pub printing_rx: Receiver<()>,
|
||||||
pub quiet: Arc<AtomicBool>,
|
pub quiet: Arc<AtomicBool>,
|
||||||
pub running: Arc<AtomicBool>,
|
pub running: Arc<AtomicBool>,
|
||||||
@ -84,7 +86,7 @@ impl PseudoTerminal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut reader = pty_pair.master.try_clone_reader()?;
|
let mut reader = pty_pair.master.try_clone_reader()?;
|
||||||
let (message_tx, message_rx) = unbounded();
|
let (stdout_tx, stdout_rx) = unbounded();
|
||||||
let (printing_tx, printing_rx) = unbounded();
|
let (printing_tx, printing_rx) = unbounded();
|
||||||
// Output -> stdout handling
|
// Output -> stdout handling
|
||||||
let quiet_clone = quiet.clone();
|
let quiet_clone = quiet.clone();
|
||||||
@ -92,25 +94,21 @@ impl PseudoTerminal {
|
|||||||
|
|
||||||
let parser = Arc::new(RwLock::new(Parser::new(h, w, 10000)));
|
let parser = Arc::new(RwLock::new(Parser::new(h, w, 10000)));
|
||||||
let parser_clone = parser.clone();
|
let parser_clone = parser.clone();
|
||||||
|
let stdout_tx_clone = stdout_tx.clone();
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
let mut stdout = std::io::stdout();
|
let mut stdout = std::io::stdout();
|
||||||
let mut buf = [0; 8 * 1024];
|
let mut buf = [0; 8 * 1024];
|
||||||
let mut first: bool = true;
|
|
||||||
|
|
||||||
'read_loop: loop {
|
'read_loop: loop {
|
||||||
if let Ok(len) = reader.read(&mut buf) {
|
if let Ok(len) = reader.read(&mut buf) {
|
||||||
if len == 0 {
|
if len == 0 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
message_tx
|
stdout_tx_clone
|
||||||
.send(String::from_utf8_lossy(&buf[0..len]).to_string())
|
.send(String::from_utf8_lossy(&buf[0..len]).to_string())
|
||||||
.ok();
|
.ok();
|
||||||
let quiet = quiet_clone.load(Ordering::Relaxed);
|
let quiet = quiet_clone.load(Ordering::Relaxed);
|
||||||
trace!("Quiet: {}", quiet);
|
trace!("Quiet: {}", quiet);
|
||||||
let contains_clear = buf[..len]
|
|
||||||
.windows(4)
|
|
||||||
.any(|window| window == [0x1B, 0x5B, 0x32, 0x4A]);
|
|
||||||
debug!("Contains clear: {}", contains_clear);
|
|
||||||
debug!("Read {} bytes", len);
|
debug!("Read {} bytes", len);
|
||||||
if let Ok(mut parser) = parser_clone.write() {
|
if let Ok(mut parser) = parser_clone.write() {
|
||||||
let prev = parser.screen().clone();
|
let prev = parser.screen().clone();
|
||||||
@ -118,12 +116,7 @@ impl PseudoTerminal {
|
|||||||
parser.process(&buf[..len]);
|
parser.process(&buf[..len]);
|
||||||
debug!("{}", parser.get_raw_output().len());
|
debug!("{}", parser.get_raw_output().len());
|
||||||
|
|
||||||
let write_buf = if first {
|
let write_buf = parser.screen().contents_diff(&prev);
|
||||||
parser.screen().contents_formatted()
|
|
||||||
} else {
|
|
||||||
parser.screen().contents_diff(&prev)
|
|
||||||
};
|
|
||||||
first = false;
|
|
||||||
if !quiet {
|
if !quiet {
|
||||||
let mut logged_interrupted_error = false;
|
let mut logged_interrupted_error = false;
|
||||||
while let Err(e) = stdout.write_all(&write_buf) {
|
while let Err(e) = stdout.write_all(&write_buf) {
|
||||||
@ -162,7 +155,8 @@ impl PseudoTerminal {
|
|||||||
running,
|
running,
|
||||||
parser,
|
parser,
|
||||||
pty_pair,
|
pty_pair,
|
||||||
message_rx,
|
stdout_rx,
|
||||||
|
stdout_tx,
|
||||||
printing_rx,
|
printing_rx,
|
||||||
is_within_nx_tui,
|
is_within_nx_tui,
|
||||||
})
|
})
|
||||||
@ -204,17 +198,16 @@ impl PseudoTerminal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let (exit_to_process_tx, exit_to_process_rx) = bounded(1);
|
let (exit_to_process_tx, exit_to_process_rx) = bounded(1);
|
||||||
|
|
||||||
|
let command_info = format!("> {}\n\n\r", command);
|
||||||
|
self.stdout_tx.send(command_info.clone()).ok();
|
||||||
|
|
||||||
|
self.parser
|
||||||
|
.write()
|
||||||
|
.expect("Failed to acquire parser write lock")
|
||||||
|
.process(command_info.as_bytes());
|
||||||
|
|
||||||
trace!("Running {}", command);
|
trace!("Running {}", command);
|
||||||
|
|
||||||
// TODO(@FrozenPandaz): This access is too naive, we need to handle the writer lock properly (e.g. multiple invocations of run_command sequentially)
|
|
||||||
// Prepend the command to the output
|
|
||||||
self.writer
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
// Sadly ANSI escape codes don't seem to work properly when writing directly to the writer...
|
|
||||||
.write_all(format!("> {}\n\n", command).as_bytes())
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut child = pair.slave.spawn_command(cmd)?;
|
let mut child = pair.slave.spawn_command(cmd)?;
|
||||||
self.running.store(true, Ordering::SeqCst);
|
self.running.store(true, Ordering::SeqCst);
|
||||||
|
|
||||||
@ -270,7 +263,7 @@ impl PseudoTerminal {
|
|||||||
self.parser.clone(),
|
self.parser.clone(),
|
||||||
self.writer.clone(),
|
self.writer.clone(),
|
||||||
process_killer,
|
process_killer,
|
||||||
self.message_rx.clone(),
|
self.stdout_rx.clone(),
|
||||||
exit_to_process_rx,
|
exit_to_process_rx,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user