Process a `NestedGlob` target: walk `search_root`, match files against `glob_pattern`, skip excluded paths, and create a symlink for each Discovers files in a directory tree matching a glob pattern and creates symlinks to each matched file. # Arguments `search_root` - Directory to walk for file discovery `glob_pattern` - Glob pattern with `**` support (e.g., `**/AGENTS.md`) `excludes` - Optional
(
&self,
search_root: &Path,
glob_pattern: &str,
excludes: &[String],
dest_template: &str,
options: &SyncOptions,
)
| 931 | /// - Uses `find()` instead of `any()` for exclusion checks to enable early-exit |
| 932 | /// - Avoids exclusion iteration when `excludes` list is empty |
| 933 | fn process_nested_glob( |
| 934 | &self, |
| 935 | search_root: &Path, |
| 936 | glob_pattern: &str, |
| 937 | excludes: &[String], |
| 938 | dest_template: &str, |
| 939 | options: &SyncOptions, |
| 940 | ) -> Result<SyncResult> { |
| 941 | let mut result = SyncResult::default(); |
| 942 | |
| 943 | if !search_root.exists() || !search_root.is_dir() { |
| 944 | println!( |
| 945 | " {} Search root does not exist: {}", |
| 946 | "!".yellow(), |
| 947 | search_root.display() |
| 948 | ); |
| 949 | result.skipped += 1; |
| 950 | return Ok(result); |
| 951 | } |
| 952 | |
| 953 | let key = ( |
| 954 | search_root.to_path_buf(), |
| 955 | glob_pattern.to_string(), |
| 956 | excludes.to_vec(), |
| 957 | ); |
| 958 | |
| 959 | let matches = { |
| 960 | let mut cache = self.glob_cache.borrow_mut(); |
| 961 | if let Some(cached) = cache.get(&key) { |
| 962 | Rc::clone(cached) |
| 963 | } else { |
| 964 | let mut found = Vec::new(); |
| 965 | self.for_each_nested_glob_match( |
| 966 | search_root, |
| 967 | glob_pattern, |
| 968 | excludes, |
| 969 | options, |
| 970 | |full_path, rel_path| { |
| 971 | found.push((full_path.to_path_buf(), rel_path.to_path_buf())); |
| 972 | Ok(()) |
| 973 | }, |
| 974 | )?; |
| 975 | let rc_found = Rc::new(found); |
| 976 | cache.insert(key, Rc::clone(&rc_found)); |
| 977 | rc_found |
| 978 | } |
| 979 | }; |
| 980 | |
| 981 | for (full_path, rel_path) in matches.iter() { |
| 982 | let dest_str = Self::expand_destination_template(dest_template, rel_path); |
| 983 | if dest_str.is_empty() { |
| 984 | if options.verbose { |
| 985 | println!( |
| 986 | " {} Destination template produced empty path for: {}", |
| 987 | "!".yellow(), |
| 988 | full_path.display() |
| 989 | ); |
| 990 | } |