borg-hive 0.0.2

Automated backups using Borg Backup
// borg-hive - Zero-configuration wrapper for borg
// Copyright (C) 2017  Lorenzo Villani
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 3 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

#![recursion_limit = "1024"]

extern crate app_dirs;
extern crate chrono;
extern crate clap;
extern crate keyring;
extern crate rpassword;
extern crate serde_json;
extern crate serde;
extern crate shellexpand;
extern crate slog_async;
extern crate slog_term;

#[macro_use]
extern crate error_chain;

#[macro_use]
extern crate serde_derive;

#[macro_use(slog_o, slog_debug, slog_error, slog_info, slog_log, slog_warn, slog_record,
            slog_record_static, slog_b, slog_kv)]
extern crate slog;

#[macro_use]
extern crate slog_scope;

#[cfg(test)]
extern crate tempdir;

mod borg;
mod cli;
mod config;
mod errors;
mod password;
mod paths;
mod state;
mod utils;

use errors::*;

fn main() {
    std::process::exit(stub());
}

fn stub() -> i32 {
    use slog::Drain;

    // Terminal drain
    let term = slog_term::TermDecorator::new().build();
    let term = slog_term::FullFormat::new(term).build().fuse();
    let term = slog_async::Async::new(term).build().fuse();

    // File drain
    let file = ::std::fs::OpenOptions::new()
        .append(true)
        .create(true)
        .write(true)
        .open(paths::log_file().unwrap())
        .unwrap();
    let file = slog_term::PlainDecorator::new(file);
    let file = slog_term::FullFormat::new(file).build().fuse();
    let file = slog_async::Async::new(file).build().fuse();

    let root = slog::Duplicate::new(term, file).fuse();
    let root = slog::Logger::root(root, slog_o!());

    let _guard = slog_scope::set_global_logger(root);

    if let Err(ref e) = run() {
        error!("{}", e);

        for e in e.iter().skip(1) {
            error!("caused by: {}", e);
        }

        if let Some(backtrace) = e.backtrace() {
            error!("backtrace: {:?}", backtrace);
        }

        return 1;
    }

    return 0;
}

fn run() -> Result<()> {
    let matches = clap::App::new("borg-hive")
        .version(env!("CARGO_PKG_VERSION"))
        .author("Lorenzo Villani <lorenzo@villani.me>")
        .subcommand(clap::SubCommand::with_name("set").subcommand(
            clap::SubCommand::with_name("password"),
        ))
        .get_matches();

    if let Some(matches) = matches.subcommand_matches("set") {
        if matches.subcommand_matches("password").is_some() {
            return cli::ask_and_set_new_password();
        }
    }

    cli::backup()
}