UNPKG

diffparser

Version:
211 lines (180 loc) 7.51 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); /** * Parse unified diff input * see: http://www.gnu.org/software/diffutils/manual/diffutils.html#Unified-Format */ exports.default = function (input) { var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (!input) return []; if (input.match(/^\s+$/)) return []; var lines = input.split('\n'); if (lines.length == 0) return []; var files = []; var file = null; var oldLine = 0; var newLine = 0; var position = 0; var current = null; function start(line) { var _parseFile = parseFile(line), _parseFile2 = _slicedToArray(_parseFile, 2), from = _parseFile2[0], to = _parseFile2[1]; file = { from: from, to: to, chunks: [], deletions: 0, additions: 0 }; files.push(file); position = 0; } function restart() { if (!file || file.chunks.length) start(); } function newFile() { restart(); file.new = true; file.from = '/dev/null'; } function deletedFile() { restart(); file.deleted = true; file.to = '/dev/null'; } function index(line) { restart(); file.index = line.split(' ').slice(1); } function fromFile(line) { restart(); file.from = parseFileFallback(line); } function toFile(line) { restart(); file.to = parseFileFallback(line); } function chunk(line, match) { var _match$map = match.map(function (l) { return +(l || 0); }), _match$map2 = _slicedToArray(_match$map, 5), oldStart = _match$map2[1], oldLines = _match$map2[2], newStart = _match$map2[3], newLines = _match$map2[4]; oldLine = oldStart; newLine = newStart; current = { content: line, changes: [], oldStart: oldStart, oldLines: oldLines, newStart: newStart, newLines: newLines }; file.chunks.push(current); if (!position) position = 1; } function del(line) { current.changes.push({ type: 'del', del: true, oldLine: oldLine++, position: position++, content: line }); file.deletions++; } function add(line) { current.changes.push({ type: 'add', add: true, newLine: newLine++, position: position++, content: line }); file.additions++; } var noeol = '\\ No newline at end of file'; function normal(line) { if (!file) return; current.changes.push({ type: 'normal', normal: true, oldLine: line !== noeol ? oldLine++ : undefined, newLine: line !== noeol ? newLine++ : undefined, position: position++, content: line }); } var schema = [[/^\s+/, normal], [/^diff\s/, start], [/^new file mode \d+$/, newFile], [/^deleted file mode \d+$/, deletedFile], [/^index\s[\da-zA-Z]+\.\.[\da-zA-Z]+(\s(\d+))?$/, index], [/^---\s/, fromFile], [/^\+\+\+\s/, toFile], [/^@@\s+\-(\d+),?(\d*)\s+\+(\d+),?(\d*)\s@@/, chunk], [/^-/, del], [/^\+/, add]]; function parse(line) { return schema.some(function (p) { var _p = _slicedToArray(p, 2), pattern = _p[0], handler = _p[1]; if (typeof handler !== 'function') { throw new Error(pattern + ' has no handler'); } var m = line.match(pattern); if (m) { handler(line, m); return true; } return false; }); } lines.forEach(parse); if (opts.findRenames) consolidateRenames(files); return files; }; function getContent(file) { return file.chunks.map(function (chunk) { return chunk.changes.map(function (c) { return c.content.slice(1); }); }).join('\n'); } function consolidateRenames(files) { var newFiles = files.filter(function (f) { return f.new; }); newFiles.forEach(function (newFile) { var newContent = getContent(newFile); var i = files.findIndex(function (f) { return f.deleted && getContent(f) == newContent; }); if (~i) { var oldFile = files[i]; files.splice(i, 1); delete newFile.new; delete newFile.chunks; delete newFile.deletions; delete newFile.additions; delete newFile.index; newFile.renamed = true; newFile.from = oldFile.from; } }); } function parseFile(s) { if (!s) return []; var fileNames = s.split(' ').slice(-2); return fileNames.map(function (f) { return f.replace(/^(a|b)\//, ''); }); } function parseFileFallback(s) { s = s.replace(/^\s*(\++|-+)/, '').trim(); // ignore possible timestamp var t = /\t.*|\d{4}-\d\d-\d\d\s\d\d:\d\d:\d\d(.\d+)?\s(\+|-)\d\d\d\d/.exec(s); if (t) s = s.substring(0, t.index).trim(); // ignore git prefixes a/ or b/ return s.match(/^(a|b)\//) ? s.substr(2) : s; } module.exports = exports['default'];