135 lines
12 KiB
JavaScript
135 lines
12 KiB
JavaScript
|
/*istanbul ignore start*/'use strict';
|
||
|
|
||
|
exports.__esModule = true;
|
||
|
exports. /*istanbul ignore end*/parsePatch = parsePatch;
|
||
|
function parsePatch(uniDiff) {
|
||
|
/*istanbul ignore start*/var /*istanbul ignore end*/options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
|
||
|
|
||
|
var diffstr = uniDiff.split('\n'),
|
||
|
list = [],
|
||
|
i = 0;
|
||
|
|
||
|
function parseIndex() {
|
||
|
var index = {};
|
||
|
list.push(index);
|
||
|
|
||
|
// Parse diff metadata
|
||
|
while (i < diffstr.length) {
|
||
|
var line = diffstr[i];
|
||
|
|
||
|
// File header found, end parsing diff metadata
|
||
|
if (/^(\-\-\-|\+\+\+|@@)\s/.test(line)) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Diff index
|
||
|
var header = /^(?:Index:|diff(?: -r \w+)+)\s+(.+?)\s*$/.exec(line);
|
||
|
if (header) {
|
||
|
index.index = header[1];
|
||
|
}
|
||
|
|
||
|
i++;
|
||
|
}
|
||
|
|
||
|
// Parse file headers if they are defined. Unified diff requires them, but
|
||
|
// there's no technical issues to have an isolated hunk without file header
|
||
|
parseFileHeader(index);
|
||
|
parseFileHeader(index);
|
||
|
|
||
|
// Parse hunks
|
||
|
index.hunks = [];
|
||
|
|
||
|
while (i < diffstr.length) {
|
||
|
var _line = diffstr[i];
|
||
|
|
||
|
if (/^(Index:|diff|\-\-\-|\+\+\+)\s/.test(_line)) {
|
||
|
break;
|
||
|
} else if (/^@@/.test(_line)) {
|
||
|
index.hunks.push(parseHunk());
|
||
|
} else if (_line && options.strict) {
|
||
|
// Ignore unexpected content unless in strict mode
|
||
|
throw new Error('Unknown line ' + (i + 1) + ' ' + JSON.stringify(_line));
|
||
|
} else {
|
||
|
i++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Parses the --- and +++ headers, if none are found, no lines
|
||
|
// are consumed.
|
||
|
function parseFileHeader(index) {
|
||
|
var fileHeader = /^(\-\-\-|\+\+\+)\s+(\S*)\s?(.*?)\s*$/.exec(diffstr[i]);
|
||
|
if (fileHeader) {
|
||
|
var keyPrefix = fileHeader[1] === '---' ? 'old' : 'new';
|
||
|
index[keyPrefix + 'FileName'] = fileHeader[2];
|
||
|
index[keyPrefix + 'Header'] = fileHeader[3];
|
||
|
|
||
|
i++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Parses a hunk
|
||
|
// This assumes that we are at the start of a hunk.
|
||
|
function parseHunk() {
|
||
|
var chunkHeaderIndex = i,
|
||
|
chunkHeaderLine = diffstr[i++],
|
||
|
chunkHeader = chunkHeaderLine.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/);
|
||
|
|
||
|
var hunk = {
|
||
|
oldStart: +chunkHeader[1],
|
||
|
oldLines: +chunkHeader[2] || 1,
|
||
|
newStart: +chunkHeader[3],
|
||
|
newLines: +chunkHeader[4] || 1,
|
||
|
lines: []
|
||
|
};
|
||
|
|
||
|
var addCount = 0,
|
||
|
removeCount = 0;
|
||
|
for (; i < diffstr.length; i++) {
|
||
|
var operation = diffstr[i][0];
|
||
|
|
||
|
if (operation === '+' || operation === '-' || operation === ' ' || operation === '\\') {
|
||
|
hunk.lines.push(diffstr[i]);
|
||
|
|
||
|
if (operation === '+') {
|
||
|
addCount++;
|
||
|
} else if (operation === '-') {
|
||
|
removeCount++;
|
||
|
} else if (operation === ' ') {
|
||
|
addCount++;
|
||
|
removeCount++;
|
||
|
}
|
||
|
} else {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Handle the empty block count case
|
||
|
if (!addCount && hunk.newLines === 1) {
|
||
|
hunk.newLines = 0;
|
||
|
}
|
||
|
if (!removeCount && hunk.oldLines === 1) {
|
||
|
hunk.oldLines = 0;
|
||
|
}
|
||
|
|
||
|
// Perform optional sanity checking
|
||
|
if (options.strict) {
|
||
|
if (addCount !== hunk.newLines) {
|
||
|
throw new Error('Added line count did not match for hunk at line ' + (chunkHeaderIndex + 1));
|
||
|
}
|
||
|
if (removeCount !== hunk.oldLines) {
|
||
|
throw new Error('Removed line count did not match for hunk at line ' + (chunkHeaderIndex + 1));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return hunk;
|
||
|
}
|
||
|
|
||
|
while (i < diffstr.length) {
|
||
|
parseIndex();
|
||
|
}
|
||
|
|
||
|
return list;
|
||
|
}
|
||
|
//# sourceMappingURL=data:application/json;base64,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LENBQVIsRUFBVyxDQUFYLENBQVosQ0FEMEI7O0FBRzlCLFVBQUksY0FBYyxHQUFkLElBQXFCLGNBQWMsR0FBZCxJQUFxQixjQUFjLEdBQWQsSUFBcUIsY0FBYyxJQUFkLEVBQW9CO0FBQ3JGLGFBQUssS0FBTCxDQUFXLElBQVgsQ0FBZ0IsUUFBUSxDQUFSLENBQWhCLEVBRHFGOztBQUdyRixZQUFJLGNBQWMsR0FBZCxFQUFtQjtBQUNyQixxQkFEcUI7U0FBdkIsTUFFTyxJQUFJLGNBQWMsR0FBZCxFQUFtQjtBQUM1Qix3QkFENEI7U0FBdkIsTUFFQSxJQUFJLGNBQWMsR0FBZCxFQUFtQjtBQUM1QixxQkFENEI7QUFFNUIsd0JBRjRCO1NBQXZCO09BUFQsTUFXTztBQUNMLGNBREs7T0FYUDtLQUhGOzs7QUFmbUIsUUFtQ2YsQ0FBQyxRQUFELElBQWEsS0FBSyxRQUFMLEtBQWtCLENBQWxCLEVBQXFCO0FBQ3BDLFdBQUssUUFBTCxHQUFnQixDQUFoQixDQURvQztLQUF0QztBQUdBLFFBQUksQ0FBQyxXQUFELElBQWdCLEtBQUssUUFBTCxLQUFrQixDQUFsQixFQUFxQjtBQUN2QyxXQUFLLFFBQUwsR0FBZ0IsQ0FBaEIsQ0FEdUM7S0FBekM7OztBQXRDbUIsUUEyQ2YsUUFBUSxNQUFSLEVBQWdCO0FBQ2xCLFVBQUksYUFBYSxLQUFLLFFBQUwsRUFBZTtBQUM5QixjQUFNLElBQUksS0FBSixDQUFVLHNEQUFzRCxtQkFBbUIsQ0FBbkIsQ0FBdEQsQ0FBaEIsQ0FEOEI7T0FBaEM7QUFHQSxVQUFJLGdCQUFnQixLQUFLLFFBQUwsRUFBZTtBQUNqQyxjQUFNLElBQUksS0FBSixDQUFVLHdEQUF3RCxtQkFBbUIsQ0FBbkIsQ0FBeEQsQ0FBaEIsQ0FEaUM7T0FBbkM7S0FKRjs7QUFTQSxXQUFPLElBQVAsQ0FwRG1CO0dBQXJCOztBQXVEQSxTQUFPLElBQUksUUFBUSxNQUFSLEVBQWdCO0FBQ3pCLGlCQUR5QjtHQUEzQjs7QUFJQSxTQUFPLElBQVAsQ0E3SGdEO0NBQTNDIiwiZmlsZSI6InBhcnNlLmpzIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGZ1bmN0aW9uIHBhcnNlUGF0Y2godW5pRGlmZiwgb3B0aW9ucyA9IHt9KSB7XG4gIGxldCBkaWZmc3RyID0gdW5pRGlmZi5zcGxpdCgnXFxuJyksXG4gICAgICBsaXN0ID0gW10sXG4gICAgICBpID0gMDtcblxuICBmdW5jdGlvbiBwYXJzZUluZGV4KCkge1xuICAgIGxldCBpbmRleCA9IHt9O1xuICAgIGxpc3QucHVzaChpbmRleCk7XG5cbiAgICAvLyBQYXJzZSBkaWZmIG1ldGFkYXRhXG4gICAgd2hpbGUgKGkgPCBkaWZmc3RyLmxlbmd0aCkge1xuICAgICAgbGV0IGxpbmUgPSBkaWZmc3RyW2ldO1xuXG4gICAgICAvLyBGaWxlIGhlYWRlciBmb3VuZ
|