use std::process::ExitCode;
use clap::Parser;
use log::{LevelFilter, debug};
use rootless_run::{RootlessBackend, RootlesskitBackend, RootlesskitOptions};
use simplelog::{ColorChoice, Config, TermLogger, TerminalMode};
#[derive(Debug, thiserror::Error)]
enum Error {
#[error(transparent)]
Rootlesskit(#[from] rootless_run::Error),
#[error("Non-zero return code:\n{stderr}")]
NonZero {
stderr: String,
},
}
#[derive(Debug, Parser)]
struct Cli {
#[arg(help = "A command to run with rootlesskit")]
cmd: Vec<String>,
}
fn init_logger() {
if TermLogger::init(
LevelFilter::Debug,
Config::default(),
TerminalMode::Stderr,
ColorChoice::Auto,
)
.is_err()
{
debug!("Not initializing another logger, as one is initialized already.");
}
}
fn run_cmd(cmd: &[&str]) -> Result<(), Error> {
let backend = RootlesskitBackend::new(RootlesskitOptions::default());
let output = backend.run(cmd)?;
if !output.status.success() {
return Err(Error::NonZero {
stderr: format!("{}", String::from_utf8_lossy(&output.stderr)),
});
}
print!("{}", String::from_utf8_lossy(&output.stdout));
Ok(())
}
fn main() -> ExitCode {
init_logger();
let cli = Cli::parse();
let cmd: Vec<&str> = cli.cmd.iter().map(|arg| arg.as_str()).collect();
if let Err(error) = run_cmd(&cmd) {
eprintln!("{error}");
ExitCode::FAILURE
} else {
ExitCode::SUCCESS
}
}