diff --git a/README.md b/README.md index 1809166..2b0c3c4 100644 --- a/README.md +++ b/README.md @@ -23,8 +23,8 @@ to manage backups on several storages mounted on multiple devices with a single - [x] update storage bind command - [ ] add storage remove command - [ ] add sync subcommand -- [ ] add check subcommand - - [ ] check that all parents exist +- [x] add check subcommand + - [x] check that all parents exist - [x] reorganize cmd option for storage - [x] use subcommand - [ ] backup subcommands diff --git a/src/cmd_args.rs b/src/cmd_args.rs index 0fe2eda..0db0217 100644 --- a/src/cmd_args.rs +++ b/src/cmd_args.rs @@ -53,7 +53,7 @@ pub(crate) enum Commands { remote_name: Option, }, - /// Check config files. + /// Check config files validity. Check {}, /// Generate completion script. diff --git a/src/cmd_check.rs b/src/cmd_check.rs new file mode 100644 index 0000000..0ae7b96 --- /dev/null +++ b/src/cmd_check.rs @@ -0,0 +1,60 @@ +use std::path::PathBuf; + +use anyhow::{anyhow, Context, Result}; + +use crate::{ + backups::Backups, + devices, + storages::{Storage, StorageExt, Storages}, +}; + +pub(crate) fn cmd_check(config_dir: &PathBuf) -> Result<()> { + info!("Config dir: {}", &config_dir.display()); + + let device = devices::get_device(&config_dir)?; + info!("Current device: {:?}", device); + + let devices = devices::get_devices(&config_dir)?; + info!("Configured devices: {:?}", devices); + + let storages = Storages::read(&config_dir)?; + info!("Storages: {:?}", storages); + if !(storages.list.iter().all(|(_name, storage)| match storage { + Storage::SubDirectory(storage) => storage.parent(&storages).is_some(), + _ => true, + })) { + return Err(anyhow!( + "Some SubDirectory doesn't have its parent in the storages list." + )); + }; + info!("All SubDirectory's parent exists."); + + for device in &devices { + let backups = Backups::read(&config_dir, &device)?; + for (name, backup) in &backups.list { + if name != backup.name() { + return Err(anyhow!( + "The backup {} name and its key is different.", + name + )); + } + let _device = backup + .device(&devices) + .context(format!("The backup {}'s device doesn't exist.", name))?; + if !(storages.list.contains_key(&backup.source().storage)) { + return Err(anyhow!( + "The source of backup {} doesn't exist in storages.", + &backup.name() + )); + } + if !(storages.list.contains_key(&backup.destination().storage)) { + return Err(anyhow!( + "The destination of backup {} doesn't exist in storages.", + &backup.name() + )); + } + } + } + println!("All check passed"); + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index d14a081..4c6ff47 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,10 +28,11 @@ use devices::{Device, DEVICESFILE, *}; mod backups; mod cmd_args; mod cmd_backup; +mod cmd_check; +mod cmd_completion; mod cmd_init; mod cmd_storage; mod cmd_sync; -mod cmd_completion; mod devices; mod inquire_filepath_completer; mod storages; @@ -90,11 +91,7 @@ fn main() -> Result<()> { println!("{}", &config_dir.display()); } Commands::Sync { remote_name } => cmd_sync::cmd_sync(&config_dir, remote_name)?, - Commands::Check {} => { - println!("Config dir: {}", &config_dir.display()); - let _storages = Storages::read(&config_dir)?; - todo!() - } + Commands::Check {} => cmd_check::cmd_check(&config_dir)?, Commands::Backup(backup) => { trace!("backup subcommand with args: {:?}", backup); let repo = Repository::open(&config_dir).context( @@ -123,9 +120,7 @@ fn main() -> Result<()> { } => cmd_backup::cmd_backup_done(name, exit_status, log, repo, &config_dir)?, } } - Commands::Completion { shell } => { - cmd_completion::cmd_completion(shell)? - } + Commands::Completion { shell } => cmd_completion::cmd_completion(shell)?, } full_status(&Repository::open(&config_dir)?)?; Ok(())