UNPKG

4.12 kBJavaScriptView Raw
1"use strict";
2/**
3 * Parse a string that represents a git patch
4 * @param {String} contents The contents of the patch to parse
5 * @return {Object} An object where the keys are filenames, and the
6 * values are the contents of the diff
7 */
8function parsePatch(contents) {
9 var sha = contents.split(' ')[1];
10 var message = /^Subject: \[.+?\] ([\S\s]+)?^---$/m.exec(contents)[1].trim().replace('\n', '');
11 var fileParts = contents.split(/^diff --git /m).slice(1);
12 var files = {};
13 fileParts.forEach(function (part) {
14 var start = part.indexOf('@@');
15 var diffContents = part.slice(start);
16 // XXX won't work with spaces in filenames
17 var fileNameMatch = /^\+\+\+ b\/(.+)$/m.exec(part);
18 if (!fileNameMatch) {
19 // This was probably a deleted file
20 return;
21 }
22 var fileName = fileNameMatch[1];
23 var fileData = parseUnifiedDiff(diffContents);
24 files[fileName] = fileData;
25 });
26 return {
27 files: files,
28 sha: sha,
29 message: message
30 };
31}
32exports.parsePatch = parsePatch;
33function parseMultiPatch(contents) {
34 //contents = contents.replace(/\n[+-]{1}/g, '\n');
35 var patchStart = /^From /gm;
36 var match = patchStart.exec(contents);
37 var patchIndices = [];
38 while (match !== null) {
39 patchIndices.push(match.index);
40 match = patchStart.exec(contents);
41 }
42 var patches = [];
43 patchIndices.forEach(function (_, i) {
44 var patchContent = '';
45 if (i + 1 < patchIndices.length) {
46 patchContent = contents.slice(patchIndices[i], patchIndices[i + 1]);
47 }
48 else {
49 patchContent = contents.slice(patchIndices[i]);
50 }
51 // Remove the weird -- 2.2.1 part at the end of every patch
52 patchContent = patchContent.split(/^-- $/m)[0];
53 patches.push(patchContent);
54 });
55 return patches.map(parsePatch);
56}
57exports.parseMultiPatch = parseMultiPatch;
58function parseUnifiedDiff(diffContents) {
59 var diffLines = diffContents.split('\n');
60 // Take off the last line which is just empty
61 var contentPatchLines = diffLines.slice(0, diffLines.length - 1);
62 var parsedLines = contentPatchLines.map(function (line) {
63 if (!line) {
64 // The last line ends up being an empty string
65 return null;
66 }
67 if (/^@/.test(line)) {
68 var lineNumberMatch = /^@@ -(\d+),?(\d+)? \+(\d+),?(\d+)? @@/.exec(line).map(function (str) {
69 return parseInt(str, 10);
70 });
71 return {
72 type: 'lineNumbers',
73 lineNumbers: {
74 removed: {
75 start: lineNumberMatch[1],
76 lines: lineNumberMatch[2]
77 },
78 added: {
79 start: lineNumberMatch[3],
80 lines: lineNumberMatch[4]
81 }
82 }
83 };
84 }
85 var type = 'context';
86 if (/^\+/.test(line)) {
87 type = 'added';
88 }
89 else if (/^-/.test(line)) {
90 type = 'removed';
91 }
92 var content = line.slice(1);
93 return {
94 type: type,
95 content: content
96 };
97 });
98 // Now that we have parsed all of the lines, assemble them into sections that
99 // have their own line number ranges
100 var sections = [];
101 var currSection;
102 parsedLines.forEach(function (line) {
103 if (line !== null && line.content !== ' No newline at end of file') {
104 if (line.type === 'lineNumbers') {
105 if (currSection) {
106 sections.push(currSection);
107 }
108 currSection = {
109 lines: [],
110 lineNumbers: line.lineNumbers
111 };
112 }
113 else {
114 currSection.lines.push(line);
115 }
116 }
117 });
118 sections.push(currSection);
119 return sections;
120}
121exports.parseUnifiedDiff = parseUnifiedDiff;
122//# sourceMappingURL=patch-parser.js.map
\No newline at end of file