7550437c60364df04e8d92a258cf960d5a718e45.svn-base
2.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
'use strict';
const { exec } = require('child_process');
require('./logger')();
function fetchGitData(git, cb) {
if (!cb) {
throw new Error('fetchGitData requires a callback');
}
//-- Malformed/undefined git object
if (typeof git === 'undefined') {
return cb(new Error('No options passed'));
}
if (!Object.prototype.hasOwnProperty.call(git, 'head')) {
return cb(new Error('You must provide the head'));
}
if (!Object.prototype.hasOwnProperty.call(git.head, 'id')) {
return cb(new Error('You must provide the head.id'));
}
//-- Set required properties of git if they weren"t provided
if (!Object.prototype.hasOwnProperty.call(git, 'branch')) {
git.branch = '';
}
if (!Object.prototype.hasOwnProperty.call(git, 'remotes')) {
git.remotes = [];
}
//-- Assert the property types
if (typeof git.branch !== 'string') {
git.branch = '';
}
if (!(Array.isArray(git.remotes))) {
git.remotes = [];
}
//-- Use git?
exec(`git rev-parse --verify ${git.head.id}`, err => {
if (err) {
// git is not available...
git.head.author_name = git.head.author_name || 'Unknown Author';
git.head.author_email = git.head.author_email || '';
git.head.committer_name = git.head.committer_name || 'Unknown Committer';
git.head.committer_email = git.head.committer_email || '';
git.head.message = git.head.message || 'Unknown Commit Message';
return cb(null, git);
}
fetchHeadDetails(git, cb);
});
}
function fetchBranch(git, cb) {
exec('git branch', (err, branches) => {
if (err) {
return cb(err);
}
git.branch = (branches.match(/^\* (\w+)/) || [])[1];
fetchRemotes(git, cb);
});
}
const REGEX_COMMIT_DETAILS = /\nauthor (.+?) <([^>]*)>.+\ncommitter (.+?) <([^>]*)>.+[\S\s]*?\n\n(.*)/m;
function fetchHeadDetails(git, cb) {
exec(`git cat-file -p ${git.head.id}`, (err, response) => {
if (err) {
return cb(err);
}
const items = response.match(REGEX_COMMIT_DETAILS).slice(1);
const fields = ['author_name', 'author_email', 'committer_name', 'committer_email', 'message'];
fields.forEach((field, index) => {
git.head[field] = items[index];
});
if (git.branch) {
fetchRemotes(git, cb);
} else {
fetchBranch(git, cb);
}
});
}
function fetchRemotes(git, cb) {
exec('git remote -v', (err, remotes) => {
if (err) {
return cb(err);
}
const processed = {};
remotes.split('\n').forEach(remote => {
if (!/\s\(push\)$/.test(remote)) {
return;
}
remote = remote.split(/\s+/);
saveRemote(processed, git, remote[0], remote[1]);
});
cb(null, git);
});
}
function saveRemote(processed, git, name, url) {
const key = `${name}-${url}`;
if (Object.prototype.hasOwnProperty.call(processed, key)) {
return;
}
processed[key] = true;
git.remotes.push({ name, url });
}
module.exports = fetchGitData;