tune-basic-toolset 0.1.14 → 0.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/patch.tool.js +21 -45
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tune-basic-toolset",
3
- "version": "0.1.14",
3
+ "version": "0.1.15",
4
4
  "description": "Basic toolset for tune",
5
5
  "main": "src/index.js",
6
6
  "files": [
package/src/patch.tool.js CHANGED
@@ -1,21 +1,20 @@
1
1
  const fs = require('fs').promises;
2
2
 
3
3
  // Patch tool to apply custom diffs marked with <<<<<<< ORIGINAL and >>>>>>> UPDATED
4
- // More tolerant to whitespace differences on each line and reports per-block success.
5
- module.exports = async function patch({ text, filename }, ctx) {
6
- if (!text || !filename) {
7
- return "No patch text or filename provided";
8
- }
9
-
10
- // Match: <<<<<<< ORIGINAL ... ======= ... >>>>>>> UPDATED
11
- // Be tolerant to CRLF/LF and optional trailing text/spaces on the markers.
12
- const patchRegex = /<{6,}\s*ORIGINAL[^\n]*\r?\n([\s\S]*?)=+[^\n]*\r?\n([\s\S]*?)>{6,}\s*UPDATED[^\n]*(?:\r?\n|$)/g;
4
+ // Handles patches with context and applies only the segments between markers.
13
5
 
6
+ module.exports = async function patch({ text, filename }, ctx) {
7
+ // Regex to match each patch block
8
+ // Be lenient about the number of conflict marker characters because some
9
+ // environments may trim one or more > or < characters.
10
+ const patchRegex = /<{6,}\s*ORIGINAL[^\n]*\n([\s\S]*?)=+\n([\s\S]*?)>{6,}\s*UPDATED[^\n]*(?:\n|$)/g;
14
11
  const patches = [];
15
- let m;
16
- while ((m = patchRegex.exec(text)) !== null) {
17
- const oldPart = String(m[1]).replace(/^\s*\r?\n+|\r?\n+\s*$/g, "");
18
- const newPart = String(m[2]).replace(/^\s*\r?\n+|\r?\n+\s*$/g, "");
12
+ let match;
13
+
14
+ // Extract all old/new segments
15
+ while ((match = patchRegex.exec(text)) !== null) {
16
+ const oldPart = match[1].replace(/^\n+|\n+$/g, "");
17
+ const newPart = match[2].replace(/^\n+|\n+$/g, "");
19
18
  patches.push({ oldPart, newPart });
20
19
  }
21
20
 
@@ -25,41 +24,18 @@ module.exports = async function patch({ text, filename }, ctx) {
25
24
 
26
25
  let fileContent = await ctx.read(filename);
27
26
 
28
- function buildPattern(oldStr) {
29
- // Escape special regex chars
30
- let escaped = oldStr.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
31
- // Normalize line endings to \r?\n so CRLF/LF both match
27
+ for (const { oldPart, newPart } of patches) {
28
+ // Escape regex special chars in oldPart.
29
+ // Do NOT relax all whitespace to \s+; that can swallow preceding newlines.
30
+ // Only normalize line endings so CRLF in patches can match LF in files.
31
+ let escaped = oldPart.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
32
32
  escaped = escaped.replace(/\r?\n/g, "\\r?\\n");
33
- // Tolerate indentation/space differences (spaces or tabs), zero-or-more
34
- // Keep newlines strict so structure must still match.
35
- escaped = escaped.replace(/[ \t]+/g, "[ \\t]*");
36
- return new RegExp(escaped, "g");
37
- }
38
-
39
- const totalSegments = patches.length;
40
- let appliedSegments = 0;
41
- let totalReplacements = 0;
33
+ const oldRegex = new RegExp(escaped, "g");
42
34
 
43
- for (const { oldPart, newPart } of patches) {
44
- const re = buildPattern(oldPart);
45
- let matches = 0;
46
- fileContent = fileContent.replace(re, () => {
47
- matches += 1;
48
- return newPart;
49
- });
50
- if (matches > 0) {
51
- appliedSegments += 1;
52
- totalReplacements += matches;
53
- }
35
+ // Perform replacement using a function to avoid replacement string ambiguities
36
+ fileContent = fileContent.replace(oldRegex, () => newPart);
54
37
  }
55
38
 
56
39
  await ctx.write(filename, fileContent);
57
-
58
- if (appliedSegments === 0) {
59
- return `no matches applied (0/${totalSegments})`;
60
- }
61
- if (appliedSegments < totalSegments) {
62
- return `patched partially (${appliedSegments}/${totalSegments}), replacements: ${totalReplacements}`;
63
- }
64
- return `patched (${appliedSegments}/${totalSegments}), replacements: ${totalReplacements}`;
40
+ return "patched";
65
41
  };