UNPKG

@boost/config

Version:

Powerful convention based finder, loader, and manager of both configuration and ignore files.

72 lines (61 loc) 1.9 kB
import fs from 'node:fs'; import { Path } from '@boost/common'; import type { Blueprint, Schemas } from '@boost/common/optimal'; import { color } from '@boost/internal'; import { Finder } from './Finder'; import type { IgnoreFile, IgnoreFinderOptions } from './types'; export class IgnoreFinder extends Finder<IgnoreFile, IgnoreFinderOptions> { blueprint(schemas: Schemas): Blueprint<IgnoreFinderOptions> { const { bool, string } = schemas; return { errorIfNoRootFound: bool(true), name: string().required().camelCase(), }; } /** * Find a single ignore file in the provided directory. */ // eslint-disable-next-line @typescript-eslint/require-await async findFilesInDir(dir: Path): Promise<Path[]> { const files: Path[] = []; const path = dir.append(this.getFileName()); if (path.exists()) { files.push(path); } this.debug.invariant( files.length > 0, `Finding ignore files in ${color.filePath(dir.path())}`, files.map((file) => file.name()).join(', '), 'No files', ); return files; } /** * Return an ignore specific file. */ getFileName(): string { return `.${this.options.name.toLowerCase()}ignore`; } /** * Load and parse a list of found files into a list of ignore patterns. */ async resolveFiles(basePath: Path, foundFiles: Path[]): Promise<IgnoreFile[]> { this.debug('Resolving %d ignore files', foundFiles.length); return Promise.all( foundFiles.map(async (filePath) => { const contents = await this.cache.cacheFileContents(filePath, () => fs.promises.readFile(filePath.path(), 'utf8'), ); const ignore = contents .split('\n') .map((line) => line.trim()) .filter((line) => line !== '' && !line.startsWith('#')); return { ignore, path: filePath, source: this.isRootDir(filePath.parent()) ? ('root' as const) : ('branch' as const), }; }), ); } }