Skip to content

Commit

Permalink
added color support
Browse files Browse the repository at this point in the history
  • Loading branch information
ruyadorno committed May 19, 2020
1 parent 41d9056 commit 0720227
Showing 1 changed file with 66 additions and 21 deletions.
87 changes: 66 additions & 21 deletions lib/diff.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const fs = require('fs')
const { EOL } = require('os')
const { promisify } = require('util')
const ansi = require('ansi-styles')
const Arborist = require('@npmcli/arborist')
const jsDiff = require('diff')
const pacote = require('pacote')
Expand Down Expand Up @@ -50,6 +52,8 @@ const getMime = () => {
'patents',
'readme',
'ts',
'yml',
'yaml',
'flow'
], 'text/plain')

Expand Down Expand Up @@ -112,7 +116,34 @@ const untar = ({ files, item, prefix, opts, refs }) =>
.end(item)
})

const printDiff = ({ files, refs, versions }) => {
const colorizeDiff = ({ res, headerLength }) => {
const colors = {
charsRemoved: ansi.bgRed,
charsAdded: ansi.bgGreen,
removed: ansi.red,
added: ansi.green,
header: ansi.yellow,
section: ansi.magenta
}
const colorize = (str, colorId) => {
var { open, close } = colors[colorId]
// avoid highlighting the "\n" (would highlight till the end of the line)
return str.replace(/[^\n\r]+/g, open + '$&' + close)
}

// this RegExp will include all the `\n` chars into the lines, easier to join
const lines = res.split(/^/m)

const start = colorize(lines.slice(0, headerLength || 2).join(''), 'header')
const end = lines.slice(headerLength || 2).join('')
.replace(/^-.*/gm, colorize('$&', 'removed'))
.replace(/^\+.*/gm, colorize('$&', 'added'))
.replace(/^@@.+@@/gm, colorize('$&', 'section'))

return start + end
}

const printDiff = ({ files, opts, refs, versions }) => {
for (const filename of files.values()) {
const names = {
a: `a/${filename}`,
Expand All @@ -135,9 +166,31 @@ const printDiff = ({ files, refs, versions }) => {

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

let res
let res = ''
let headerLength = 0
const header = str => {
headerLength++
res += `${str}${EOL}`
}

// manually build a git diff-compatible header
header(`diff --git ${names.a} ${names.b}`)
if (modes.a === modes.b) {
fileMode = filenames.a.mode
} else {
if (modes.a && modes.b) {
header(`old mode ${modes.a}`)
header(`new mode ${modes.b}`)
} else if (modes.a && !modes.b) {
header(`deleted file mode ${modes.a}`)
} else if (!modes.a && modes.b) {
header(`new file mode ${modes.b}`)
}
}
header(`index ${versions.a}..${versions.b} ${fileMode}`)

if (diffFileType(filename)) {
res = jsDiff.createTwoFilesPatch(
res += jsDiff.createTwoFilesPatch(
names.a,
names.b,
contents.a || '',
Expand All @@ -149,27 +202,17 @@ const printDiff = ({ files, refs, versions }) => {
'===================================================================\n',
''
)
headerLength += 2
} else {
res = `--- ${names.a}\n+++ ${names.b}`
header(`--- ${names.a}`)
header(`+++ ${names.b}`)
}

output(`diff --git ${names.a} ${names.b}`)

if (modes.a === modes.b) {
fileMode = filenames.a.mode
} else {
if (modes.a && modes.b) {
output(`old mode ${modes.a}`)
output(`new mode ${modes.b}`)
} else if (modes.a && !modes.b) {
output(`deleted file mode ${modes.a}`)
} else if (!modes.a && modes.b) {
output(`new file mode ${modes.b}`)
}
}

output(`index ${versions.a}..${versions.b} ${fileMode}`)
output(res)
output(
opts.color
? colorizeDiff({ res, headerLength })
: res
)
}
}

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

printDiff({
files,
opts,
refs,
versions
})
Expand Down Expand Up @@ -293,6 +337,7 @@ const diffComparison = async (specs) => {

printDiff({
files,
opts,
refs,
versions
})
Expand Down

0 comments on commit 0720227

Please sign in to comment.