UNPKG

tune-basic-toolset

Version:
41 lines (33 loc) 1.58 kB
const fs = require('fs').promises; // Patch tool to apply custom diffs marked with <<<<<<< ORIGINAL and >>>>>>> UPDATED // Handles patches with context and applies only the segments between markers. module.exports = async function patch({ text, filename }, ctx) { // Regex to match each patch block // Be lenient about the number of conflict marker characters because some // environments may trim one or more > or < characters. const patchRegex = /<{6,}\s*ORIGINAL[^\n]*\n([\s\S]*?)=+\n([\s\S]*?)>{6,}\s*UPDATED[^\n]*(?:\n|$)/g; const patches = []; let match; // Extract all old/new segments while ((match = patchRegex.exec(text)) !== null) { const oldPart = match[1].replace(/^\n+|\n+$/g, ""); const newPart = match[2].replace(/^\n+|\n+$/g, ""); patches.push({ oldPart, newPart }); } if (patches.length === 0) { return "No valid patch segments found"; } let fileContent = await ctx.read(filename); for (const { oldPart, newPart } of patches) { // Escape regex special chars in oldPart. // Do NOT relax all whitespace to \s+; that can swallow preceding newlines. // Only normalize line endings so CRLF in patches can match LF in files. let escaped = oldPart.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); escaped = escaped.replace(/\r?\n/g, "\\r?\\n"); const oldRegex = new RegExp(escaped, "g"); // Perform replacement using a function to avoid replacement string ambiguities fileContent = fileContent.replace(oldRegex, () => newPart); } await ctx.write(filename, fileContent); return "patched"; };