Skip to content

Commit cb3826c

Browse files
committed
feat: Add option "diff" to print the difference instead of the output
1 parent 29579a3 commit cb3826c

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ Usage: `jsonlint [options] [<file, directory, pattern> ...]`
122122
-E, --extensions [ext] file extensions to process for directory walk
123123
(default: ["json","JSON"])
124124
-i, --in-place overwrite the input files
125+
-j, --diff print difference instead of writing the output
125126
-k, --check check that the input is equal to the output
126127
-t, --indent [num|char] number of spaces or specific characters
127128
to use for indentation (default: 2)
@@ -187,6 +188,8 @@ The configuration is an object with the following properties, described above, w
187188
| sort-keys | sortKeys |
188189
| extensions | |
189190
| in-place | inPlace |
191+
| diff | |
192+
| check | |
190193
| indent | |
191194
| compact | |
192195
| mode | |

lib/cli.js

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const commander = require('commander')
2121
.option('-s, --sort-keys', 'sort object keys (not when prettifying)')
2222
.option('-E, --extensions [ext]', 'file extensions to process for directory walk', collectValues, ['json', 'JSON'])
2323
.option('-i, --in-place', 'overwrite the input files')
24+
.option('-j, --diff', 'print difference instead of writing the output')
2425
.option('-k, --check', 'check that the input is equal to the output')
2526
.option('-t, --indent [num|char]', 'number of spaces or specific characters to use for indentation', 2)
2627
.option('-c, --compact', 'compact error display')
@@ -87,6 +88,7 @@ if (params.config === false) {
8788
}
8889

8990
const extensions = options.extensions.map(extension => '.' + extension)
91+
let reported
9092

9193
function convertConfig (config) {
9294
const result = {}
@@ -108,10 +110,16 @@ function mergeOptions (target, ...sources) {
108110
return target
109111
}
110112

111-
function logNormalError (error, file) {
112-
if (process.exitCode > 0) {
113+
function separateBlocks() {
114+
if (reported) {
113115
console.log()
116+
} else {
117+
reported = true
114118
}
119+
}
120+
121+
function logNormalError (error, file) {
122+
separateBlocks()
115123
console.log('File:', file)
116124
console.error(error.message)
117125
}
@@ -227,6 +235,33 @@ function checkContents (file, source, parsed) {
227235
}
228236
}
229237

238+
function diffContents(file, source, parsed) {
239+
const { createTwoFilesPatch, structuredPatch } = require('diff')
240+
const compact = options.quiet || options.compact
241+
let diff, length
242+
if (compact) {
243+
diff = structuredPatch(`${file}.orig`, file, source, parsed, '', '', { context: 3 })
244+
length = diff.hunks && diff.hunks.length
245+
} else {
246+
diff = createTwoFilesPatch(`${file}.orig`, file, source, parsed, '', '', { context: 3 })
247+
length = diff.split(/\r?\n/).length - 4
248+
}
249+
if (length > 0) {
250+
if (compact) {
251+
const hunk = length === 1 ? 'hunk' : 'hunks'
252+
console.info(`${file}: ${length} ${hunk}`)
253+
} else {
254+
separateBlocks()
255+
console.log('File:', file)
256+
console.log(diff)
257+
}
258+
} else {
259+
if (compact) {
260+
console.info(`${file}: no difference`)
261+
}
262+
}
263+
}
264+
230265
function processFile (file) {
231266
file = normalize(file)
232267
if (options.logFiles) {
@@ -238,6 +273,8 @@ function processFile (file) {
238273
writeFileSync(file, ensureLineBreak(parsed, source))
239274
} else if (options.check) {
240275
checkContents(file, source, ensureLineBreak(parsed, source))
276+
} else if (options.diff) {
277+
diffContents(file, source, ensureLineBreak(parsed, source))
241278
} else {
242279
if (!(options.quiet || options.logFiles)) {
243280
console.log(parsed)
@@ -311,6 +348,8 @@ function main () {
311348
const parsed = processContents(source, file)
312349
if (options.check) {
313350
checkContents(file, source, ensureLineBreak(parsed, source))
351+
} else if (options.diff) {
352+
diffContents(file, source, ensureLineBreak(parsed, source))
314353
} else if (!(options.quiet || options.logFiles)) {
315354
console.log(parsed)
316355
}

0 commit comments

Comments
 (0)