Skip to content

Commit

Permalink
Merge pull request #108 from theseus-rs/improve-windows-commands
Browse files Browse the repository at this point in the history
fix: improve commands on windows to return stdout and stderr
  • Loading branch information
brianheineman authored Jul 17, 2024
2 parents 282e75f + 14863d5 commit a3f0c4b
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 73 deletions.
22 changes: 0 additions & 22 deletions .github/workflows/clear-caches.yml

This file was deleted.

91 changes: 40 additions & 51 deletions postgresql_commands/src/traits.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::error::{Error, Result};
use std::env::consts::OS;
use std::ffi::{OsStr, OsString};
use std::fmt::Debug;
use std::path::PathBuf;
use std::process::ExitStatus;
use std::time::Duration;
use tracing::debug;

Expand Down Expand Up @@ -140,46 +142,37 @@ impl CommandExecutor for std::process::Command {
/// Execute the command and return the stdout and stderr
fn execute(&mut self) -> Result<(String, String)> {
debug!("Executing command: {}", self.to_command_string());
#[cfg(not(target_os = "windows"))]
{
let output = self.output()?;
let stdout = String::from_utf8_lossy(&output.stdout).into_owned();
let stderr = String::from_utf8_lossy(&output.stderr).into_owned();

debug!(
"Result: {}\nstdout: {}\nstderr: {}",
output
.status
.code()
.map_or("None".to_string(), |c| c.to_string()),
stdout,
stderr
);

if output.status.success() {
Ok((stdout, stderr))
} else {
Err(Error::CommandError { stdout, stderr })
}
}
let program = self.get_program().to_string_lossy().to_string();
let stdout: String;
let stderr: String;
let status: ExitStatus;

// TODO: Processes can hang on Windows when attempting to get stdout/stderr using code
// that works for Linux/MacOS; this implementation should be updated to retrieve the
// values of stdout/stderr without hanging
#[cfg(target_os = "windows")]
{
if OS == "windows" && program.as_str().ends_with("pg_ctl") {
// The pg_ctl process can hang on Windows when attempting to get stdout/stderr.
let mut process = self
.stdout(std::process::Stdio::piped())
.stderr(std::process::Stdio::piped())
.spawn()?;
let status = process.wait()?;
let stdout = String::new();
let stderr = String::new();
if status.success() {
Ok((stdout, stderr))
} else {
Err(Error::CommandError { stdout, stderr })
}
stdout = String::new();
stderr = String::new();
status = process.wait()?;
} else {
let output = self.output()?;
stdout = String::from_utf8_lossy(&output.stdout).into_owned();
stderr = String::from_utf8_lossy(&output.stderr).into_owned();
status = output.status;
}
debug!(
"Result: {}\nstdout: {}\nstderr: {}",
status.code().map_or("None".to_string(), |c| c.to_string()),
stdout,
stderr
);

if status.success() {
Ok((stdout, stderr))
} else {
Err(Error::CommandError { stdout, stderr })
}
}
}
Expand All @@ -194,19 +187,18 @@ impl AsyncCommandExecutor for tokio::process::Command {
Some(duration) => tokio::time::timeout(duration, self.output()).await?,
None => self.output().await,
}?;

#[cfg(not(target_os = "windows"))]
let stdout = String::from_utf8_lossy(&output.stdout).into_owned();
#[cfg(not(target_os = "windows"))]
let stderr = String::from_utf8_lossy(&output.stderr).into_owned();

// TODO: Processes can hang on Windows when attempting to get stdout/stderr using code
// that works for Linux/MacOS; this implementation should be updated to retrieve the
// values of stdout/stderr without hanging
#[cfg(target_os = "windows")]
let stdout = String::new();
#[cfg(target_os = "windows")]
let stderr = String::new();
let program = self.as_std().get_program().to_string_lossy().to_string();
let stdout: String;
let stderr: String;

if OS == "windows" && program.as_str().ends_with("pg_ctl") {
// The pg_ctl process can hang on Windows when attempting to get stdout/stderr.
stdout = String::new();
stderr = String::new();
} else {
stdout = String::from_utf8_lossy(&output.stdout).into_owned();
stderr = String::from_utf8_lossy(&output.stderr).into_owned();
}

debug!(
"Result: {}\nstdout: {}\nstderr: {}",
Expand Down Expand Up @@ -371,10 +363,7 @@ mod test {
command.args(["/C", "echo foo"]);

let (stdout, stderr) = command.execute()?;
#[cfg(not(target_os = "windows"))]
assert!(stdout.starts_with("foo"));
#[cfg(target_os = "windows")]
assert!(stdout.is_empty());
assert!(stderr.is_empty());
Ok(())
}
Expand Down

0 comments on commit a3f0c4b

Please sign in to comment.