use std::path::PathBuf;
use clap::{Parser, Subcommand};
use log::debug;
use crate::api::model;
use crate::core::config;
use directories::ProjectDirs;
use rustyline::Editor;
mod api;
mod core;
#[derive(Parser)]
#[clap(name = "Papa")]
#[clap(author = "AnAcutalEmerald <emerald_actual@proton.me>")]
#[clap(version = env!("CARGO_PKG_VERSION"))]
#[clap(about = "Command line mod manager for Northstar")]
#[clap(after_help = "Welcome back. Cockpit cooling reactivated.")]
struct Cli {
#[clap(subcommand)]
command: Commands,
#[clap(short, long)]
debug: bool,
}
#[derive(Subcommand)]
enum Commands {
Install {
#[clap(value_name = "MOD")]
#[clap(help = "Mod name(s) to install")]
#[clap(required_unless_present = "url")]
mod_names: Vec<String>,
#[clap(short, long)]
#[clap(value_name = "URL")]
url: Option<String>,
#[clap(short, long)]
yes: bool,
#[clap(short, long)]
force: bool,
},
Remove {
#[clap(value_name = "MOD")]
#[clap(help = "Mod name(s) to remove")]
mod_names: Vec<String>,
},
List {},
Clear {
#[clap(
help = "Force removal of all files in the cahce directory, not just downloaded packages"
)]
#[clap(long, short)]
full: bool,
},
Config {
#[clap(long, short, value_name = "PATH")]
mods_dir: Option<String>,
#[clap(long, short, value_name = "CACHE")]
cache: Option<bool>,
},
Update {
#[clap(short, long)]
yes: bool,
},
Search {
term: Vec<String>,
},
Disable { mods: Vec<String> },
Enable { mods: Vec<String> },
#[cfg(feature = "northstar")]
#[clap(alias("ns"))]
Northstar {
#[clap(subcommand)]
command: NstarCommands,
},
}
#[derive(Subcommand)]
enum NstarCommands {
Init { game_path: Option<PathBuf> },
Update {},
#[cfg(feature = "launcher")]
Start {},
}
#[tokio::main]
async fn main() {
let cli = Cli::parse();
if cli.debug {
std::env::set_var("RUST_LOG", "DEBUG");
}
env_logger::builder().format_timestamp(None).init();
let dirs = ProjectDirs::from("me", "greenboi", "papa").unwrap();
let config = config::load_config(dirs.config_dir()).unwrap();
let rl = Editor::<()>::new();
let mut core = core::Core::new(config, dirs, rl);
let res = match cli.command {
Commands::Update { yes } => core.update(yes).await,
Commands::Config {
mods_dir: None,
cache: None,
} => {
println!(
"Current config:\n{}",
toml::to_string_pretty(&core.config).unwrap()
);
Ok(())
}
Commands::Config { mods_dir, cache } => core.update_config(mods_dir, cache),
Commands::List {} => core.list(),
Commands::Install {
mod_names: _,
url: Some(url),
yes: _,
force: _,
} => core.install_from_url(url).await,
Commands::Install {
mod_names,
url: None,
yes,
force,
} => core.install(mod_names, yes, force).await,
Commands::Disable { mods } => core.disable(mods),
Commands::Enable { mods } => core.enable(mods),
Commands::Search { term } => core.search(term).await,
Commands::Remove { mod_names } => core.remove(mod_names),
Commands::Clear { full } => core.clear(full),
#[cfg(feature = "northstar")]
Commands::Northstar { command } => match command {
NstarCommands::Init { game_path } => {
let game_path = if let Some(p) = game_path {
match p.canonicalize() {
Ok(p) => p,
Err(e) => {
debug!("{:#?}", e);
println!("{}", e);
return;
}
}
} else {
std::env::current_dir().unwrap()
};
core.init_northstar(&game_path).await
}
NstarCommands::Update {} => core.update_northstar().await,
#[cfg(feature = "launcher")]
NstarCommands::Start {} => core.start_northstar(),
},
};
if let Some(e) = res.err() {
if cli.debug {
debug!("{:#?}", e);
} else {
println!("{}", e);
}
}
}