UNPKG

3.28 kBJavaScriptView Raw
1(function() {
2 var _, parseFile;
3
4 _ = require('underscore');
5
6 _.str = require('underscore.string');
7
8 module.exports = function(input) {
9 var add, chunk, del, deleted_file, file, files, from_file, i, index, len, line, lines, ln_add, ln_del, new_file, noeol, normal, parse, restart, schema, start, to_file;
10 if (!input) {
11 return [];
12 }
13 if (input.match(/^\s+$/)) {
14 return [];
15 }
16 lines = input.split('\n');
17 if (lines.length === 0) {
18 return [];
19 }
20 files = [];
21 file = null;
22 ln_del = 0;
23 ln_add = 0;
24 start = function() {
25 file = {
26 lines: [],
27 deletions: 0,
28 additions: 0
29 };
30 return files.push(file);
31 };
32 restart = function() {
33 if (!file || file.lines.length) {
34 return start();
35 }
36 };
37 new_file = function() {
38 restart();
39 return file["new"] = true;
40 };
41 deleted_file = function() {
42 restart();
43 return file.deleted = true;
44 };
45 index = function(line) {
46 restart();
47 return file.index = line.split(' ').slice(1);
48 };
49 from_file = function(line) {
50 restart();
51 return file.from = parseFile(line);
52 };
53 to_file = function(line) {
54 restart();
55 return file.to = parseFile(line);
56 };
57 chunk = function(line, match) {
58 ln_del = +match[1];
59 ln_add = +match[3];
60 return file.lines.push({
61 type: 'chunk',
62 chunk: true,
63 content: line
64 });
65 };
66 del = function(line) {
67 file.lines.push({
68 type: 'del',
69 del: true,
70 ln: ln_del++,
71 content: line
72 });
73 return file.deletions++;
74 };
75 add = function(line) {
76 file.lines.push({
77 type: 'add',
78 add: true,
79 ln: ln_add++,
80 content: line
81 });
82 return file.additions++;
83 };
84 noeol = '\\ No newline at end of file';
85 normal = function(line) {
86 if (!file) {
87 return;
88 }
89 return file.lines.push({
90 type: 'normal',
91 normal: true,
92 ln1: line !== noeol ? ln_del++ : void 0,
93 ln2: line !== noeol ? ln_add++ : void 0,
94 content: line
95 });
96 };
97 schema = [[/^diff\s/, start], [/^new file mode \d+$/, new_file], [/^deleted file mode \d+$/, deleted_file], [/^index\s[\da-zA-Z]+\.\.[\da-zA-Z]+(\s(\d+))?$/, index], [/^---\s/, from_file], [/^\+\+\+\s/, to_file], [/^@@\s+\-(\d+),(\d+)\s+\+(\d+),(\d+)\s@@/, chunk], [/^-/, del], [/^\+/, add]];
98 parse = function(line) {
99 var i, len, m, p;
100 for (i = 0, len = schema.length; i < len; i++) {
101 p = schema[i];
102 m = line.match(p[0]);
103 if (m) {
104 p[1](line, m);
105 return true;
106 }
107 }
108 return false;
109 };
110 for (i = 0, len = lines.length; i < len; i++) {
111 line = lines[i];
112 if (!parse(line)) {
113 normal(line);
114 }
115 }
116 return files;
117 };
118
119 parseFile = function(s) {
120 var t;
121 s = _.str.ltrim(s, '-');
122 s = _.str.ltrim(s, '+');
123 s = s.trim();
124 t = /\d{4}-\d\d-\d\d\s\d\d:\d\d:\d\d(.\d+)?\s(\+|-)\d\d\d\d/.exec(s);
125 if (t) {
126 s = s.substring(0, t.index).trim();
127 }
128 if (s.match(/^(a|b)\//)) {
129 return s.substr(2);
130 } else {
131 return s;
132 }
133 };
134
135}).call(this);