diff --git a/datman/src/commands/backup.rs b/datman/src/commands/backup.rs index 1d5fbe7..e701445 100644 --- a/datman/src/commands/backup.rs +++ b/datman/src/commands/backup.rs @@ -25,7 +25,7 @@ use anyhow::{anyhow, bail}; use arc_interner::ArcIntern; use chrono::{DateTime, NaiveDateTime, TimeZone, Utc}; use log::{info, warn}; -use std::collections::{BTreeSet, HashMap, HashSet}; +use std::collections::{HashMap, HashSet}; use std::fmt::Debug; use std::io::Write; use std::path::Path; @@ -151,15 +151,18 @@ pub fn backup_source_to_destination( cross_filesystems, } => { info!("Looking to backup {} to {}", source_name, dest_name); + let rules = load_labelling_rules(desc_path, source_name)?; + let exclusions = rules.get_exclusions_set(directory); + info!("Scanning."); - let tree = scan(directory, !*cross_filesystems, &BTreeSet::new())? + let tree = scan(directory, !*cross_filesystems, &exclusions)? .ok_or_else(|| anyhow!("Source does not exist."))?; let absolute_source_path = desc_path.join(directory); let absolute_dest_path = desc_path.join(&dest.path); let pile_descriptor = load_pile_descriptor(&absolute_dest_path)?; let pile = open_pile(&absolute_dest_path, &pile_descriptor)?; - let rules = load_labelling_rules(desc_path, source_name)?; + let root = if let Some(root) = label_filter_and_convert(tree, descriptor, source_name, &rules, dest)? { diff --git a/datman/src/labelling.rs b/datman/src/labelling.rs index 7360ea5..28e4a4b 100644 --- a/datman/src/labelling.rs +++ b/datman/src/labelling.rs @@ -15,10 +15,10 @@ You should have received a copy of the GNU General Public License along with Yama. If not, see . */ -use std::collections::HashMap; +use std::collections::{BTreeSet, HashMap}; use std::fs::File; use std::io::{BufRead, BufReader, Write}; -use std::path::Path; +use std::path::{Path, PathBuf}; use anyhow::anyhow; use anyhow::Context; @@ -222,6 +222,23 @@ impl LabellingRules { } None } + + pub fn get_exclusions_set(&self, base: &Path) -> BTreeSet { + let mut exclusions = BTreeSet::new(); + + for (ext_path, state) in &self.position_based_rules { + assert!(ext_path.is_empty() || ext_path.starts_with('/')); + let full_path = PathBuf::from(format!( + "{}{ext_path}", + base.to_str().expect("base path must always be utf-8") + )); + if state == &Excluded { + exclusions.insert(full_path); + } + } + + exclusions + } } /// Uninteractively label the nodes.