use anyhow::{Context, Result as AResult};
use clap::{Parser, Subcommand};
pub use common::*;
use global::GlobalsFinal;
use std::path::PathBuf;
mod bubblewrap;
mod common;
mod extract;
mod global;
#[cfg(feature = "remap")]
mod remap;
mod sandbox;
mod snapshot;
const CONFIGFILE: &str = "${XDG_CONFIG_HOME:-~/.config}/genpac/config.toml";
#[derive(Subcommand)]
pub enum SubCommands {
#[cfg(feature = "remap")]
Remap(remap::SubCmdArgs),
#[command(alias = "sbox")]
Sandbox(sandbox::SubCmdArgs),
#[command(subcommand, alias = "snap")]
Snapshot(snapshot::SubCmdArgs),
Extract(extract::SubCmdArgs),
}
impl SubCommands {
fn dispatch(self, globals: GlobalsFinal) -> AResult<()> {
match self {
#[cfg(feature = "remap")]
Self::Remap(sc) => sc.handle(globals)?,
Self::Sandbox(sc) => sc.handle(globals)?,
Self::Snapshot(sc) => sc.handle(globals)?,
Self::Extract(sc) => sc.handle(globals)?,
}
Ok(())
}
}
fn main() -> AResult<()> {
let cli = global::Cli::parse();
let globals = cli.globals().init_logger()?;
let cfg = shellexpand::env(CONFIGFILE).context("Cannot expand config file path")?;
let cfg = shellexpand::tilde(&cfg);
let cfg = PathBuf::from(cfg.as_ref());
if !cfg.is_file() {
let e = format!("Config file '{}' not found. Cannot proceed!", cfg.display());
log::error!("{e}");
anyhow::bail!(e);
} else {
log::debug!("Loading config from '{}'", cfg.display());
}
let cfg = std::fs::read_to_string(cfg).context("Unable to read config file")?;
let globals = match globals.config(cfg) {
Ok(x) => x,
Err(e) => {
log::error!("Unable to parse configuration file:");
log::error!("{e}");
anyhow::bail!(e);
}
};
match cli.subcmd().dispatch(globals) {
Ok(()) => Ok(()),
Err(e) => {
log::error!("Failed to execute subcommand:");
log::error!("{e}");
anyhow::bail!(e);
}
}
}