import * as glob from 'fast-glob' import { readFileSync, statSync, writeFileSync } from 'fs' import { relative, resolve } from 'path' export const isSourceCode = (filePath: any): boolean => { return /\.(js|ts)x?$/.test(filePath) } export const isDirectory = (path: string): boolean => { try { const stat = statSync(path) return stat.isDirectory() } catch (error) { return false } } export const toAbsolutePath = (path: string): string => { return path.startsWith('/') ? path : resolve(process.cwd(), path) } export const isFile = (path: string) => { try { return statSync(path).isFile() } catch (e) { return false } } export const getFiles = ( /** file/dir/glob */ paths: string, options: { exclude?: string } = {}, ): string[] => { const extraIgnore = options.exclude ? options.exclude.split(',') : [] let files: string[] = [] paths.split(',').forEach((path) => { const absolutePath = toAbsolutePath(path) if (isFile(absolutePath)) { files.push(absolutePath) } else if (isDirectory(absolutePath)) { const gitIgnoreFile = resolve(absolutePath, '.gitignore') let gitIgnore = [] as string[] if (isFile(gitIgnoreFile)) { gitIgnore = readFile(gitIgnoreFile) .split('\n') .filter(Boolean) .map((rule) => rule.replace(/^\//, './')) } const ignore = gitIgnore.concat(extraIgnore) const filesInDir = glob.sync('**/*.*', { cwd: absolutePath, ignore, onlyFiles: true, absolute: true, }) files.push(...filesInDir) } else { const gitIgnoreFile = resolve(process.cwd(), '.gitignore') let gitIgnore = [] as string[] if (isFile(gitIgnoreFile)) { gitIgnore = readFile(gitIgnoreFile) .split('\n') .filter(Boolean) .map((rule) => rule.replace(/^\//, './')) } const ignore = gitIgnore.concat(extraIgnore) const globFiles = glob.sync(path, { ignore, onlyFiles: true, absolute: true, }) files.push(...globFiles) } }) return dedupe(files) } const dedupe = (texts: string[]) => { let o = Object.create(null) texts.forEach((t) => (o[t] = true)) return Object.keys(o) } export const readFile = (path: string) => { return readFileSync(path, { encoding: 'utf-8', }) } export const writeFile = (path: string, content: string): void => { writeFileSync(path, content, { encoding: 'utf-8', }) } export const toRelative = (absPath: string) => { return relative(process.cwd(), absPath) }