diff --git a/src/args.rs b/src/args.rs index 9337126..8e9486e 100755 --- a/src/args.rs +++ b/src/args.rs @@ -17,7 +17,7 @@ pub struct Args { /// 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)] + #[arg(long, num_args(0..))] pub ignore: Vec, /// don't ask for confirmation, just apply the changes. #[arg(long)] diff --git a/src/update_index.rs b/src/update_index.rs index 745a2c2..e399aea 100755 --- a/src/update_index.rs +++ b/src/update_index.rs @@ -5,19 +5,19 @@ use crate::{indexchanges::IndexChange, indexfile::IndexFile}; pub fn perform_index_diff<'a>( source: &Path, index: &'a Path, - mut ignore_subdirs: Vec<&'a Path>, + mut ignore_paths: 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); + ignore_paths.push(inner_index); } rec( source.as_ref(), Path::new(""), index, &mut changes, - &ignore_subdirs, + &ignore_paths, )?; Ok(changes) } @@ -30,15 +30,8 @@ fn rec( index_files: &Path, // list of changes to be made changes: &mut Vec, - // if the index is part of `source`, where exactly is it? - ignore_subdirs: &Vec<&Path>, + ignore_paths: &Vec<&Path>, ) -> Result<(), io::Error> { - for ii in ignore_subdirs { - if rel_path.starts_with(ii) { - return Ok(()); - } - } - // used to find removals let index_rel_path = index_files.join(rel_path); let mut index_entries = match fs::read_dir(&index_rel_path) { @@ -57,33 +50,30 @@ fn rec( // find changes/adds for entry in source_files { let entry = entry?; + let rel_path = rel_path.join(entry.file_name()); + // ignore entries + if ignore_paths.iter().any(|ii| &rel_path == ii) { + continue; + } + let metadata = entry.metadata()?; let in_index_and_is_dir = index_entries.remove(&entry.file_name()); if metadata.is_dir() { if let Some(false) = in_index_and_is_dir { // is dir, but was file -> remove file - changes.push(IndexChange::RemoveFile(rel_path.join(entry.file_name()))); + changes.push(IndexChange::RemoveFile(rel_path.clone())); } - rec( - source, - &rel_path.join(entry.file_name()), - index_files, - changes, - ignore_subdirs, - )?; + rec(source, &rel_path, index_files, changes, ignore_paths)?; } else { if let Some(true) = in_index_and_is_dir { // is file, but was dir -> remove dir - changes.push(IndexChange::RemoveDir(rel_path.join(entry.file_name()))); + changes.push(IndexChange::RemoveDir(rel_path.clone())); } let newif = IndexFile::new_from_metadata(&metadata); - let oldif = IndexFile::from_path(&index_files.join(rel_path).join(entry.file_name())); + let oldif = IndexFile::from_path(&index_files.join(&rel_path)); match oldif { Ok(Ok(oldif)) if oldif == newif => {} - _ => changes.push(IndexChange::AddFile( - rel_path.join(entry.file_name()), - newif, - )), + _ => changes.push(IndexChange::AddFile(rel_path, newif)), } } }