use std::path::PathBuf;
use clap::{Parser, Subcommand};
use tracing::debug;
use tracing_subscriber::{EnvFilter, FmtSubscriber};
pub mod config;
mod core;
pub mod model;
pub mod traits;
pub mod utils;
#[macro_use]
mod macros;
use model::ModName;
use utils::validate_modname;
#[derive(Parser)]
#[clap(name = "Papa")]
#[clap(author = "AnAcutalEmerald <emerald_actual@proton.me>")]
#[clap(about = "Command line mod manager for Northstar")]
#[clap(after_help = "Welcome back. Cockpit cooling reactivated.")]
#[clap(version)]
struct Cli {
#[clap(subcommand)]
command: Commands,
#[clap(global = true, short, long)]
debug: bool,
#[clap(global = true, short = 'C', long = "no-cache")]
no_cache: bool,
}
#[derive(Subcommand)]
enum Commands {
Env {},
Export {
#[clap(default_value = "papa.ron")]
file: PathBuf,
},
Import {
#[arg(default_value = "papa.ron")]
file: PathBuf,
#[clap(short, long)]
yes: bool,
#[clap(short, long)]
force: bool,
},
#[clap(alias = "i")]
Install {
#[clap(value_name = "MOD")]
#[clap(help = "Mod name(s) to install")]
#[clap(required_unless_present = "file")]
#[clap(value_parser = validate_modname)]
mod_names: Vec<ModName>,
#[arg(short = 'F', long)]
file: Option<PathBuf>,
#[clap(short, long)]
yes: bool,
#[clap(short, long)]
force: bool,
#[clap(short, long)]
global: bool,
},
#[clap(alias = "r", alias = "rm")]
Remove {
#[clap(value_name = "MOD")]
#[clap(help = "Mod name(s) to remove")]
#[clap(value_parser = validate_modname)]
#[clap(required = true)]
mod_names: Vec<ModName>,
},
#[clap(alias = "l", alias = "ls")]
List {
#[clap(short, long)]
global: bool,
#[clap(short, long)]
all: bool,
},
#[clap(alias = "u")]
Update {
#[clap(short, long)]
yes: bool,
},
#[clap(alias = "s")]
Search {
term: Vec<String>,
},
Disable {
mods: Vec<String>,
#[clap(short, long)]
all: bool,
#[clap(short, long)]
force: bool,
},
Enable {
mods: Vec<String>,
#[arg(short, long)]
all: bool,
},
#[cfg(feature = "northstar")]
#[clap(alias("ns"))]
Northstar {
#[clap(subcommand)]
command: NstarCommands,
},
}
#[derive(Subcommand)]
pub enum NstarCommands {
Init {
#[arg(default_value_t = false, short, long)]
force: bool,
path: Option<PathBuf>,
},
Update {},
}
fn main() {
let cli = Cli::parse();
if cli.debug {
std::env::set_var("RUST_LOG", "DEBUG");
}
let subscriber = FmtSubscriber::builder()
.without_time()
.with_env_filter(EnvFilter::from_default_env())
.finish();
tracing::subscriber::set_global_default(subscriber).expect("Unable to init tracing");
debug!("Config: {:#?}", *config::CONFIG);
let res = match cli.command {
Commands::Update { yes } => core::update(yes, cli.no_cache),
Commands::List { global, all } => core::list(global, all),
Commands::Install {
file, yes, force, ..
} if file.is_some() => {
let Some(f) = file else {
return
};
core::import(f, yes, force, cli.no_cache)
}
Commands::Install {
mod_names,
yes,
force,
..
} => core::install(mod_names, yes, force, cli.no_cache),
Commands::Disable { mods, all, force } => {
core::disable(mods.into_iter().collect(), all, force)
}
Commands::Enable { mods, all } => core::enable(mods.into_iter().collect(), all),
Commands::Search { term } => core::search(&term),
Commands::Remove { mod_names } => core::remove(mod_names),
Commands::Import { file, yes, force } => core::import(file, yes, force, cli.no_cache),
Commands::Export { file } => core::export(file),
Commands::Env {} => core::env(),
#[cfg(feature = "northstar")]
Commands::Northstar { command } => core::northstar(&command),
};
if let Err(e) = res {
if cli.debug {
debug!("{:#?}", e);
}
}
}