diff options
| author | Doan Luu Duc Tai <doan@luuduct.ai> | 2026-10-30 14:00:58 -0500 |
|---|---|---|
| committer | Doan Luu Duc Tai <doan@luuduct.ai> | 2026-10-30 14:00:58 -0500 |
| commit | 19a0280d7dabd4ca637d8070cc7d3691a0e85bd1 (patch) | |
| tree | de4591ed54ef860f04dd88bb3aae51dee51237a7 /src/process.rs | |
| parent | 006a1e94075e90fccfe248cd66bf7d0586a86279 (diff) | |
Manage the portable stack with Rust and rootless Podman
Diffstat (limited to 'src/process.rs')
| -rw-r--r-- | src/process.rs | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/process.rs b/src/process.rs new file mode 100644 index 0000000..eb48bc8 --- /dev/null +++ b/src/process.rs @@ -0,0 +1,70 @@ +// Copyright (C) 2026 Doan Luu Duc Tai <doan@luuduct.ai> +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <https://www.gnu.org/licenses/>. + +use std::fmt; +use std::io::{self, Write}; +use std::process::{Command, Output}; + +use anyhow::{Context, Result, bail}; + +pub(crate) fn capture(command: &mut Command) -> Result<Output> { + let output = command.output().with_context(|| { + format!( + "Could not start {}", + command.get_program().to_string_lossy() + ) + })?; + if !output.status.success() { + bail!( + "{} failed ({}): {}", + command.get_program().to_string_lossy(), + output.status, + String::from_utf8_lossy(&output.stderr).trim() + ); + } + Ok(output) +} + +pub(crate) fn text(command: &mut Command) -> Result<String> { + String::from_utf8(capture(command)?.stdout).context("Command returned non-UTF-8 output") +} + +pub(crate) fn run(command: &mut Command) -> Result<()> { + let status = command.status().with_context(|| { + format!( + "Could not start {}", + command.get_program().to_string_lossy() + ) + })?; + if !status.success() { + bail!( + "{} failed ({status})", + command.get_program().to_string_lossy() + ); + } + Ok(()) +} + +pub(crate) fn available(command: &mut Command) -> bool { + command.output().is_ok_and(|output| output.status.success()) +} + +pub(crate) fn line(message: fmt::Arguments<'_>) -> Result<()> { + writeln!(io::stdout().lock(), "{message}").context("Could not write command output") +} + +pub(crate) fn error(message: fmt::Arguments<'_>) -> io::Result<()> { + writeln!(io::stderr().lock(), "{message}") +} |
