Repository: tauri-apps/tauri
File: crates/tauri-cli/src/lib.rs (Rust)

Code before:
    let cmdline = format!("{program} {args}");
    log::debug!(action = "Running"; "Command `{cmdline}`");

    self.stdout(Stdio::piped());
    self.stderr(Stdio::piped());

    let mut child = self
      .spawn()
      .with_context(|| format!("failed to run command `{cmdline}`"))?;

    let mut stdout = child.stdout.take().map(BufReader::new).unwrap();
    let stdout_lines = Arc::new(Mutex::new(Vec::new()));
    let stdout_lines_ = stdout_lines.clone();
    std::thread::spawn(move || {
      let mut line = String::new();
      loop {
        line.clear();
        match stdout.read_line(&mut line) {
          Ok(0) => break,
          Ok(_) => {
            log::debug!(action = "stdout"; "{}", line.trim_end());
            if let Ok(mut lines) = stdout_lines_.lock() {
              lines.extend(line.as_bytes());
            }
          }
          Err(_) => break,
        }
      }
    });

    let mut stderr = child.stderr.take().map(BufReader::new).unwrap();
    let stderr_lines = Arc::new(Mutex::new(Vec::new()));
    let stderr_lines_ = stderr_lines.clone();
    std::thread::spawn(move || {
      let mut line = String::new();
      loop {
        line.clear();
        match stderr.read_line(&mut line) {
          Ok(0) => break,
          Ok(_) => {
            log::debug!(action = "stderr"; "{}", line.trim_end());
            if let Ok(mut lines) = stderr_lines_.lock() {
              lines.extend(line.as_bytes());
            }
          }
          Err(_) => break,
        }
      }
    });

    let status = child

Review comment (suggestion):
probably not a good idea, just because one line may error out doesn't mean we should stop reading completely. Except of course if we've had issues with the old behavior which i'm not aware of.

Code after:

  fn output_ok(&mut self) -> crate::Result<Output> {
    let program = self.get_program().to_string_lossy().into_owned();
    let args = self
      .get_args()
      .map(|a| a.to_string_lossy())
      .collect::<Vec<_>>()
      .join(" ");
    let cmdline = format!("{program} {args}");
    log::debug!(action = "Running"; "Command `{cmdline}`");

    self.stdout(Stdio::piped());
    self.stderr(Stdio::piped());

    let mut child = self
      .spawn()
      .with_context(|| format!("failed to run command `{cmdline}`"))?;

    let mut stdout = child.stdout.take().map(BufReader::new).unwrap();
    let stdout_lines = Arc::new(Mutex::new(Vec::new()));
    let stdout_lines_ = stdout_lines.clone();
    std::thread::spawn(move || {
      let mut line = String::new();
      if let Ok(mut lines) = stdout_lines_.lock() {
        loop {
          line.clear();
          match stdout.read_line(&mut line) {
            Ok(0) => break,
            Ok(_) => {
              log::debug!(action = "stdout"; "{}", line.trim_end());
              lines.extend(line.as_bytes());
            }
            Err(_) => (),
          }
        }
      }
    });

    let mut stderr = child.stderr.take().map(BufReader::new).unwrap();
    let stderr_lines = Arc::new(Mutex::new(Vec::new()));
    let stderr_lines_ = stderr_lines.clone();
    std::thread::spawn(move || {
      let mut line = String::new();
      if let Ok(mut lines) = stderr_lines_.lock() {
        loop {
          line.clear();
          match stderr.read_line(&mut line) {
            Ok(0) => break,
            Ok(_) => {
              log::debug!(action = "stderr"; "{}", line.trim_end());
              lines.extend(line.as_bytes());