diff --git a/.github/workflows/clear-caches.yml b/.github/workflows/clear-caches.yml deleted file mode 100644 index 3078fe2..0000000 --- a/.github/workflows/clear-caches.yml +++ /dev/null @@ -1,22 +0,0 @@ -# Clearing caches regularly takes care of caches growing to problematic size over time - -name: Clear caches - -on: - schedule: - - cron: '0 4 * * MON' - workflow_dispatch: - -permissions: - contents: read - -jobs: - clear-caches: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Clear all caches - run: gh cache delete --all - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/postgresql_commands/src/traits.rs b/postgresql_commands/src/traits.rs index 3c173a6..dbd6df5 100644 --- a/postgresql_commands/src/traits.rs +++ b/postgresql_commands/src/traits.rs @@ -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; @@ -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 }) } } } @@ -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: {}", @@ -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(()) }