1 | #! /usr/bin/env node
|
2 | import fs from 'fs/promises'
|
3 | import path from 'path'
|
4 |
|
5 | async function readGitignore() {
|
6 | try {
|
7 | const gitIgnore = `${await fs.readFile('.gitignore')}`
|
8 | return gitIgnore.split('\n').filter(file => file)
|
9 | } catch (e) {
|
10 | if (e.code !== 'ENOENT') {
|
11 | throw e
|
12 | }
|
13 | return []
|
14 | }
|
15 | }
|
16 |
|
17 | async function scanDirectory(directory, ignoreSet, fileMatcher) {
|
18 | const entries = await fs.readdir(directory, { withFileTypes: true })
|
19 |
|
20 | const filtered = entries
|
21 | .filter(entry => !entry.name.startsWith('.'))
|
22 | .filter(entry => !ignoreSet.has(entry.name))
|
23 |
|
24 | const found = await Promise.all(filtered.map(async entry => {
|
25 | if (entry.isDirectory()) {
|
26 | const directoryPath = path.join(directory, entry.name)
|
27 | return ignoreSet.has(directoryPath) ? [] : scanDirectory(directoryPath, ignoreSet, fileMatcher)
|
28 | }
|
29 | return fileMatcher(entry.name) ? path.join(directory, entry.name) : []
|
30 | }))
|
31 | return found.flat()
|
32 | }
|
33 |
|
34 | export async function findFiles(directory, ignored = new Set(), fileMatcher = () => true) {
|
35 | const gitIgnores = await readGitignore()
|
36 | gitIgnores.forEach(ignore => ignored.add(ignore))
|
37 | return scanDirectory(directory, ignored, fileMatcher)
|
38 | }
|