You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
152 lines
16 KiB
152 lines
16 KiB
|
2 months ago
|
/*istanbul ignore start*/
|
||
|
|
"use strict";
|
||
|
|
|
||
|
|
Object.defineProperty(exports, "__esModule", {
|
||
|
|
value: true
|
||
|
|
});
|
||
|
|
exports.parsePatch = parsePatch;
|
||
|
|
/*istanbul ignore end*/
|
||
|
|
function parsePatch(uniDiff) {
|
||
|
|
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:\s|diff\s|\-\-\-\s|\+\+\+\s|===================================================================)/.test(_line)) {
|
||
|
|
break;
|
||
|
|
} else if (/^@@/.test(_line)) {
|
||
|
|
index.hunks.push(parseHunk());
|
||
|
|
} else if (_line) {
|
||
|
|
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+(.*)\r?$/.exec(diffstr[i]);
|
||
|
|
if (fileHeader) {
|
||
|
|
var keyPrefix = fileHeader[1] === '---' ? 'old' : 'new';
|
||
|
|
var data = fileHeader[2].split('\t', 2);
|
||
|
|
var fileName = data[0].replace(/\\\\/g, '\\');
|
||
|
|
if (/^".*"$/.test(fileName)) {
|
||
|
|
fileName = fileName.substr(1, fileName.length - 2);
|
||
|
|
}
|
||
|
|
index[keyPrefix + 'FileName'] = fileName;
|
||
|
|
index[keyPrefix + 'Header'] = (data[1] || '').trim();
|
||
|
|
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: typeof chunkHeader[2] === 'undefined' ? 1 : +chunkHeader[2],
|
||
|
|
newStart: +chunkHeader[3],
|
||
|
|
newLines: typeof chunkHeader[4] === 'undefined' ? 1 : +chunkHeader[4],
|
||
|
|
lines: []
|
||
|
|
};
|
||
|
|
|
||
|
|
// Unified Diff Format quirk: If the chunk size is 0,
|
||
|
|
// the first number is one lower than one would expect.
|
||
|
|
// https://www.artima.com/weblogs/viewpost.jsp?thread=164293
|
||
|
|
if (hunk.oldLines === 0) {
|
||
|
|
hunk.oldStart += 1;
|
||
|
|
}
|
||
|
|
if (hunk.newLines === 0) {
|
||
|
|
hunk.newStart += 1;
|
||
|
|
}
|
||
|
|
var addCount = 0,
|
||
|
|
removeCount = 0;
|
||
|
|
for (; i < diffstr.length && (removeCount < hunk.oldLines || addCount < hunk.newLines ||
|
||
|
|
/*istanbul ignore start*/
|
||
|
|
(_diffstr$i =
|
||
|
|
/*istanbul ignore end*/
|
||
|
|
diffstr[i]) !== null && _diffstr$i !== void 0 &&
|
||
|
|
/*istanbul ignore start*/
|
||
|
|
_diffstr$i
|
||
|
|
/*istanbul ignore end*/
|
||
|
|
.startsWith('\\')); i++) {
|
||
|
|
/*istanbul ignore start*/
|
||
|
|
var _diffstr$i;
|
||
|
|
/*istanbul ignore end*/
|
||
|
|
var operation = diffstr[i].length == 0 && i != diffstr.length - 1 ? ' ' : 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 {
|
||
|
|
throw new Error(
|
||
|
|
/*istanbul ignore start*/
|
||
|
|
"Hunk at line ".concat(
|
||
|
|
/*istanbul ignore end*/
|
||
|
|
chunkHeaderIndex + 1, " contained invalid line ").concat(diffstr[i]));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Handle the empty block count case
|
||
|
|
if (!addCount && hunk.newLines === 1) {
|
||
|
|
hunk.newLines = 0;
|
||
|
|
}
|
||
|
|
if (!removeCount && hunk.oldLines === 1) {
|
||
|
|
hunk.oldLines = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Perform sanity checking
|
||
|
|
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;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJwYXJzZVBhdGNoIiwidW5pRGlmZiIsImRpZmZzdHIiLCJzcGxpdCIsImxpc3QiLCJpIiwicGFyc2VJbmRleCIsImluZGV4IiwicHVzaCIsImxlbmd0aCIsImxpbmUiLCJ0ZXN0IiwiaGVhZGVyIiwiZXhlYyIsInBhcnNlRmlsZUhlYWRlciIsImh1bmtzIiwicGFyc2VIdW5rIiwiRXJyb3IiLCJKU09OIiwic3RyaW5naWZ5IiwiZmlsZUhlYWRlciIsImtleVByZWZpeCIsImRhdGEiLCJmaWxlTmFtZSIsInJlcGxhY2UiLCJzdWJzdHIiLCJ0cmltIiwiY2h1bmtIZWFkZXJJbmRleCIsImNodW5rSGVhZGVyTGluZSIsImNodW5rSGVhZGVyIiwiaHVuayIsIm9sZFN0YXJ0Iiwib2xkTGluZXMiLCJuZXdTdGFydCIsIm5ld0xpbmVzIiwibGluZXMiLCJhZGRDb3VudCIsInJlbW92ZUNvdW50IiwiX2RpZmZzdHIkaSIsInN0YXJ0c1dpdGgiLCJvcGVyYXRpb24iLCJjb25jYXQiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvcGF0Y2gvcGFyc2UuanMiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGZ1bmN0aW9uIHBhcnNlUGF0Y2godW5pRGlmZikge1xuICBsZXQgZGlmZnN0ciA9IHVuaURpZmYuc3BsaXQoL1xcbi8pLFxuICAgICAgbGlzdCA9IFtdLFxuICAgICAgaSA9IDA7XG5cbiAgZnVuY3Rpb24gcGFyc2VJbmRleCgpIHtcbiAgICBsZXQgaW5kZXggPSB7fTtcbiAgICBsaXN0LnB1c2goaW5kZXgpO1xuXG4gICAgLy8gUGFyc2UgZGlmZiBtZXRhZGF0YVxuICAgIHdoaWxlIChpIDwgZGlmZnN0ci5sZW5ndGgpIHtcbiAgICAgIGxldCBsaW5lID0gZGlmZnN0cltpXTtcblxuICAgICAgLy8gRmlsZSBoZWFkZXIgZm91bmQsIGVuZCBwYXJzaW5nIGRpZmYgbWV0YWRhdGFcbiAgICAgIGlmICgoL14oXFwtXFwtXFwtfFxcK1xcK1xcK3xAQClcXHMvKS50ZXN0KGxpbmUpKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICAvLyBEaWZmIGluZGV4XG4gICAgICBsZXQgaGVhZGVyID0gKC9eKD86SW5kZXg6fGRpZmYoPzogLXIgXFx3KykrKVxccysoLis/KVxccyokLykuZXhlYyhsaW5lKTtcbiAgICAgIGlmIChoZWFkZXIpIHtcbiAgICAgICAgaW5kZXguaW5kZXggPSBoZWFkZXJbMV07XG4gICAgICB9XG5cbiAgICAgIGkrKztcbiAgICB9XG5cbiAgICAvLyBQYXJzZSBmaWxlIGhlYWRlcnMgaWYgdGhleSBhcmUgZGVmaW5lZC4gVW5pZmllZCBkaWZmIHJlcXVpcmVzIHRoZW0sIGJ1dFxuICAgIC8vIHRoZXJlJ3Mgbm8gdGVjaG5pY2FsIGlzc3VlcyB0byBoYXZlIGFuIGlzb2xhdGVkIGh1bmsgd2l0aG91dCBmaWxlIGhlYWRlclxuICAgIHBhcnNlRmlsZUhlYWRlcihpbmRleCk7XG4gICAgcGFyc2VGaWxlSGVhZGVyKGluZGV4KTtcblxuICAgIC8vIFBhcnNlIGh1bmtzXG4gICAgaW5kZXguaHVua3MgPSBbXTtcblxuICAgIHdoaWxlIChpIDwgZGlmZnN0ci5sZW5ndGgpIHtcbiAgICAgIGxldCBsaW5lID0gZGlmZnN0cltpXTtcbiAgICAgIGlmICgoL14oSW5kZXg6XFxzfGRpZmZcXHN8XFwtXFwtXFwtXFxzfFxcK1xcK1xcK1xcc3w9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09KS8pLnRlc3QobGluZSkpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9IGVsc2UgaWYgKCgvXkBALykudGVzdChsaW5lKSkge1xuICAgICAgICBpbmRleC5odW5rcy5wdXNoKHBhcnNlSHVuaygpKTtcbiAgICAgIH0gZWxzZSBpZiAobGluZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gbGluZSAnICsgKGkgKyAxKSArICcgJyArIEpTT04uc3RyaW5naWZ5KGxpbmUpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGkrKztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBQYXJzZXMgdGhlIC0tLSBhbmQgKysrIGhlYWRlcnMsIGlmIG5vbmUgYXJlIGZvdW5kLCBubyBsaW5lc1xuICAvLyBhcmUgY29uc3VtZWQuXG4gIGZ1bmN0aW9uIHBhcnNlRmlsZUhlYWRlcihpbmRleCkge1xuICAgIGNvbnN0IGZpbGVIZWFkZXIgPSAoL14oLS0tfFxcK1xcK1xcKylcXHMrKC4qKVxccj8kLykuZXhlYyhkaWZmc3RyW2ldKTtcbiAgICBpZiAoZmlsZUhlYWRlcikge1xuICAgICAgbGV0IGtleVByZWZpeCA9IGZpbGVIZWFkZXJbMV0gPT09ICctLS0nID8gJ29sZCcgOiAnbmV3JztcbiAgICAgIGNvbnN0IGRhdGEgPSBmaWxlSGVhZGVyWzJdLnNwbGl0KCdcXHQnLCAyKTtcbiAgICAgIGxldCBmaWxlTmFtZSA9IGRhdGFbMF0ucmVwbGFjZSgvXFxcXFxcXFwvZywgJ1xcXFwnKTtcbiAgICAgIGlmICgoL15cIi4qXCIkLykudGVzdChmaWxlTmFtZSkpIHtcbiAgICAgICAgZmlsZU5hbWUgPSBmaWxlTmFtZS5zdWJzdHIoMSwgZmlsZU5hbWUubGVuZ3RoIC0gMik7XG4gICAgICB9XG4gICAgICBpbmRleFtrZXlQcmVmaXggKyAnRmlsZU5hbWUnXSA9IGZpbGVOYW1lO1xuICAgICAgaW5kZXhba2V5UHJlZml4ICsgJ0hlYWRlciddID0gKGRhdGFbMV0gfHwgJycpLnRyaW0oKTtcblxuICAgICAgaSsrO1xuICAgIH1cbiAgfVxuXG4gIC8vIFBhcnNlcyBhIGh1bmtcbiAgLy8gVGhpcyBhc3N1bWVzIHRoYXQgd2UgYXJlIGF0IHRoZSBzdGFydCBvZiBhIGh1bmsuXG4gIGZ1bmN0aW9uIHBhcnNlSHVuaygpIHtcbiAgICBsZXQgY2h1bmtIZWFkZXJJbmRleCA9IGksXG4gICAgICAgIGNodW5rSGVhZGVyTGluZSA9IGRpZmZzdHJbaSsrXSxcbiAgICAgICAgY2h1bmtIZWFkZXIgPSBjaHVua0hlYWRlckxpbmUuc3BsaXQoL0BAIC0oXFxkKykoPzosKFxcZCspKT8gXFwrKFxcZCspKD86LChcXGQrKSk/IEBALyk7XG5cbiAgICBsZXQgaHVuayA9IHtcbiAgICAgIG9sZFN0YXJ0OiArY2h1bmtIZWFkZXJbMV0sXG4gICAgICBvbGRMaW5lczogdHlwZW9mIGNodW5rSGVhZGVyWzJdID09PSAndW5kZWZpbmVkJyA/IDEgOiArY2h1bmtIZWFkZXJbMl0sXG4gICAgICBuZXdTdGFydDogK2NodW5rSGVhZGVyWzNdLFxuICAgICAgbmV3TGluZXM6IHR5cGVvZiBjaHVua0hlYWRlcls0XSA9PT0gJ3VuZGVmaW5lZCcgPyAxIDogK2NodW5rSGVhZGVyWzRdLFxuICAgICAgbGl
|