UNPKG

2.66 kBJavaScriptView Raw
1var BlameLine = require('./blame_line').BlameLine;
2
3var Blame = exports.Blame = function(repo, file, commit, callback) {
4 var _repo = repo, _file = file, _commit = commit, _lines = [];
5
6 // Unpack parameters as commit might be null
7 var args = Array.prototype.slice.call(arguments, 2);
8 callback = args.pop();
9 var _commit = args.length ? args.shift() : null;
10
11 // Control access to internal variables
12 Object.defineProperty(this, "repo", { get: function() { return _repo; }, set: function(value) { _repo = value; }, enumerable: false});
13 Object.defineProperty(this, "file", { get: function() { return _file; }, set: function(value) { _file = value; }, enumerable: true});
14 Object.defineProperty(this, "commit", { get: function() { return _commit; }, set: function(value) { _commit = value; }, enumerable: true});
15 Object.defineProperty(this, "lines", { get: function() { return _lines; }, set: function(value) { _lines = value; }, enumerable: true});
16
17 // Load the blame object
18 load_blame(this, _repo, _file, _commit, callback);
19}
20
21// Load and parse the blame
22var load_blame = function(blame, repo, file, commit, callback) {
23 repo.git.blame({p:true}, commit, '--', file, function(err, blame_output) {
24 process_raw_blame(blame, blame_output, repo, callback)
25 });
26}
27
28// Parse the output and set all parameters on the current blame object
29var process_raw_blame = function(blame, output, repo, callback) {
30 // Cleanup the output (removing whitespace at the start and end)
31 output = output ? output.trim() : '';
32 // Set up variables
33 var lines = [], final = [];
34 var info = {}, commits = [];
35
36 var output_lines = output.split("\n");
37 for(var i = 0; i < output_lines.length; i++) {
38 var line = output_lines[i];
39 var match = line.match(/^(\w{40}) (\d+) (\d+)/);
40
41 // If we have a tab character at the start skip it
42 if(line.substr(0, 1) == "\t") {
43 lines.push(line.substring(1, line.length));
44 } else if(match) {
45 if(!commits[match[1]]) {
46 repo.commit(match[1], function(err, commit) {
47 commits[match[1]] = commit;
48 });
49 }
50 // Add the info for this line
51 info[parseInt(match[3])] = [commits[match[1]], parseInt(match[2])];
52 }
53 }
54
55 // Let's sort the content
56 var sorted_keys = Object.keys(info).sort(function(a, b) { return parseInt(a) - parseInt(b); });
57 sorted_keys.forEach(function(key) {
58 var info_object = info[key];
59 final.push(new BlameLine(key, info_object[1], info_object[0], lines[key - 1]));
60 });
61 // Assign the blame lines to the blame object and return
62 blame.lines = final;
63 callback(null, blame);
64}
\No newline at end of file