@@ -48,6 +48,48 @@ parse_pattern_file() {
4848 grep -v ' ^#' " $file_path " 2> /dev/null | grep -v ' ^[[:space:]]*$' || true
4949}
5050
51+ # Copy a single file to destination, handling exclusion, path preservation, and dry-run
52+ # Usage: _copy_pattern_file file dst_root excludes preserve_paths dry_run
53+ # Returns: 0 if file was copied (or would be in dry-run), 1 if skipped/failed
54+ _copy_pattern_file () {
55+ local file=" $1 "
56+ local dst_root=" $2 "
57+ local excludes=" $3 "
58+ local preserve_paths=" $4 "
59+ local dry_run=" $5 "
60+
61+ # Remove leading ./
62+ file=" ${file# ./ } "
63+
64+ # Skip if excluded
65+ is_excluded " $file " " $excludes " && return 1
66+
67+ # Determine destination path
68+ local dest_file
69+ if [ " $preserve_paths " = " true" ]; then
70+ dest_file=" $dst_root /$file "
71+ else
72+ dest_file=" $dst_root /$( basename " $file " ) "
73+ fi
74+
75+ # Copy the file (or show what would be copied in dry-run mode)
76+ if [ " $dry_run " = " true" ]; then
77+ log_info " [dry-run] Would copy: $file "
78+ return 0
79+ fi
80+
81+ local dest_dir
82+ dest_dir=$( dirname " $dest_file " )
83+ mkdir -p " $dest_dir "
84+ if cp " $file " " $dest_file " 2> /dev/null; then
85+ log_info " Copied $file "
86+ return 0
87+ else
88+ log_warn " Failed to copy $file "
89+ return 1
90+ fi
91+ }
92+
5193# Copy files matching patterns from source to destination
5294# Usage: copy_patterns src_root dst_root includes excludes [preserve_paths] [dry_run]
5395# includes: newline-separated glob patterns to include
@@ -102,36 +144,8 @@ copy_patterns() {
102144 if [ " $have_globstar " -eq 0 ] && echo " $pattern " | grep -q ' \*\*' ; then
103145 # Fallback to find for ** patterns on Bash 3.2
104146 while IFS= read -r file; do
105- # Remove leading ./
106- file=" ${file# ./ } "
107-
108- # Skip if excluded
109- is_excluded " $file " " $excludes " && continue
110-
111- # Determine destination path
112- local dest_file
113- if [ " $preserve_paths " = " true" ]; then
114- dest_file=" $dst_root /$file "
115- else
116- dest_file=" $dst_root /$( basename " $file " ) "
117- fi
118-
119- # Create destination directory (skip in dry-run mode)
120- local dest_dir
121- dest_dir=$( dirname " $dest_file " )
122-
123- # Copy the file (or show what would be copied in dry-run mode)
124- if [ " $dry_run " = " true" ]; then
125- log_info " [dry-run] Would copy: $file "
147+ if _copy_pattern_file " $file " " $dst_root " " $excludes " " $preserve_paths " " $dry_run " ; then
126148 copied_count=$(( copied_count + 1 ))
127- else
128- mkdir -p " $dest_dir "
129- if cp " $file " " $dest_file " 2> /dev/null; then
130- log_info " Copied $file "
131- copied_count=$(( copied_count + 1 ))
132- else
133- log_warn " Failed to copy $file "
134- fi
135149 fi
136150 done << EOF
137151$( find . -path " ./$pattern " -type f 2> /dev/null)
142156 # Skip if not a file
143157 [ -f " $file " ] || continue
144158
145- # Remove leading ./
146- file=" ${file# ./ } "
147-
148- # Skip if excluded
149- is_excluded " $file " " $excludes " && continue
150-
151- # Determine destination path
152- local dest_file
153- if [ " $preserve_paths " = " true" ]; then
154- dest_file=" $dst_root /$file "
155- else
156- dest_file=" $dst_root /$( basename " $file " ) "
157- fi
158-
159- # Create destination directory (skip in dry-run mode)
160- local dest_dir
161- dest_dir=$( dirname " $dest_file " )
162-
163- # Copy the file (or show what would be copied in dry-run mode)
164- if [ " $dry_run " = " true" ]; then
165- log_info " [dry-run] Would copy: $file "
159+ if _copy_pattern_file " $file " " $dst_root " " $excludes " " $preserve_paths " " $dry_run " ; then
166160 copied_count=$(( copied_count + 1 ))
167- else
168- mkdir -p " $dest_dir "
169- if cp " $file " " $dest_file " 2> /dev/null; then
170- log_info " Copied $file "
171- copied_count=$(( copied_count + 1 ))
172- else
173- log_warn " Failed to copy $file "
174- fi
175161 fi
176162 done
177163 fi
0 commit comments