From 0ffe0c345d1c435fec0e1dba352b1b8b62533db7 Mon Sep 17 00:00:00 2001 From: steven-omaha <35634100+steven-omaha@users.noreply.github.com> Date: Thu, 18 May 2023 13:36:26 +0200 Subject: [PATCH] feat(groups): allow nested group dirs Instead of expecting all files to be located immediately under the group dir, we allow them to be nested in additional folders. We walk the group folder, and treat every file as a group file. The relative path of the file as seen from the group dir becomes the group name. Fixes #27. --- Cargo.lock | 20 +++++++ crates/pacdef_core/Cargo.toml | 1 + crates/pacdef_core/src/grouping/group.rs | 69 +++++++++++++++++++----- crates/pacdef_core/src/path.rs | 45 +++++++++++++++- 4 files changed, 122 insertions(+), 13 deletions(-) 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