@@ -234,14 +234,20 @@ func copyDirRecursiveWithPrefix(srcDir, dstDir, globalBase, prefix string, exclu
234
234
235
235
// getMatchesForPattern returns files/directories matching a pattern relative to sourceDir.
236
236
// If no matches are found, it logs a debug message and returns an empty slice.
237
- // When the pattern ends with "/*", it retries with a recursive "/**" variant.
237
+ // For patterns ending with "/*" (shallow copy indicator) the function does not fallback to a recursive variant.
238
238
func getMatchesForPattern (sourceDir , pattern string ) ([]string , error ) {
239
239
fullPattern := filepath .Join (sourceDir , pattern )
240
240
matches , err := u .GetGlobMatches (fullPattern )
241
241
if err != nil {
242
242
return nil , fmt .Errorf ("error getting glob matches for %q: %w" , fullPattern , err )
243
243
}
244
244
if len (matches ) == 0 {
245
+ // If the pattern ends with "/*" (and not "/**"), do not fallback.
246
+ if strings .HasSuffix (pattern , "/*" ) && ! strings .HasSuffix (pattern , "/**" ) {
247
+ l .Debug ("No matches found for shallow pattern; target directory will be empty" , "pattern" , fullPattern )
248
+ return []string {}, nil
249
+ }
250
+ // Fallback for patterns ending with "/*" (non-shallow) or others.
245
251
if strings .HasSuffix (pattern , "/*" ) {
246
252
recursivePattern := strings .TrimSuffix (pattern , "/*" ) + "/**"
247
253
fullRecursivePattern := filepath .Join (sourceDir , recursivePattern )
@@ -287,25 +293,25 @@ func copyToTargetWithPatterns(
287
293
return cp .Copy (sourceDir , targetPath )
288
294
}
289
295
290
- // If inclusion patterns are provided, use them to determine which files to copy .
291
- if len ( s .IncludedPaths ) > 0 {
292
- filesToCopy := make ( map [ string ] struct {})
293
- for _ , pattern := range s . IncludedPaths {
294
- matches , err := getMatchesForPattern ( sourceDir , pattern )
295
- if err != nil {
296
- l . Debug ( "Warning: error getting matches for pattern" , "pattern" , pattern , "error" , err )
297
- continue
298
- }
299
- for _ , match := range matches {
300
- filesToCopy [ match ] = struct {}{}
301
- }
296
+ // If inclusion patterns are provided, process each pattern individually .
297
+ for _ , pattern := range s .IncludedPaths {
298
+ // Determine if the pattern indicates shallow copy.
299
+ shallow := false
300
+ if strings . HasSuffix ( pattern , "/*" ) && ! strings . HasSuffix ( pattern , "/**" ) {
301
+ shallow = true
302
+ }
303
+
304
+ matches , err := getMatchesForPattern ( sourceDir , pattern )
305
+ if err != nil {
306
+ l . Debug ( "Warning: error getting matches for pattern" , "pattern" , pattern , "error" , err )
307
+ continue
302
308
}
303
- if len (filesToCopy ) == 0 {
304
- l .Debug ("No files matched the inclusion patterns - target directory will be empty" )
305
- return nil
309
+ if len (matches ) == 0 {
310
+ l .Debug ("No files matched the inclusion pattern" , "pattern" , pattern )
311
+ continue
306
312
}
307
- for file := range filesToCopy {
308
- // Retrieve file information early so that we can adjust exclusion checks if this is a directory .
313
+ for _ , file := range matches {
314
+ // Retrieve file information.
309
315
info , err := os .Stat (file )
310
316
if err != nil {
311
317
return fmt .Errorf ("stating file %q: %w" , file , err )
@@ -315,8 +321,9 @@ func copyToTargetWithPatterns(
315
321
return fmt .Errorf ("computing relative path for %q: %w" , file , err )
316
322
}
317
323
relPath = filepath .ToSlash (relPath )
324
+
325
+ // Check exclusion patterns (for directories, try both plain and trailing slash).
318
326
skip := false
319
- // For directories, check both the plain relative path and with a trailing slash.
320
327
for _ , ex := range s .ExcludedPaths {
321
328
if info .IsDir () {
322
329
matched , err := u .PathMatch (ex , relPath )
@@ -327,7 +334,6 @@ func copyToTargetWithPatterns(
327
334
skip = true
328
335
break
329
336
}
330
- // Also try matching with a trailing slash.
331
337
matched , err = u .PathMatch (ex , relPath + "/" )
332
338
if err != nil {
333
339
l .Debug ("Error matching exclusion pattern with trailing slash" , "pattern" , ex , "path" , relPath + "/" , "error" , err )
@@ -337,7 +343,6 @@ func copyToTargetWithPatterns(
337
343
break
338
344
}
339
345
} else {
340
- // For files, just check the plain relative path.
341
346
matched , err := u .PathMatch (ex , relPath )
342
347
if err != nil {
343
348
l .Debug ("Error matching exclusion pattern" , "pattern" , ex , "path" , relPath , "error" , err )
@@ -355,19 +360,26 @@ func copyToTargetWithPatterns(
355
360
// Build the destination path.
356
361
dstPath := filepath .Join (targetPath , relPath )
357
362
if info .IsDir () {
358
- // Instead of resetting the base for relative paths,
359
- // use the new recursive function that preserves the global relative path.
360
- if err := copyDirRecursiveWithPrefix (file , dstPath , sourceDir , relPath , s .ExcludedPaths ); err != nil {
361
- return err
363
+ if shallow {
364
+ // Use shallow copy: copy only immediate file entries.
365
+ l .Debug ("Directory is not copied becasue it is a shallow copy" , "directory" , relPath )
366
+ } else {
367
+ // Use the existing recursive copy with prefix.
368
+ if err := copyDirRecursiveWithPrefix (file , dstPath , sourceDir , relPath , s .ExcludedPaths ); err != nil {
369
+ return err
370
+ }
362
371
}
363
372
} else {
364
373
if err := copyFile (file , dstPath ); err != nil {
365
374
return err
366
375
}
367
376
}
368
377
}
369
- } else {
370
- // No inclusion patterns defined; copy everything except those matching excluded items.
378
+ }
379
+
380
+ // If no inclusion patterns are defined; copy everything except those matching excluded items.
381
+ // (This branch is preserved from the original logic.)
382
+ if len (s .IncludedPaths ) == 0 {
371
383
if err := copyDirRecursive (sourceDir , targetPath , sourceDir , s .ExcludedPaths , s .IncludedPaths ); err != nil {
372
384
return fmt .Errorf ("error copying from %q to %q: %w" , sourceDir , targetPath , err )
373
385
}
0 commit comments