Skip to content

Commit 56dbb6b

Browse files
committed
fix: properly check for diff with multiple files from overwrite:false
Fixes #437
1 parent 21c9262 commit 56dbb6b

File tree

4 files changed

+47
-8
lines changed

4 files changed

+47
-8
lines changed

lib/check/check-apply.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const run = async (type, dir, files, options) => {
1212
const { add: addFiles, rm: rmFiles } = files
1313

1414
const rm = await rmEach(dir, rmFiles, options, (f) => rel(f))
15-
const parseOpts = { allowMultipleSources: false }
15+
const parseOpts = { command: 'check' }
1616
const [add, update] = partition(await parseEach(dir, addFiles, options, parseOpts, async (p) => {
1717
const diff = await p.applyDiff()
1818
const target = rel(p.target)

lib/util/files.js

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const mergeFiles = mergeWithCustomizers((value, srcValue, key, target, source, s
3131
}
3232
}, customizers.overwriteArrays)
3333

34-
const fileEntries = (dir, files, options, { allowMultipleSources = true } = {}) => {
34+
const fileEntries = (dir, files, options, { command } = {}) => {
3535
const results = []
3636

3737
for (const [key, source] of Object.entries(files)) {
@@ -45,12 +45,21 @@ const fileEntries = (dir, files, options, { allowMultipleSources = true } = {})
4545

4646
if (Array.isArray(source)) {
4747
// When turning an object of files into all its entries, we allow
48-
// multiples when applying changes, but not when checking for changes
49-
// since earlier files would always return as needing an update. So we
50-
// either allow multiples and return the array or only return the last
51-
// source file in the array.
52-
const sources = allowMultipleSources ? source : source.slice(-1)
53-
results.push(...sources.map(s => [target, s]))
48+
// multiples when applying and checking changes. When applying we can
49+
// run them each as [[t,s1],[t,s2],...] because they can be applied in order
50+
// and get the correct result. When checking for changes we need to run them
51+
// as [target,{file:[s1,s2...]}] so that all files can be merged first and then
52+
// we can diff our target against that.
53+
if (command === 'check') {
54+
const sources = source.reduce((acc, { file, ...rest }) => {
55+
acc.file.push(file)
56+
Object.assign(acc, rest)
57+
return acc
58+
}, { file: [] })
59+
results.push([target, sources])
60+
} else {
61+
results.push(...source.map(s => [target, s]))
62+
}
5463
} else {
5564
results.push([target, source])
5665
}

lib/util/parser.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,16 @@ class Base {
6262
}
6363

6464
read (s) {
65+
if (Array.isArray(s)) {
66+
return Promise.all(s.map(f => this.read(f)))
67+
}
6568
return fs.readFile(s, { encoding: 'utf-8' })
6669
}
6770

6871
template (s) {
72+
if (Array.isArray(s)) {
73+
return Promise.all(s.map(f => this.template(f)))
74+
}
6975
return template(s, this.options)
7076
}
7177

@@ -285,6 +291,9 @@ class Json extends Base {
285291
}
286292

287293
parse (s) {
294+
if (Array.isArray(s)) {
295+
return s.map(f => this.parse(f)).reduce((a, f) => this.merge(a, f), {})
296+
}
288297
return jsonParse(s)
289298
}
290299

test/apply/overwrite-false.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,31 @@ t.test('json merge', async (t) => {
3131
})
3232

3333
await s.apply()
34+
t.strictSame(await s.check(), [])
3435

3536
const pkg = await s.readJson('package.json')
3637
t.equal(pkg.scripts.test, 'tap test/')
3738
t.equal(pkg.scripts.snap, 'tap')
3839

40+
await s.writeJson('package.json', {
41+
...pkg,
42+
author: 'What?',
43+
scripts: {
44+
...pkg.scripts,
45+
test: 'tap',
46+
},
47+
templateOSS: {
48+
...pkg.templateOSS,
49+
version: '1.0.0',
50+
},
51+
})
52+
53+
const checks = await s.check()
54+
t.equal(checks.length, 1)
55+
t.match(checks[0].title, 'package.json needs to be updated')
56+
t.match(checks[0].body[0], `"author" is "What?", expected "GitHub Inc."`)
57+
t.match(checks[0].body[0], `scripts.test" is "tap", expected "tap test/"`)
58+
59+
await s.apply()
3960
t.strictSame(await s.check(), [])
4061
})

0 commit comments

Comments
 (0)