use std::{fs::OpenOptions, io::BufWriter, process::exit};
use config::BackupConfig;
use storage::{local::LocalStorage, Storage};
use tracing::info;
use tracing_appender::non_blocking::NonBlocking;
use tracing_subscriber::fmt;
mod config;
mod storage;
mod util;
fn main() {
let version: &str = env!("CARGO_PKG_VERSION");
info!("rsbackup version : {}", version);
println!("rsbackup version : {}", version);
let file = OpenOptions::new()
.create(true) .append(true) .open(util::log_file())
.expect("failed to open log file");
let writer = BufWriter::new(file);
let (non_blocking, _guard) = NonBlocking::new(writer);
let subscriber = fmt()
.with_max_level(tracing::metadata::LevelFilter::DEBUG)
.with_writer(non_blocking)
.finish();
tracing::subscriber::set_global_default(subscriber).expect("setting default subscriber failed");
let config = BackupConfig::new().unwrap();
tracing::info!("Backup Check Frequency: {}", config.check_frequency);
let mut errors = Vec::new(); for (index, item) in config.backup_items.iter().enumerate() {
if item.backup_destination.is_empty() || item.backup_directory.is_empty() {
info!(
"Please go to the directory '{}' to modify the backup configuration file settings.",
BackupConfig::config_file().display()
);
eprintln!(
"Please go to the directory '{}' to modify the backup configuration file settings.",
BackupConfig::config_file().display()
);
exit(0)
}
tracing::info!("Backup Item {}", index + 1);
tracing::info!(" Backup Directory: {}", item.backup_directory);
tracing::info!(" Backup Destination: {}", item.backup_destination);
if let Some(exclude) = &item.exclude {
if !exclude.is_empty() {
tracing::info!(" Exclude:");
for ex in exclude {
tracing::info!(" {}", ex);
}
}
}
if item.pre_backup_command.is_some() {
tracing::info!(
" Pre Backup Command: {}",
item.pre_backup_command.as_ref().unwrap()
);
util::run_command(item.pre_backup_command.as_ref().unwrap());
}
let storage = LocalStorage::new(&item.backup_destination);
if let Err(err) = storage.store_file(
&item.backup_directory,
&item.backup_destination,
item.exclude.as_ref().map_or(&[], |vec| vec.as_slice()),
) {
tracing::error!(" Backup error: {}", err);
errors.push(err); }
if item.after_backup_command.is_some() {
tracing::info!(
" After Backup Command: {}",
item.after_backup_command.as_ref().unwrap()
);
util::run_command(item.after_backup_command.as_ref().unwrap());
}
}
println!("task finish!");
info!("task finish!");
if !errors.is_empty() {}
}