1pub mod command;
2pub mod network;
3pub mod network_hetzner;
4pub mod nginx;
5pub mod pm2;
6
7use std::process::Output;
8
9pub(crate) fn decode_output(bytes: &[u8]) -> String {
10 let text = String::from_utf8_lossy(bytes).trim().to_string();
11 if text.is_empty() {
12 "(empty)".to_string()
13 } else {
14 text
15 }
16}
17
18pub(crate) fn command_debug_log(
19 debug: bool,
20 program: &str,
21 args: &[&str],
22 output: &Output,
23 logger: impl FnOnce(String),
24) {
25 if !debug {
26 return;
27 }
28 logger(format!(
29 "{} {} -> status={} stdout='{}' stderr='{}'",
30 program,
31 args.join(" "),
32 output.status,
33 decode_output(&output.stdout),
34 decode_output(&output.stderr)
35 ));
36}
37
38pub(crate) fn command_failure_message(
39 program: &str,
40 args: &[&str],
41 output: &Output,
42 hint: Option<&str>,
43) -> String {
44 let stderr = decode_output(&output.stderr);
45 let stdout = decode_output(&output.stdout);
46 let mut message = format!(
47 "{} {} failed with status {}.\nstdout: {}\nstderr: {}",
48 program,
49 args.join(" "),
50 output.status,
51 stdout,
52 stderr
53 );
54 if let Some(hint) = hint {
55 message.push_str(&format!("\nhelp: {}", hint));
56 }
57 message
58}