diff --git a/Cargo.lock b/Cargo.lock index 0ef07a1..c613691 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -363,6 +363,7 @@ dependencies = [ "serde_json", "serde_yaml", "termios", + "walkdir", ] [[package]] @@ -481,6 +482,15 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "scratch" version = "1.0.5" @@ -618,6 +628,16 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "walkdir" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "winapi" version = "0.2.8" diff --git a/crates/pacdef_core/Cargo.toml b/crates/pacdef_core/Cargo.toml index 705a92d..d72960d 100644 --- a/crates/pacdef_core/Cargo.toml +++ b/crates/pacdef_core/Cargo.toml @@ -19,6 +19,7 @@ const_format = { version = "0.2", default-features = false } path-absolutize = "3.0" regex = { version = "1.7", default-features = false, features = ["std"] } termios = "0.3" +walkdir = "2.3" serde = "1.0" serde_derive = "1.0" diff --git a/crates/pacdef_core/src/grouping/group.rs b/crates/pacdef_core/src/grouping/group.rs index b1b843f..ecf72d5 100644 --- a/crates/pacdef_core/src/grouping/group.rs +++ b/crates/pacdef_core/src/grouping/group.rs @@ -6,6 +6,9 @@ use std::io::Write; use std::path::{Path, PathBuf}; use anyhow::{Context, Result}; +use walkdir::WalkDir; + +use crate::path::get_relative_path; use super::{Package, Section}; @@ -20,7 +23,7 @@ pub struct Group { } impl Group { - /// Load all group files from the pacdef group dir. + /// Load all group files from the pacdef group dir by recursing through the group dir. /// /// This method will print a warning if /// - there are no files under `group_dir`, or @@ -39,19 +42,25 @@ impl Group { create_dir(group_dir).context("group dir does not exist, creating")?; } - for entry in group_dir.read_dir().context("reading group dir")? { - let file = entry.context("getting group file")?; + for entry in WalkDir::new(group_dir).follow_links(true).min_depth(1) { + let file = entry?; let path = file.path(); + if path.is_dir() { + continue; + } + if warn_not_symlinks && !path.is_symlink() { + // TODO is there an efficient way to make sure *any* of the elements in the path + // is a symlink? eprintln!( "WARNING: group file {} is not a symlink", path.to_string_lossy() ); } - let group = - Self::try_from(&path).with_context(|| format!("reading group file {path:?}"))?; + let group = Self::try_from(path, group_dir) + .with_context(|| format!("reading group file {path:?}"))?; result.insert(group); } @@ -96,17 +105,14 @@ impl Eq for Group { } impl Group { - fn try_from
(p: P) -> Result (path: P, group_dir: P) -> Result (full_path: P, base_path: P) -> PathBuf
+where
+ P: AsRef