From e8e5b363fff26e7128a7f4b5b58efbcb6074d2e0 Mon Sep 17 00:00:00 2001 From: Mark Date: Sat, 4 Nov 2023 15:11:20 +0100 Subject: [PATCH] add --ignore --- Cargo.toml | 0 src/args.rs | 8 ++++++++ src/main.rs | 43 +++++++++++++++++++++++++++++++------------ src/update_index.rs | 19 +++++++++++++------ 4 files changed, 52 insertions(+), 18 deletions(-) mode change 100644 => 100755 Cargo.toml diff --git a/Cargo.toml b/Cargo.toml old mode 100644 new mode 100755 diff --git a/src/args.rs b/src/args.rs index a470d9d..9337126 100755 --- a/src/args.rs +++ b/src/args.rs @@ -14,4 +14,12 @@ pub struct Args { /// where your backup will be stored #[arg()] pub target: Option, + /// directories to ignore. + /// can be paths relative to (like backups/) or paths starting with (like my_source/backups/). + /// if starts with , it is automatically ignored and doesn't need to be specified. + #[arg(long)] + pub ignore: Vec, + /// don't ask for confirmation, just apply the changes. + #[arg(long)] + pub noconfirm: bool, } diff --git a/src/main.rs b/src/main.rs index df08826..59123f0 100755 --- a/src/main.rs +++ b/src/main.rs @@ -19,7 +19,14 @@ fn main() { let args = args::Args::parse(); // index diff eprintln!("performing index diff..."); - let changes = match perform_index_diff(&args.source, &args.index) { + let source = &args.source; + let index = &args.index; + let ignore_subdirs = args + .ignore + .iter() + .map(|path| path.strip_prefix(source).unwrap_or(path)) + .collect(); + let changes = match perform_index_diff(source, index, ignore_subdirs) { Ok(c) => c, Err(e) => { eprintln!("Failed to generate index diff:\n {e}"); @@ -44,18 +51,30 @@ fn main() { eprintln!(" + add/update file"); eprintln!(" - remove file"); eprintln!(" [-] remove directory (and all contents!)"); - eprintln!("Press Enter to to apply these actions."); - if args.target.is_none() { - eprintln!("[WARN] You didn't set a `target` directory!\n[WARN] Be careful not to update your index without actually applying the changes to the `target` filesystem!"); - } - // apply changes - if std::io::stdin().read_line(&mut String::new()).is_ok() { - match apply_indexchanges(&args.source, &args.index, &args.target, &changes) { - Ok(()) => {} - Err(e) => { - eprintln!("Failed to apply: {e}"); - exit(30); + // apply changes after confirming + if !args.noconfirm { + let mut line = String::new(); + loop { + if args.target.is_none() { + eprintln!("[WARN] You didn't set a `target` directory!\n[WARN] Be careful not to update your index without actually applying the changes to the `target` filesystem!\nType 'Ok' and press enter to continue."); + } else { + eprintln!("Exclude unwanted directories/files using --ignore,\nor press enter to apply the changes."); } + line.clear(); + std::io::stdin().read_line(&mut line).unwrap(); + let line = line.trim().to_lowercase(); + if line == "exit" { + return; + } else if args.target.is_some() || line == "ok" { + break; + } + } + } + match apply_indexchanges(&args.source, &args.index, &args.target, &changes) { + Ok(()) => {} + Err(e) => { + eprintln!("Failed to apply: {e}"); + exit(30); } } } diff --git a/src/update_index.rs b/src/update_index.rs index 03def2c..745a2c2 100755 --- a/src/update_index.rs +++ b/src/update_index.rs @@ -2,14 +2,22 @@ use std::{collections::HashMap, fs, io, path::Path}; use crate::{indexchanges::IndexChange, indexfile::IndexFile}; -pub fn perform_index_diff(source: &Path, index: &Path) -> io::Result> { +pub fn perform_index_diff<'a>( + source: &Path, + index: &'a Path, + mut ignore_subdirs: Vec<&'a Path>, +) -> io::Result> { let mut changes = Vec::new(); + if let Ok(inner_index) = index.strip_prefix(source) { + eprintln!("[info] source contains index, but index will not be part of the backup."); + ignore_subdirs.push(inner_index); + } rec( source.as_ref(), Path::new(""), index, &mut changes, - index.strip_prefix(source).ok(), + &ignore_subdirs, )?; Ok(changes) } @@ -23,11 +31,10 @@ fn rec( // list of changes to be made changes: &mut Vec, // if the index is part of `source`, where exactly is it? - inner_index: Option<&Path>, + ignore_subdirs: &Vec<&Path>, ) -> Result<(), io::Error> { - if let Some(ii) = &inner_index { + for ii in ignore_subdirs { if rel_path.starts_with(ii) { - eprintln!("[info] source contains index, but index will not be part of the backup."); return Ok(()); } } @@ -62,7 +69,7 @@ fn rec( &rel_path.join(entry.file_name()), index_files, changes, - inner_index, + ignore_subdirs, )?; } else { if let Some(true) = in_index_and_is_dir {