(cwd: string, pattern: string)
| 540 | } |
| 541 | |
| 542 | function expandGlobPattern(cwd: string, pattern: string): string[] { |
| 543 | const parts = pattern.split('/') |
| 544 | const results: string[] = [] |
| 545 | |
| 546 | function walk(currentPath: string, partIndex: number): void { |
| 547 | if (partIndex >= parts.length) { |
| 548 | if (fs.existsSync(path.join(currentPath, 'package.json'))) { |
| 549 | results.push(currentPath) |
| 550 | } |
| 551 | return |
| 552 | } |
| 553 | |
| 554 | const part = parts[partIndex] |
| 555 | |
| 556 | if (part === '*') { |
| 557 | if (!fs.existsSync(currentPath)) return |
| 558 | try { |
| 559 | for (const entry of fs.readdirSync(currentPath)) { |
| 560 | const fullPath = path.join(currentPath, entry) |
| 561 | if (isDirectory(fullPath)) { |
| 562 | if (partIndex === parts.length - 1) { |
| 563 | if (fs.existsSync(path.join(fullPath, 'package.json'))) { |
| 564 | results.push(fullPath) |
| 565 | } |
| 566 | } else { |
| 567 | walk(fullPath, partIndex + 1) |
| 568 | } |
| 569 | } |
| 570 | } |
| 571 | } catch { |
| 572 | // Permission denied |
| 573 | } |
| 574 | } else if (part === '**') { |
| 575 | walkRecursive(currentPath, results) |
| 576 | } else { |
| 577 | walk(path.join(currentPath, part), partIndex + 1) |
| 578 | } |
| 579 | } |
| 580 | |
| 581 | walk(cwd, 0) |
| 582 | return results |
| 583 | } |
| 584 | |
| 585 | function walkRecursive(dir: string, results: string[]): void { |
| 586 | if (!fs.existsSync(dir)) return |
no test coverage detected