@yeoman/conflicter
Version:
Conflict resolution for yeoman's generator/environment stack
73 lines • 2.8 kB
JavaScript
import { readFile, stat } from 'node:fs/promises';
import { dirname, resolve } from 'node:path';
import { Minimatch } from 'minimatch';
import slash from 'slash';
import { transformFileField } from '@yeoman/transform';
import { isFilePending } from 'mem-fs-editor/state';
const eachFolder = function* (folder) {
let last;
do {
yield folder;
last = folder;
folder = dirname(folder);
} while (folder !== last);
};
export class YoResolve {
groupedYoResolve = new Map();
yoResolveFileName;
constructor(options) {
this.yoResolveFileName = options?.yoResolveFileName ?? '.yo-resolve';
}
async getStatusForFile(filePath) {
for (const folder of eachFolder(slash(filePath))) {
const map = await this.getMapForFolder(folder);
if (map) {
for (const [pattern, value] of map) {
if (pattern.match(filePath)) {
return value;
}
}
}
}
return undefined;
}
createTransform() {
return transformFileField('conflicter', async (status, file) => status ?? this.getStatusForFile(file.path), { filter: isFilePending });
}
async getMapForFolder(folder) {
const map = this.groupedYoResolve.get(folder);
if (map || map === null) {
return map ?? undefined;
}
try {
const yoResolveFile = resolve(folder, this.yoResolveFileName);
const fileStat = await stat(yoResolveFile);
if (fileStat.isFile()) {
const contents = await readFile(yoResolveFile);
const map = new Map();
this.groupedYoResolve.set(folder, map);
if (contents) {
const parsed = contents
.toString()
.split(/\r?\n/)
.map(override => override.trim())
.map(override => override.split('#')[0].trim())
.filter(Boolean)
.map(override => override.split(/[\s+=]/));
for (const [pattern, status = 'skip'] of parsed) {
const negate = pattern.startsWith('!');
const minimatchPattern = `${negate ? '!' : ''}${folder}/${negate ? pattern.slice(1) : pattern}`;
map.set(new Minimatch(minimatchPattern), status);
}
}
return map;
}
}
catch {
// Ignore errors
}
return undefined;
}
}
export const createYoResolveTransform = (...arguments_) => new YoResolve(...arguments_).createTransform();
//# sourceMappingURL=yo-resolve.js.map