|
1 | 1 | //! Helpers intended for [`std::process::Command`] and related structures.
|
2 | 2 |
|
3 | 3 | use std::{
|
| 4 | + fmt::Write, |
4 | 5 | io::{Read, Seek},
|
5 | 6 | os::unix::process::CommandExt,
|
6 | 7 | process::Command,
|
@@ -33,6 +34,9 @@ pub trait CommandRunExt {
|
33 | 34 | /// Execute the child process, parsing its stdout as JSON. This uses `run` internally
|
34 | 35 | /// and will return an error if the child process exits abnormally.
|
35 | 36 | fn run_and_parse_json<T: serde::de::DeserializeOwned>(&mut self) -> Result<T>;
|
| 37 | + |
| 38 | + /// Print the command as it would be typed into a terminal |
| 39 | + fn to_string_pretty(&mut self) -> String; |
36 | 40 | }
|
37 | 41 |
|
38 | 42 | /// Helpers intended for [`std::process::ExitStatus`].
|
@@ -146,6 +150,19 @@ impl CommandRunExt for Command {
|
146 | 150 | // representation that the user can copy paste into their shell
|
147 | 151 | .context(format!("Failed to run command: {self:#?}"))
|
148 | 152 | }
|
| 153 | + |
| 154 | + fn to_string_pretty(&mut self) -> String { |
| 155 | + std::iter::once(self.get_program()) |
| 156 | + .chain(self.get_args()) |
| 157 | + .fold(String::new(), |mut acc, element| { |
| 158 | + if !acc.is_empty() { |
| 159 | + acc.push(' '); |
| 160 | + } |
| 161 | + // SAFETY: Writes to string can't fail |
| 162 | + write!(&mut acc, "{}", crate::PathQuotedDisplay::new(&element)).unwrap(); |
| 163 | + acc |
| 164 | + }) |
| 165 | + } |
149 | 166 | }
|
150 | 167 |
|
151 | 168 | /// Helpers intended for [`tokio::process::Command`].
|
@@ -224,4 +241,27 @@ mod tests {
|
224 | 241 | success.unwrap();
|
225 | 242 | assert!(fail.is_err());
|
226 | 243 | }
|
| 244 | + |
| 245 | + #[test] |
| 246 | + fn to_string_pretty() { |
| 247 | + let mut cmd = Command::new("podman"); |
| 248 | + cmd.args([ |
| 249 | + "run", |
| 250 | + "--privileged", |
| 251 | + "--pid=host", |
| 252 | + "--user=root:root", |
| 253 | + "-v", |
| 254 | + "/var/lib/containers:/var/lib/containers", |
| 255 | + "-v", |
| 256 | + "this has spaces", |
| 257 | + "label=type:unconfined_t", |
| 258 | + "--env=RUST_LOG=trace", |
| 259 | + "quay.io/ckyrouac/bootc-dev", |
| 260 | + "bootc", |
| 261 | + "install", |
| 262 | + "to-existing-root", |
| 263 | + ]); |
| 264 | + |
| 265 | + assert_eq!(cmd.to_string_pretty(), "podman run --privileged '--pid=host' '--user=root:root' -v /var/lib/containers:/var/lib/containers -v 'this has spaces' 'label=type:unconfined_t' '--env=RUST_LOG=trace' quay.io/ckyrouac/bootc-dev bootc install to-existing-root"); |
| 266 | + } |
227 | 267 | }
|
0 commit comments