|
1 | | -import { createReadStream, createWriteStream, existsSync, globSync, mkdirSync, statSync } from 'node:fs'; |
| 1 | +import { createReadStream, createWriteStream, existsSync, globSync, mkdirSync, type PathLike, statSync } from 'node:fs'; |
2 | 2 | import { basename, dirname, extname, join, normalize, posix, sep } from 'node:path'; |
3 | 3 | import untildify from 'untildify'; |
4 | 4 | import type { CopyFileOptions } from './interfaces.js'; |
@@ -115,6 +115,17 @@ export function filterDotFiles(paths: string[], dot: boolean): string[] { |
115 | 115 | }); |
116 | 116 | } |
117 | 117 |
|
| 118 | +function tryCreatingDir(path: PathLike, defaultReturn: any) { |
| 119 | + try { |
| 120 | + if (statSync(path).isDirectory()) { |
| 121 | + return `${path}/**`; |
| 122 | + } |
| 123 | + } catch { |
| 124 | + // fall through |
| 125 | + } |
| 126 | + return defaultReturn; |
| 127 | +} |
| 128 | + |
118 | 129 | /** |
119 | 130 | * Copy the files per a glob pattern, the first item(s) can be a 1 or more files to copy |
120 | 131 | * while the last item in the array is the output outDirectory directory |
@@ -177,25 +188,22 @@ export function copyfiles(sources: string | string[], outPath: string, options: |
177 | 188 | // Use a Set for deduplication from the start |
178 | 189 | const allFilesSet = new Set<string>(); |
179 | 190 | for (const pattern of sources) { |
180 | | - let files = globSync(pattern, { exclude: excludeGlobs }); |
| 191 | + let adjustedPattern = tryCreatingDir(pattern, pattern); |
| 192 | + // fs.globSync treats /** differently, so adjust to /**/* |
| 193 | + adjustedPattern = adjustedPattern.replace(/\*\*$/, '**/*'); |
| 194 | + let files = globSync(adjustedPattern, { exclude: excludeGlobs }); |
181 | 195 | // If options.all is set and pattern does not start with a dot, also search for dot-prefixed files |
182 | 196 | if (options.all && pattern.includes('*') && !pattern.startsWith('.')) { |
183 | 197 | // e.g. '*.txt' => '.*.txt', '**/*.txt' => '**/.*.txt' |
184 | | - const dotPattern = pattern.replace(/(\*\.[^/]+$|\*$)/, '.$1'); |
| 198 | + const dotPattern = pattern.replace(/(\*\.[^/]+$|\*$)/, '.$1').replace(/\*\*$/, '**/*'); |
185 | 199 | if (dotPattern !== pattern) { |
186 | 200 | files = files.concat(globSync(dotPattern, { exclude: excludeGlobs })); |
187 | 201 | } |
188 | 202 | } |
189 | 203 | // Normalize all file paths to POSIX style (forward slashes) |
190 | 204 | files = files.map(f => f.replaceAll('\\', '/')); |
191 | 205 | // Remove directories manually (since nodir is not supported) |
192 | | - files = files.filter(f => { |
193 | | - try { |
194 | | - return !statSync(f).isDirectory(); |
195 | | - } /* v8 ignore next */ catch { |
196 | | - return false; |
197 | | - } |
198 | | - }); |
| 206 | + files = files.filter(f => !tryCreatingDir(f, false)); |
199 | 207 | // Add to Set for deduplication |
200 | 208 | for (const f of files) { |
201 | 209 | allFilesSet.add(f); |
|
0 commit comments