(
source: string,
patch: StructuredPatch,
options: ApplyPatchOptions = {}
)
| 73 | } |
| 74 | |
| 75 | function applyStructuredPatch( |
| 76 | source: string, |
| 77 | patch: StructuredPatch, |
| 78 | options: ApplyPatchOptions = {} |
| 79 | ): string | false { |
| 80 | if (options.autoConvertLineEndings || options.autoConvertLineEndings == null) { |
| 81 | if (hasOnlyWinLineEndings(source) && isUnix(patch)) { |
| 82 | patch = unixToWin(patch); |
| 83 | } else if (hasOnlyUnixLineEndings(source) && isWin(patch)) { |
| 84 | patch = winToUnix(patch); |
| 85 | } |
| 86 | } |
| 87 | |
| 88 | // Apply the diff to the input |
| 89 | const lines = source.split('\n'), |
| 90 | hunks = patch.hunks, |
| 91 | compareLine = options.compareLine || ((lineNumber, line, operation, patchContent) => line === patchContent), |
| 92 | fuzzFactor = options.fuzzFactor || 0; |
| 93 | let minLine = 0; |
| 94 | |
| 95 | if (fuzzFactor < 0 || !Number.isInteger(fuzzFactor)) { |
| 96 | throw new Error('fuzzFactor must be a non-negative integer'); |
| 97 | } |
| 98 | |
| 99 | // Special case for empty patch. |
| 100 | if (!hunks.length) { |
| 101 | return source; |
| 102 | } |
| 103 | |
| 104 | // Before anything else, handle EOFNL insertion/removal. If the patch tells us to make a change |
| 105 | // to the EOFNL that is redundant/impossible - i.e. to remove a newline that's not there, or add a |
| 106 | // newline that already exists - then we either return false and fail to apply the patch (if |
| 107 | // fuzzFactor is 0) or simply ignore the problem and do nothing (if fuzzFactor is >0). |
| 108 | // If we do need to remove/add a newline at EOF, this will always be in the final hunk: |
| 109 | let prevLine = '', |
| 110 | removeEOFNL = false, |
| 111 | addEOFNL = false; |
| 112 | for (let i = 0; i < hunks[hunks.length - 1].lines.length; i++) { |
| 113 | const line = hunks[hunks.length - 1].lines[i]; |
| 114 | if (line[0] == '\\') { |
| 115 | if (prevLine[0] == '+') { |
| 116 | removeEOFNL = true; |
| 117 | } else if (prevLine[0] == '-') { |
| 118 | addEOFNL = true; |
| 119 | } |
| 120 | } |
| 121 | prevLine = line; |
| 122 | } |
| 123 | if (removeEOFNL) { |
| 124 | if (addEOFNL) { |
| 125 | // This means the final line gets changed but doesn't have a trailing newline in either the |
| 126 | // original or patched version. In that case, we do nothing if fuzzFactor > 0, and if |
| 127 | // fuzzFactor is 0, we simply validate that the source file has no trailing newline. |
| 128 | if (!fuzzFactor && lines[lines.length - 1] == '') { |
| 129 | return false; |
| 130 | } |
| 131 | } else if (lines[lines.length - 1] == '') { |
| 132 | lines.pop(); |
no test coverage detected