From 7e4fee7268c96d026380f1cd47de096012ea7cf5 Mon Sep 17 00:00:00 2001 From: ylemkimon Date: Sat, 23 Oct 2021 16:41:36 +0900 Subject: [PATCH] feat(reify): add an ability to add a hook --- workspaces/arborist/README.md | 6 ++++++ workspaces/arborist/lib/arborist/reify.js | 7 +++++++ .../tap-snapshots/test/arborist/reify.js.test.cjs | 10 ++++++++++ workspaces/arborist/test/arborist/reify.js | 13 +++++++++++++ 4 files changed, 36 insertions(+) diff --git a/workspaces/arborist/README.md b/workspaces/arborist/README.md index 8722b7a43cc2f..2a54427da20c2 100644 --- a/workspaces/arborist/README.md +++ b/workspaces/arborist/README.md @@ -110,6 +110,12 @@ arb.reify({ // write the lockfile(s) back to disk, and package.json with any updates // defaults to 'true' save: true, + + // experimental hooks + hooks: { + // hook that runs after building the idealTree but before saving it + [Symbol.for('beforeReify')]: Arborist => ... + } }).then(() => { // node modules has been written to match the idealTree }) diff --git a/workspaces/arborist/lib/arborist/reify.js b/workspaces/arborist/lib/arborist/reify.js index 547e54ac37670..b83ae7c5b30d7 100644 --- a/workspaces/arborist/lib/arborist/reify.js +++ b/workspaces/arborist/lib/arborist/reify.js @@ -99,6 +99,9 @@ const _resolvedAdd = Symbol.for('resolvedAdd') const _usePackageLock = Symbol.for('usePackageLock') const _formatPackageLock = Symbol.for('formatPackageLock') +// hooks +const _beforeReify = Symbol.for('beforeReify') + module.exports = cls => class Reifier extends cls { constructor (options) { super(options) @@ -147,6 +150,10 @@ module.exports = cls => class Reifier extends cls { process.emit('time', 'reify') await this[_validatePath]() await this[_loadTrees](options) + if (options.hooks + && typeof options.hooks[_beforeReify] === 'function') { + options.hooks[_beforeReify](this) + } await this[_diffTrees]() await this[_reifyPackages]() await this[_saveIdealTree](options) diff --git a/workspaces/arborist/tap-snapshots/test/arborist/reify.js.test.cjs b/workspaces/arborist/tap-snapshots/test/arborist/reify.js.test.cjs index 7a6a3e714ba51..15ca8b1ee8e8e 100644 --- a/workspaces/arborist/tap-snapshots/test/arborist/reify.js.test.cjs +++ b/workspaces/arborist/tap-snapshots/test/arborist/reify.js.test.cjs @@ -32358,6 +32358,16 @@ ArboristNode { } ` +exports[`test/arborist/reify.js TAP run hooks > must match snapshot 1`] = ` +ArboristNode { + "isProjectRoot": true, + "location": "", + "name": "tap-testdir-reify-run-hooks", + "packageName": "hook-test-modified", + "path": "{CWD}/test/arborist/tap-testdir-reify-run-hooks", +} +` + exports[`test/arborist/reify.js TAP running lifecycle scripts of unchanged link nodes on reify > result 1`] = ` ArboristNode { "children": Map { diff --git a/workspaces/arborist/test/arborist/reify.js b/workspaces/arborist/test/arborist/reify.js index c8c4cb137d424..f022113819fba 100644 --- a/workspaces/arborist/test/arborist/reify.js +++ b/workspaces/arborist/test/arborist/reify.js @@ -2432,3 +2432,16 @@ t.test('add local dep with existing dev + peer/optional', async t => { t.equal(tree.children.get('abbrev').resolved, 'file:../../dep', 'resolved') t.equal(tree.children.size, 1, 'children') }) + +t.test('run hooks', async t => { + const path = t.testdir({ + 'package.json': JSON.stringify({ + name: 'hook-test', + }), + }) + const tree = await reify(path, { hooks: { + [Symbol.for('beforeReify')]: (arborist) => { + arborist.idealTree.package.name = 'hook-test-modified' + } } }) + t.matchSnapshot(printTree(tree)) +})