UNPKG

3.96 kBJavaScriptView Raw
1var la = require('lazy-ass')
2var check = require('check-more-types')
3var exec = require('./exec')
4var log = require('debug')('ggit')
5var _ = require('lodash')
6var R = require('ramda')
7var fileContentsInRepo = require('./file-contents')
8la(
9 check.fn(fileContentsInRepo),
10 'missing file contents function',
11 fileContentsInRepo
12)
13var read = require('fs').readFileSync
14var Q = require('q')
15var repoRoot = require('./repo-root')
16var join = require('path').join
17
18var modifications = {
19 A: 'added',
20 M: 'modified',
21 C: 'copied',
22 D: 'deleted'
23}
24
25var stdoutToGrouped = require('./parse-file-status')
26
27function changedFiles (needContents) {
28 var gitCommand = _.template(
29 'git diff --name-status --diff-filter=<%= filter %>'
30 )
31 log('filter letters Added (A), Copied (C), Deleted (D), Modified (M)')
32
33 var filter = R.keys(modifications).join('')
34 var cmd = gitCommand({ filter: filter })
35 log('changed files command', cmd)
36
37 function addContents (grouped) {
38 if (!needContents) {
39 return grouped
40 }
41
42 return repoRoot()
43 .then(function (repoPath) {
44 log('repo root', repoPath)
45 return repoPath
46 })
47 .then(function (repoPath) {
48 var promise = Q.when(grouped)
49
50 _.each(grouped, function (list) {
51 la(
52 check.array(list),
53 'expected list of modifications',
54 list,
55 'in',
56 grouped
57 )
58 list.forEach(function (info) {
59 la(check.unemptyString(info.name), 'missing file name', info)
60 info.filename = join(repoPath, info.name)
61 })
62 })
63
64 _.each(grouped, function (list, modification) {
65 log('fetching contents for modification', modification)
66 la(modifications[modification], 'unknown modification', modification)
67
68 if (modification === 'M') {
69 // need both repo and local copy
70 list.forEach(function (info) {
71 info.after = read(info.filename, 'utf8')
72 promise = promise
73 .then(function () {
74 return fileContentsInRepo(
75 info.name
76 ).catch(function fileNotFound () {
77 // maybe the file was just added and then modified
78 // GIT thinks it is M, but there is no repo content yet
79 return ''
80 })
81 })
82 .then(function (contents) {
83 info.before = contents
84 return grouped
85 })
86 })
87 } else if (modification === 'A') {
88 // for added files, only grab file contents
89 list.forEach(function (info) {
90 info.after = read(info.filename, 'utf8')
91 })
92 } else if (modification === 'D') {
93 list.forEach(function (info) {
94 promise = promise
95 .then(function () {
96 return fileContentsInRepo(info.name)
97 })
98 .then(function (contents) {
99 info.before = contents
100 return grouped
101 })
102 })
103 }
104 })
105
106 return promise
107 })
108 }
109
110 // another command that gives status especially for added files
111 var secondCommand = 'git status --porcelain'
112
113 return Q.all([exec(cmd), exec(secondCommand)])
114 .spread(function (firstOutput, secondOutput) {
115 log('first output')
116 log(firstOutput)
117 log('second output')
118 log(secondOutput)
119 return firstOutput + '\n' + secondOutput
120 })
121 .then(stdoutToGrouped)
122 .then(R.tap(log))
123 .then(addContents)
124}
125
126module.exports = changedFiles
127
128if (!module.parent) {
129 ;(function showChangedFiles () {
130 var needContents = true
131 changedFiles(needContents)
132 .then(function (files) {
133 console.log('changed files in the current repo')
134 console.log(files)
135 })
136 .done()
137 })()
138}