2017-05-28 00:38:50 +02:00
|
|
|
/*istanbul ignore start*/'use strict';
|
|
|
|
|
|
|
|
exports.__esModule = true;
|
|
|
|
exports. /*istanbul ignore end*/parsePatch = parsePatch;
|
|
|
|
function parsePatch(uniDiff) {
|
2017-12-10 21:51:33 +01:00
|
|
|
/*istanbul ignore start*/var /*istanbul ignore end*/options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
2017-05-28 00:38:50 +02:00
|
|
|
|
|
|
|
var diffstr = uniDiff.split(/\r\n|[\n\v\f\r\x85]/),
|
|
|
|
delimiters = uniDiff.match(/\r\n|[\n\v\f\r\x85]/g) || [],
|
|
|
|
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 headerPattern = /^(---|\+\+\+)\s+([\S ]*)(?:\t(.*?)\s*)?$/;
|
|
|
|
var fileHeader = headerPattern.exec(diffstr[i]);
|
|
|
|
if (fileHeader) {
|
|
|
|
var keyPrefix = fileHeader[1] === '---' ? 'old' : 'new';
|
2017-08-14 05:01:11 +02:00
|
|
|
var fileName = fileHeader[2].replace(/\\\\/g, '\\');
|
|
|
|
if (/^".*"$/.test(fileName)) {
|
|
|
|
fileName = fileName.substr(1, fileName.length - 2);
|
|
|
|
}
|
|
|
|
index[keyPrefix + 'FileName'] = fileName;
|
2017-05-28 00:38:50 +02:00
|
|
|
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: [],
|
|
|
|
linedelimiters: []
|
|
|
|
};
|
|
|
|
|
|
|
|
var addCount = 0,
|
|
|
|
removeCount = 0;
|
|
|
|
for (; i < diffstr.length; i++) {
|
|
|
|
// Lines starting with '---' could be mistaken for the "remove line" operation
|
|
|
|
// But they could be the header for the next file. Therefore prune such cases out.
|
|
|
|
if (diffstr[i].indexOf('--- ') === 0 && i + 2 < diffstr.length && diffstr[i + 1].indexOf('+++ ') === 0 && diffstr[i + 2].indexOf('@@') === 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
var operation = diffstr[i][0];
|
|
|
|
|
|
|
|
if (operation === '+' || operation === '-' || operation === ' ' || operation === '\\') {
|
|
|
|
hunk.lines.push(diffstr[i]);
|
|
|
|
hunk.linedelimiters.push(delimiters[i] || '\n');
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2017-12-10 21:51:33 +01:00
|
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wYXRjaC9wYXJzZS5qcyJdLCJuYW1lcyI6WyJwYXJzZVBhdGNoIiwidW5pRGlmZiIsIm9wdGlvbnMiLCJkaWZmc3RyIiwic3BsaXQiLCJkZWxpbWl0ZXJzIiwibWF0Y2giLCJsaXN0IiwiaSIsInBhcnNlSW5kZXgiLCJpbmRleCIsInB1c2giLCJsZW5ndGgiLCJsaW5lIiwidGVzdCIsImhlYWRlciIsImV4ZWMiLCJwYXJzZUZpbGVIZWFkZXIiLCJodW5rcyIsInBhcnNlSHVuayIsInN0cmljdCIsIkVycm9yIiwiSlNPTiIsInN0cmluZ2lmeSIsImhlYWRlclBhdHRlcm4iLCJmaWxlSGVhZGVyIiwia2V5UHJlZml4IiwiZmlsZU5hbWUiLCJyZXBsYWNlIiwic3Vic3RyIiwiY2h1bmtIZWFkZXJJbmRleCIsImNodW5rSGVhZGVyTGluZSIsImNodW5rSGVhZGVyIiwiaHVuayIsIm9sZFN0YXJ0Iiwib2xkTGluZXMiLCJuZXdTdGFydCIsIm5ld0xpbmVzIiwibGluZXMiLCJsaW5lZGVsaW1pdGVycyIsImFkZENvdW50IiwicmVtb3ZlQ291bnQiLCJpbmRleE9mIiwib3BlcmF0aW9uIl0sIm1hcHBpbmdzIjoiOzs7Z0NBQWdCQSxVLEdBQUFBLFU7QUFBVCxTQUFTQSxVQUFULENBQW9CQyxPQUFwQixFQUEyQztBQUFBLHNEQUFkQyxPQUFjLHVFQUFKLEVBQUk7O0FBQ2hELE1BQUlDLFVBQVVGLFFBQVFHLEtBQVIsQ0FBYyxxQkFBZCxDQUFkO0FBQUEsTUFDSUMsYUFBYUosUUFBUUssS0FBUixDQUFjLHNCQUFkLEtBQXlDLEVBRDFEO0FBQUEsTUFFSUMsT0FBTyxFQUZYO0FBQUEsTUFHSUMsSUFBSSxDQUhSOztBQUtBLFdBQVNDLFVBQVQsR0FBc0I7QUFDcEIsUUFBSUMsUUFBUSxFQUFaO0FBQ0FILFNBQUtJLElBQUwsQ0FBVUQsS0FBVjs7QUFFQTtBQUNBLFdBQU9GLElBQUlMLFFBQVFTLE1BQW5CLEVBQTJCO0FBQ3pCLFVBQUlDLE9BQU9WLFFB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
|