UNPKG

4.01 kBJavaScriptView Raw
1var check = require('check-more-types')
2var moment = require('moment')
3var spawn = require('child_process').spawn
4var path = require('path')
5var getGitRootFolder = require('./repo-root')
6var debug = require('debug')('ggit')
7
8// returns commits in reverse chronological order
9function gitLog (filename, commits, cb, err, rootFolder) {
10 debug('gitLog, err?', err)
11
12 if (err) {
13 throw err
14 }
15 check.maybe.string(filename, 'missing filename')
16 check.verify.positiveNumber(commits, 'invalid number of commits', commits)
17 check.verify.fn(cb, 'callback should be a function')
18
19 // use -n <number> to limit history
20 // oe --since <date>
21 // var args = ['log', '--no-decorate', '-n ' + commits];
22 var args = ['log', '--name-status', '-n ' + commits]
23 debug('gitLog args', args)
24
25 if (filename) {
26 debug('gitLog uses filename', filename)
27 check.verify.string(rootFolder, 'could not find git root folder')
28 rootFolder = rootFolder.trim()
29 rootFolder = rootFolder.replace(/\//g, '\\')
30
31 console.log('filename', filename)
32 console.log('repo root folder', rootFolder)
33 var workingFolder = process.cwd()
34 console.log('working folder', workingFolder)
35
36 var relativePath = path.relative(workingFolder, filename)
37 // var repoPath = path.relative(rootFolder, filename);
38 args.push(relativePath)
39 }
40
41 debug('git log command', args)
42 var git = spawn('git', args)
43
44 commits = []
45 git.stdout.setEncoding('utf-8')
46 git.stdout.on('data', function (data) {
47 data.trim()
48 // console.log('git data\n', data);
49
50 var separatedData = data.split('\ncommit ')
51 separatedData = separatedData.filter(function (str) {
52 str.trim()
53 return str && str !== '\n'
54 })
55 var info = separatedData.map(parseCommit)
56 commits = commits.concat(info)
57 })
58
59 git.stderr.setEncoding('utf-8')
60 git.stderr.on('data', function (data) {
61 if (filename) {
62 throw new Error('Could not get git log for\n' + filename + '\n' + data)
63 } else {
64 throw new Error('Could not get git log\n' + data)
65 }
66 })
67
68 git.on('exit', function () {
69 debug('returning', commits.length, 'commits')
70 cb(commits)
71 })
72}
73
74function parseCommit (data) {
75 check.verify.string(data, 'null commit data')
76 data = data.trim()
77 // console.log('parsing commit\n', data);
78 var lines = data.split('\n')
79 console.assert(lines.length > 3, 'invalid commit\n', data)
80 // console.log('commit lines\n', lines);
81 var commitLine = lines[0].trim()
82 if (commitLine.indexOf('commit ') === 0) {
83 commitLine = commitLine.substr('commit '.length)
84 }
85
86 var authorLine = lines[1].split(':')[1].trim()
87 var dateLine = lines[2]
88 dateLine = dateLine.substr(dateLine.indexOf(':') + 1)
89 dateLine = dateLine.trim()
90 // console.log(dateLine);
91
92 lines.splice(0, 3)
93 lines = lines.filter(function (str) {
94 return str
95 })
96 lines = lines.map(function (str) {
97 str = str.trim()
98 return str
99 })
100
101 var files = []
102 lines = lines.filter(function (str) {
103 // console.log('checking line', str);
104 if (
105 str.indexOf('M') === 0 ||
106 str.indexOf('A') === 0 ||
107 str.indexOf('D') === 0
108 ) {
109 files.push({
110 name: str.substr(1).trim(),
111 status: str[0]
112 })
113 return false
114 } else {
115 return true
116 }
117 })
118
119 var description = lines.join('\n')
120 return {
121 commit: '' + commitLine.trim(),
122 author: authorLine.trim(),
123 date: moment(new Date(dateLine)),
124 description: description.trim(),
125 files: files
126 }
127}
128
129function getGitLog (filename, commits, cb) {
130 if (filename) {
131 check.verify.string(filename, 'expected filename')
132 filename = path.resolve(filename)
133 console.log('fetching', commits, 'history for', filename)
134 }
135 commits = commits || 30
136 check.verify.positiveNumber(commits, 'invalid max number of commits', commits)
137 check.verify.fn(cb, 'expect callback function, not', cb)
138
139 getGitRootFolder(gitLog.bind(null, filename, commits, cb))
140}
141
142module.exports = {
143 getGitLog: getGitLog,
144 parseCommit: parseCommit
145}