#[macro_use]
extern crate clap;
#[macro_use]
extern crate strum_macros;
mod catch;
mod config;
mod git;
mod init;
mod install;
mod package;
mod repo;
use anyhow::Result;
use clap::{App, AppSettings, Arg, SubCommand};
use colored::*;
use log::{error, info};
use simplelog::{LevelFilter, TermLogger, TerminalMode};
use config::Config;
use repo::Repo;
fn public_clap_app<'a, 'b>() -> App<'a, 'b> {
App::new("emplace")
.version(crate_version!())
.author(crate_authors!())
.after_help("https://github.com/tversteeg/emplace")
.setting(AppSettings::SubcommandRequiredElseHelp)
.subcommand(
SubCommand::with_name("install")
.about("Install the packages that have been mirrored from other machines"),
)
.subcommand(SubCommand::with_name("clean").about("Remove package synching"))
}
fn main() -> Result<()> {
TermLogger::init(
LevelFilter::Info,
simplelog::Config::default(),
TerminalMode::Mixed,
)
.expect("No interactive terminal");
let matches = public_clap_app()
.subcommand(
SubCommand::with_name("init")
.about("Prints the shell function used to execute emplace")
.arg(
Arg::with_name("shell")
.value_name("SHELL")
.help(
"The name of the currently running shell\nCurrently supported options: bash & zsh",
)
.required(true)
)
)
.subcommand(
SubCommand::with_name("catch")
.about("Capture a command entired in a terminal")
.arg(
Arg::with_name("line")
.value_name("LINE")
.help("The command as entired in the terminal")
.required(true),
),
)
.get_matches();
match matches.subcommand() {
("init", Some(sub_m)) => {
let shell_name = sub_m.value_of("shell").expect("Shell name is missing.");
init::init_main(shell_name).expect("Could not initialize terminal script");
}
("catch", Some(sub_m)) => {
let line = sub_m.value_of("line").expect("Line is missing");
let mut catches = catch::catch(line).expect("Could not parse line");
if catches.0.is_empty() {
return Ok(());
}
let config = match Config::from_default_file().expect("Retrieving config went wrong") {
Some(config) => config,
None => Config::new().expect("Initializing new config failed"),
};
let repo = Repo::new(config).expect("Could not initialize git repository");
catches.filter_saved_packages(
&repo
.read()
.expect("Could not read packages file from repository"),
);
let len = catches.0.len();
if len == 0 {
return Ok(());
}
match len {
1 => info!("{}", "Mirror this command?".green().bold()),
n => info!("{}", format!("Mirror these {} commands?", n).green().bold()),
}
for catch in catches.0.iter() {
info!("- {}", catch.colour_full_name());
}
if !dialoguer::Confirmation::new()
.interact()
.expect("Could not create dialogue")
{
return Ok(());
}
repo.mirror(catches).expect("Could not mirror commands");
}
("install", Some(_)) => {
let config = match Config::from_default_file().expect("Retrieving config went wrong") {
Some(config) => config,
None => Config::new().expect("Initializing new config failed"),
};
let repo = Repo::new(config).expect("Could not initialize git repository");
match repo.read() {
Ok(packages) => {
if let Err(err) = crate::install::install(packages) {
error!("Could not install new changes: {}.", err);
}
}
Err(err) => error!("{}", err),
};
}
("clean", Some(_)) => {
let config = match Config::from_default_file().expect("Retrieving config went wrong") {
Some(config) => config,
None => Config::new().expect("Initializing new config failed"),
};
let repo = Repo::new(config).expect("Could not initialize git repository");
match repo.read() {
Ok(packages) => match crate::install::clean(packages) {
Ok(packages) => repo.clean(packages).expect("Could not clean repo."),
Err(err) => error!("Could not remove from repository: {}.", err),
},
Err(err) => error!("{}", err),
};
}
(&_, _) => {}
};
Ok(())
}