Skip to content

Commit 0df268d

Browse files
authored
fix: properly check for diff with multiple files from overwrite:false (#442)
1 parent 2eca24b commit 0df268d

File tree

4 files changed

+44
-16
lines changed

4 files changed

+44
-16
lines changed

lib/check/check-apply.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +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 }
16-
const [add, update] = partition(await parseEach(dir, addFiles, options, parseOpts, async (p) => {
15+
const [add, update] = partition(await parseEach(dir, addFiles, options, {}, async (p) => {
1716
const diff = await p.applyDiff()
1817
const target = rel(p.target)
1918
if (diff === null) {

lib/util/files.js

+13-14
Original file line numberDiff line numberDiff line change
@@ -31,29 +31,28 @@ 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) => {
3535
const results = []
3636

37-
for (const [key, source] of Object.entries(files)) {
37+
for (const [key, value] of Object.entries(files)) {
3838
// remove any false values first since that means those targets are skipped
39-
if (source === false) {
39+
if (value === false) {
4040
continue
4141
}
4242

4343
// target paths need to be joined with dir and templated
4444
const target = join(dir, template(key, options))
4545

46-
if (Array.isArray(source)) {
47-
// 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]))
54-
} else {
55-
results.push([target, source])
56-
}
46+
// Allow an array of values to merge into a single source to be
47+
// applied or diffed against the target. This is how overwrite:false
48+
// works and they are merged.
49+
const source = Array.isArray(value)
50+
? value.reduce((acc, { file, ...rest }) => {
51+
acc.file.push(file)
52+
return Object.assign(acc, rest)
53+
}, { file: [] }) : value
54+
55+
results.push([target, source])
5756
}
5857

5958
return results

lib/util/parser.js

+9
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

+21
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)