xbp 10.15.4

XBP is a zero-config build pack that can also interact with proxies, kafka, sockets, synthetic monitors.
Documentation
pub mod command;
pub mod nginx;
pub mod pm2;

use std::process::Output;

pub(crate) fn decode_output(bytes: &[u8]) -> String {
    let text = String::from_utf8_lossy(bytes).trim().to_string();
    if text.is_empty() {
        "(empty)".to_string()
    } else {
        text
    }
}

pub(crate) fn command_debug_log(
    debug: bool,
    program: &str,
    args: &[&str],
    output: &Output,
    logger: impl FnOnce(String),
) {
    if !debug {
        return;
    }
    logger(format!(
        "{} {} -> status={} stdout='{}' stderr='{}'",
        program,
        args.join(" "),
        output.status,
        decode_output(&output.stdout),
        decode_output(&output.stderr)
    ));
}

pub(crate) fn command_failure_message(
    program: &str,
    args: &[&str],
    output: &Output,
    hint: Option<&str>,
) -> String {
    let stderr = decode_output(&output.stderr);
    let stdout = decode_output(&output.stdout);
    let mut message = format!(
        "{} {} failed with status {}.\nstdout: {}\nstderr: {}",
        program,
        args.join(" "),
        output.status,
        stdout,
        stderr
    );
    if let Some(hint) = hint {
        message.push_str(&format!("\nhelp: {}", hint));
    }
    message
}