-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add overwrite false property to added files
By default template-oss allows for written files to be configured on a per-repo basis. This is helpful for different repos to create their own templated files and apply those. With this change, a repo can now set overwrite: false to a templated file and have those updates be applied after the default template-oss changes are made.
- Loading branch information
1 parent
449066e
commit 4624d9c
Showing
7 changed files
with
165 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,72 @@ | ||
const { mergeWith } = require('lodash') | ||
const { mergeWith: _mergeWith } = require('lodash') | ||
|
||
const merge = (...objects) => mergeWith({}, ...objects, (value, srcValue, key) => { | ||
if (Array.isArray(srcValue)) { | ||
// Dont merge arrays, last array wins | ||
return srcValue | ||
} | ||
}) | ||
// Adapted from https://github.com/lodash/lodash/issues/3901#issuecomment-517983996 | ||
// Allows us to keep track of the current key during each merge so a customizer | ||
// can make different merges based on the parent keys. | ||
const mergeWith = (...args) => { | ||
const customizer = args.pop() | ||
const objects = args | ||
const sourceStack = [] | ||
const keyStack = [] | ||
return _mergeWith({}, ...objects, (value, srcValue, key, target, source) => { | ||
let currentKeys | ||
while (true) { | ||
if (!sourceStack.length) { | ||
sourceStack.push(source) | ||
keyStack.push([]) | ||
} | ||
if (source === sourceStack[sourceStack.length - 1]) { | ||
currentKeys = keyStack[keyStack.length - 1].concat(key) | ||
sourceStack.push(srcValue) | ||
keyStack.push(currentKeys) | ||
break | ||
} | ||
sourceStack.pop() | ||
keyStack.pop() | ||
} | ||
// Remove the last key since that is the current one and reverse the whole | ||
// array so that the first entry is the parent, 2nd grandparent, etc | ||
return customizer(value, srcValue, key, target, source, currentKeys.slice(0, -1).reverse()) | ||
}) | ||
} | ||
|
||
// Create a merge function that will run a set of customizer functions | ||
const mergeWithCustomizers = (...customizers) => { | ||
return (...objects) => mergeWith({}, ...objects, (...args) => { | ||
for (const customizer of customizers) { | ||
const result = customizer(...args) | ||
// undefined means the customizer will defer to the next one | ||
// the default behavior of undefined in lodash is to merge | ||
if (result !== undefined) { | ||
return result | ||
} | ||
} | ||
}) | ||
} | ||
|
||
const mergeWithArrays = (...keys) => | ||
(...objects) => mergeWith({}, ...objects, (value, srcValue, key) => { | ||
const customizers = { | ||
// Dont merge arrays, last array wins | ||
overwriteArrays: (value, srcValue) => { | ||
if (Array.isArray(srcValue)) { | ||
return srcValue | ||
} | ||
}, | ||
// Merge arrays if their key matches one of the passed in keys | ||
mergeArrays: (...keys) => (value, srcValue, key) => { | ||
if (Array.isArray(srcValue)) { | ||
if (keys.includes(key)) { | ||
return (Array.isArray(value) ? value : []).concat(srcValue) | ||
} | ||
return srcValue | ||
} | ||
}) | ||
}, | ||
} | ||
|
||
module.exports = merge | ||
module.exports.withArrays = mergeWithArrays | ||
module.exports = { | ||
// default merge is to overwrite arrays | ||
merge: mergeWithCustomizers(customizers.overwriteArrays), | ||
mergeWithArrays: (...keys) => mergeWithCustomizers(customizers.mergeArrays(...keys)), | ||
mergeWithCustomizers, | ||
mergeWith, | ||
customizers, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
const t = require('tap') | ||
const setup = require('../setup.js') | ||
|
||
t.test('json merge', async (t) => { | ||
const s = await setup(t, { | ||
ok: true, | ||
package: { | ||
templateOSS: { | ||
content: 'content', | ||
}, | ||
}, | ||
testdir: { | ||
content: { | ||
'index.js': `module.exports=${JSON.stringify({ | ||
rootModule: { | ||
add: { | ||
'package.json': { | ||
file: 'more-package.json', | ||
overwrite: false, | ||
}, | ||
}, | ||
}, | ||
})}`, | ||
'more-package.json': JSON.stringify({ | ||
scripts: { | ||
test: 'tap test/', | ||
}, | ||
}), | ||
}, | ||
}, | ||
}) | ||
|
||
await s.apply() | ||
|
||
const pkg = await s.readJson('package.json') | ||
t.equal(pkg.scripts.test, 'tap test/') | ||
t.equal(pkg.scripts.snap, 'tap') | ||
|
||
t.strictSame(await s.check(), []) | ||
}) |