mirror of
				https://github.com/Dummi26/rembackup.git
				synced 2025-11-04 12:51:26 +01:00 
			
		
		
		
	Make --ignore a b c work with directories and files
This commit is contained in:
		
							parent
							
								
									e8e5b363ff
								
							
						
					
					
						commit
						7595d2482c
					
				@ -17,7 +17,7 @@ pub struct Args {
 | 
				
			|||||||
    /// directories to ignore.
 | 
					    /// directories to ignore.
 | 
				
			||||||
    /// can be paths relative to <source> (like backups/) or paths starting with <source> (like my_source/backups/).
 | 
					    /// can be paths relative to <source> (like backups/) or paths starting with <source> (like my_source/backups/).
 | 
				
			||||||
    /// if <index> starts with <source>, it is automatically ignored and doesn't need to be specified.
 | 
					    /// if <index> starts with <source>, it is automatically ignored and doesn't need to be specified.
 | 
				
			||||||
    #[arg(long)]
 | 
					    #[arg(long, num_args(0..))]
 | 
				
			||||||
    pub ignore: Vec<PathBuf>,
 | 
					    pub ignore: Vec<PathBuf>,
 | 
				
			||||||
    /// don't ask for confirmation, just apply the changes.
 | 
					    /// don't ask for confirmation, just apply the changes.
 | 
				
			||||||
    #[arg(long)]
 | 
					    #[arg(long)]
 | 
				
			||||||
 | 
				
			|||||||
@ -5,19 +5,19 @@ use crate::{indexchanges::IndexChange, indexfile::IndexFile};
 | 
				
			|||||||
pub fn perform_index_diff<'a>(
 | 
					pub fn perform_index_diff<'a>(
 | 
				
			||||||
    source: &Path,
 | 
					    source: &Path,
 | 
				
			||||||
    index: &'a Path,
 | 
					    index: &'a Path,
 | 
				
			||||||
    mut ignore_subdirs: Vec<&'a Path>,
 | 
					    mut ignore_paths: Vec<&'a Path>,
 | 
				
			||||||
) -> io::Result<Vec<IndexChange>> {
 | 
					) -> io::Result<Vec<IndexChange>> {
 | 
				
			||||||
    let mut changes = Vec::new();
 | 
					    let mut changes = Vec::new();
 | 
				
			||||||
    if let Ok(inner_index) = index.strip_prefix(source) {
 | 
					    if let Ok(inner_index) = index.strip_prefix(source) {
 | 
				
			||||||
        eprintln!("[info] source contains index, but index will not be part of the backup.");
 | 
					        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(
 | 
					    rec(
 | 
				
			||||||
        source.as_ref(),
 | 
					        source.as_ref(),
 | 
				
			||||||
        Path::new(""),
 | 
					        Path::new(""),
 | 
				
			||||||
        index,
 | 
					        index,
 | 
				
			||||||
        &mut changes,
 | 
					        &mut changes,
 | 
				
			||||||
        &ignore_subdirs,
 | 
					        &ignore_paths,
 | 
				
			||||||
    )?;
 | 
					    )?;
 | 
				
			||||||
    Ok(changes)
 | 
					    Ok(changes)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -30,15 +30,8 @@ fn rec(
 | 
				
			|||||||
    index_files: &Path,
 | 
					    index_files: &Path,
 | 
				
			||||||
    // list of changes to be made
 | 
					    // list of changes to be made
 | 
				
			||||||
    changes: &mut Vec<IndexChange>,
 | 
					    changes: &mut Vec<IndexChange>,
 | 
				
			||||||
    // if the index is part of `source`, where exactly is it?
 | 
					    ignore_paths: &Vec<&Path>,
 | 
				
			||||||
    ignore_subdirs: &Vec<&Path>,
 | 
					 | 
				
			||||||
) -> Result<(), io::Error> {
 | 
					) -> Result<(), io::Error> {
 | 
				
			||||||
    for ii in ignore_subdirs {
 | 
					 | 
				
			||||||
        if rel_path.starts_with(ii) {
 | 
					 | 
				
			||||||
            return Ok(());
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // used to find removals
 | 
					    // used to find removals
 | 
				
			||||||
    let index_rel_path = index_files.join(rel_path);
 | 
					    let index_rel_path = index_files.join(rel_path);
 | 
				
			||||||
    let mut index_entries = match fs::read_dir(&index_rel_path) {
 | 
					    let mut index_entries = match fs::read_dir(&index_rel_path) {
 | 
				
			||||||
@ -57,33 +50,30 @@ fn rec(
 | 
				
			|||||||
    // find changes/adds
 | 
					    // find changes/adds
 | 
				
			||||||
    for entry in source_files {
 | 
					    for entry in source_files {
 | 
				
			||||||
        let entry = entry?;
 | 
					        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 metadata = entry.metadata()?;
 | 
				
			||||||
        let in_index_and_is_dir = index_entries.remove(&entry.file_name());
 | 
					        let in_index_and_is_dir = index_entries.remove(&entry.file_name());
 | 
				
			||||||
        if metadata.is_dir() {
 | 
					        if metadata.is_dir() {
 | 
				
			||||||
            if let Some(false) = in_index_and_is_dir {
 | 
					            if let Some(false) = in_index_and_is_dir {
 | 
				
			||||||
                // is dir, but was file -> remove file
 | 
					                // 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(
 | 
					            rec(source, &rel_path, index_files, changes, ignore_paths)?;
 | 
				
			||||||
                source,
 | 
					 | 
				
			||||||
                &rel_path.join(entry.file_name()),
 | 
					 | 
				
			||||||
                index_files,
 | 
					 | 
				
			||||||
                changes,
 | 
					 | 
				
			||||||
                ignore_subdirs,
 | 
					 | 
				
			||||||
            )?;
 | 
					 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            if let Some(true) = in_index_and_is_dir {
 | 
					            if let Some(true) = in_index_and_is_dir {
 | 
				
			||||||
                // is file, but was dir -> remove 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 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 {
 | 
					            match oldif {
 | 
				
			||||||
                Ok(Ok(oldif)) if oldif == newif => {}
 | 
					                Ok(Ok(oldif)) if oldif == newif => {}
 | 
				
			||||||
                _ => changes.push(IndexChange::AddFile(
 | 
					                _ => changes.push(IndexChange::AddFile(rel_path, newif)),
 | 
				
			||||||
                    rel_path.join(entry.file_name()),
 | 
					 | 
				
			||||||
                    newif,
 | 
					 | 
				
			||||||
                )),
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user