Skip to content

Commit 0720227

Browse files
committed
added color support
1 parent 41d9056 commit 0720227

File tree

1 file changed

+66
-21
lines changed

1 file changed

+66
-21
lines changed

lib/diff.js

+66-21
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
const fs = require('fs')
2+
const { EOL } = require('os')
23
const { promisify } = require('util')
4+
const ansi = require('ansi-styles')
35
const Arborist = require('@npmcli/arborist')
46
const jsDiff = require('diff')
57
const pacote = require('pacote')
@@ -50,6 +52,8 @@ const getMime = () => {
5052
'patents',
5153
'readme',
5254
'ts',
55+
'yml',
56+
'yaml',
5357
'flow'
5458
], 'text/plain')
5559

@@ -112,7 +116,34 @@ const untar = ({ files, item, prefix, opts, refs }) =>
112116
.end(item)
113117
})
114118

115-
const printDiff = ({ files, refs, versions }) => {
119+
const colorizeDiff = ({ res, headerLength }) => {
120+
const colors = {
121+
charsRemoved: ansi.bgRed,
122+
charsAdded: ansi.bgGreen,
123+
removed: ansi.red,
124+
added: ansi.green,
125+
header: ansi.yellow,
126+
section: ansi.magenta
127+
}
128+
const colorize = (str, colorId) => {
129+
var { open, close } = colors[colorId]
130+
// avoid highlighting the "\n" (would highlight till the end of the line)
131+
return str.replace(/[^\n\r]+/g, open + '$&' + close)
132+
}
133+
134+
// this RegExp will include all the `\n` chars into the lines, easier to join
135+
const lines = res.split(/^/m)
136+
137+
const start = colorize(lines.slice(0, headerLength || 2).join(''), 'header')
138+
const end = lines.slice(headerLength || 2).join('')
139+
.replace(/^-.*/gm, colorize('$&', 'removed'))
140+
.replace(/^\+.*/gm, colorize('$&', 'added'))
141+
.replace(/^@@.+@@/gm, colorize('$&', 'section'))
142+
143+
return start + end
144+
}
145+
146+
const printDiff = ({ files, opts, refs, versions }) => {
116147
for (const filename of files.values()) {
117148
const names = {
118149
a: `a/${filename}`,
@@ -135,9 +166,31 @@ const printDiff = ({ files, refs, versions }) => {
135166

136167
if (contents.a === contents.b) continue
137168

138-
let res
169+
let res = ''
170+
let headerLength = 0
171+
const header = str => {
172+
headerLength++
173+
res += `${str}${EOL}`
174+
}
175+
176+
// manually build a git diff-compatible header
177+
header(`diff --git ${names.a} ${names.b}`)
178+
if (modes.a === modes.b) {
179+
fileMode = filenames.a.mode
180+
} else {
181+
if (modes.a && modes.b) {
182+
header(`old mode ${modes.a}`)
183+
header(`new mode ${modes.b}`)
184+
} else if (modes.a && !modes.b) {
185+
header(`deleted file mode ${modes.a}`)
186+
} else if (!modes.a && modes.b) {
187+
header(`new file mode ${modes.b}`)
188+
}
189+
}
190+
header(`index ${versions.a}..${versions.b} ${fileMode}`)
191+
139192
if (diffFileType(filename)) {
140-
res = jsDiff.createTwoFilesPatch(
193+
res += jsDiff.createTwoFilesPatch(
141194
names.a,
142195
names.b,
143196
contents.a || '',
@@ -149,27 +202,17 @@ const printDiff = ({ files, refs, versions }) => {
149202
'===================================================================\n',
150203
''
151204
)
205+
headerLength += 2
152206
} else {
153-
res = `--- ${names.a}\n+++ ${names.b}`
207+
header(`--- ${names.a}`)
208+
header(`+++ ${names.b}`)
154209
}
155210

156-
output(`diff --git ${names.a} ${names.b}`)
157-
158-
if (modes.a === modes.b) {
159-
fileMode = filenames.a.mode
160-
} else {
161-
if (modes.a && modes.b) {
162-
output(`old mode ${modes.a}`)
163-
output(`new mode ${modes.b}`)
164-
} else if (modes.a && !modes.b) {
165-
output(`deleted file mode ${modes.a}`)
166-
} else if (!modes.a && modes.b) {
167-
output(`new file mode ${modes.b}`)
168-
}
169-
}
170-
171-
output(`index ${versions.a}..${versions.b} ${fileMode}`)
172-
output(res)
211+
output(
212+
opts.color
213+
? colorizeDiff({ res, headerLength })
214+
: res
215+
)
173216
}
174217
}
175218

@@ -224,6 +267,7 @@ const diffSelf = async () => {
224267

225268
printDiff({
226269
files,
270+
opts,
227271
refs,
228272
versions
229273
})
@@ -293,6 +337,7 @@ const diffComparison = async (specs) => {
293337

294338
printDiff({
295339
files,
340+
opts,
296341
refs,
297342
versions
298343
})

0 commit comments

Comments
 (0)