|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import * as fs from 'fs'; |
|
|
import * as path from 'path'; |
|
|
import ignore, { type Ignore } from 'ignore'; |
|
|
import { isGitRepository } from './gitUtils.js'; |
|
|
|
|
|
export interface GitIgnoreFilter { |
|
|
isIgnored(filePath: string): boolean; |
|
|
getPatterns(): string[]; |
|
|
} |
|
|
|
|
|
export class GitIgnoreParser implements GitIgnoreFilter { |
|
|
private projectRoot: string; |
|
|
private ig: Ignore = ignore(); |
|
|
private patterns: string[] = []; |
|
|
|
|
|
constructor(projectRoot: string) { |
|
|
this.projectRoot = path.resolve(projectRoot); |
|
|
} |
|
|
|
|
|
loadGitRepoPatterns(): void { |
|
|
if (!isGitRepository(this.projectRoot)) return; |
|
|
|
|
|
|
|
|
this.addPatterns(['.git']); |
|
|
|
|
|
const patternFiles = ['.gitignore', path.join('.git', 'info', 'exclude')]; |
|
|
for (const pf of patternFiles) { |
|
|
this.loadPatterns(pf); |
|
|
} |
|
|
} |
|
|
|
|
|
loadPatterns(patternsFileName: string): void { |
|
|
const patternsFilePath = path.join(this.projectRoot, patternsFileName); |
|
|
let content: string; |
|
|
try { |
|
|
content = fs.readFileSync(patternsFilePath, 'utf-8'); |
|
|
} catch (_error) { |
|
|
|
|
|
return; |
|
|
} |
|
|
const patterns = (content ?? '') |
|
|
.split('\n') |
|
|
.map((p) => p.trim()) |
|
|
.filter((p) => p !== '' && !p.startsWith('#')); |
|
|
this.addPatterns(patterns); |
|
|
} |
|
|
|
|
|
private addPatterns(patterns: string[]) { |
|
|
this.ig.add(patterns); |
|
|
this.patterns.push(...patterns); |
|
|
} |
|
|
|
|
|
isIgnored(filePath: string): boolean { |
|
|
const relativePath = path.isAbsolute(filePath) |
|
|
? path.relative(this.projectRoot, filePath) |
|
|
: filePath; |
|
|
|
|
|
if (relativePath === '' || relativePath.startsWith('..')) { |
|
|
return false; |
|
|
} |
|
|
|
|
|
let normalizedPath = relativePath.replace(/\\/g, '/'); |
|
|
if (normalizedPath.startsWith('./')) { |
|
|
normalizedPath = normalizedPath.substring(2); |
|
|
} |
|
|
|
|
|
return this.ig.ignores(normalizedPath); |
|
|
} |
|
|
|
|
|
getPatterns(): string[] { |
|
|
return this.patterns; |
|
|
} |
|
|
} |
|
|
|