From de2d33f3ed42e187803bdd31db4f7a12f08f353c Mon Sep 17 00:00:00 2001 From: Nathan Fritz Date: Tue, 18 Oct 2022 15:47:02 -0700 Subject: [PATCH] feat: add --install-strategy=hoisted|nested|shallow, deprecate --global-style, --legacy-bundling (#5709) BREAKING CHANGE: deprecate boolean install flags in favor of `--install-strategy` * deprecate --global-style, --global now sets --install-strategy=shallow * deprecate --legacy-bundling, now sets --install-strategy=nested --- lib/commands/dedupe.js | 3 +- lib/commands/find-dupes.js | 3 +- lib/commands/install.js | 3 +- lib/commands/link.js | 3 +- lib/commands/update.js | 3 +- lib/utils/config/definitions.js | 71 +++++++---- .../tap-snapshots/test/index.js.test.cjs | 3 +- .../test/lib/commands/config.js.test.cjs | 4 +- tap-snapshots/test/lib/docs.js.test.cjs | 116 +++++++++++------- test/lib/utils/config/definitions.js | 16 +++ .../arborist/lib/arborist/build-ideal-tree.js | 12 +- workspaces/arborist/lib/arborist/index.js | 1 + workspaces/arborist/lib/place-dep.js | 15 +-- .../test/arborist/build-ideal-tree.js | 6 +- workspaces/arborist/test/arborist/index.js | 10 +- workspaces/arborist/test/arborist/reify.js | 24 ++-- workspaces/arborist/test/place-dep.js | 13 +- 17 files changed, 193 insertions(+), 113 deletions(-) diff --git a/lib/commands/dedupe.js b/lib/commands/dedupe.js index 2cc44b2a9fb2f..0cc0e80709883 100644 --- a/lib/commands/dedupe.js +++ b/lib/commands/dedupe.js @@ -8,8 +8,9 @@ class Dedupe extends ArboristWorkspaceCmd { static description = 'Reduce duplication in the package tree' static name = 'dedupe' static params = [ - 'global-style', + 'install-strategy', 'legacy-bundling', + 'global-style', 'strict-peer-deps', 'package-lock', 'omit', diff --git a/lib/commands/find-dupes.js b/lib/commands/find-dupes.js index a9de2410ec0d7..b99ea7a14eb21 100644 --- a/lib/commands/find-dupes.js +++ b/lib/commands/find-dupes.js @@ -5,8 +5,9 @@ class FindDupes extends ArboristWorkspaceCmd { static description = 'Find duplication in the package tree' static name = 'find-dupes' static params = [ - 'global-style', + 'install-strategy', 'legacy-bundling', + 'global-style', 'strict-peer-deps', 'package-lock', 'omit', diff --git a/lib/commands/install.js b/lib/commands/install.js index ecc0727a2ef7c..512226c6b5a05 100644 --- a/lib/commands/install.js +++ b/lib/commands/install.js @@ -20,8 +20,9 @@ class Install extends ArboristWorkspaceCmd { 'save', 'save-exact', 'global', - 'global-style', + 'install-strategy', 'legacy-bundling', + 'global-style', 'omit', 'strict-peer-deps', 'package-lock', diff --git a/lib/commands/link.js b/lib/commands/link.js index c9169edc9e5c3..5af2c7c269f8f 100644 --- a/lib/commands/link.js +++ b/lib/commands/link.js @@ -22,8 +22,9 @@ class Link extends ArboristWorkspaceCmd { 'save', 'save-exact', 'global', - 'global-style', + 'install-strategy', 'legacy-bundling', + 'global-style', 'strict-peer-deps', 'package-lock', 'omit', diff --git a/lib/commands/update.js b/lib/commands/update.js index ca80d61537e70..be9d35093d43b 100644 --- a/lib/commands/update.js +++ b/lib/commands/update.js @@ -14,8 +14,9 @@ class Update extends ArboristWorkspaceCmd { static params = [ 'save', 'global', - 'global-style', + 'install-strategy', 'legacy-bundling', + 'global-style', 'omit', 'strict-peer-deps', 'package-lock', diff --git a/lib/utils/config/definitions.js b/lib/utils/config/definitions.js index c9d76249c7b1e..b8a7ec2d91de4 100644 --- a/lib/utils/config/definitions.js +++ b/lib/utils/config/definitions.js @@ -823,20 +823,6 @@ define('global', { }, }) -define('global-style', { - default: false, - type: Boolean, - description: ` - Causes npm to install the package into your local \`node_modules\` folder - with the same layout it uses with the global \`node_modules\` folder. - Only your direct dependencies will show in \`node_modules\` and - everything they depend on will be flattened in their \`node_modules\` - folders. This obviously will eliminate some deduping. If used with - \`legacy-bundling\`, \`legacy-bundling\` will be preferred. - `, - flatten, -}) - // the globalconfig has its default defined outside of this module define('globalconfig', { type: path, @@ -851,6 +837,25 @@ define('globalconfig', { flatten, }) +define('global-style', { + default: false, + type: Boolean, + description: ` + Only install direct dependencies in the top level \`node_modules\`, + but hoist on deeper dependendencies. + Sets \`--install-strategy=shallow\`. + `, + deprecated: ` + This option has been deprecated in favor of \`--install-strategy=shallow\` + `, + flatten (key, obj, flatOptions) { + if (obj[key]) { + obj['install-strategy'] = 'shallow' + flatOptions.installStrategy = 'shallow' + } + }, +}) + define('heading', { default: 'npm', type: String, @@ -1076,6 +1081,21 @@ define('install-links', { flatten, }) +define('install-strategy', { + default: 'hoisted', + type: ['hoisted', 'nested', 'shallow'], + description: ` + Sets the strategy for installing packages in node_modules. + hoisted (default): Install non-duplicated in top-level, and duplicated as + necessary within directory structure. + nested: (formerly --legacy-bundling) install in place, no hoisting. + shallow (formerly --global-style) only install direct deps at top-level. + linked: (coming soon) install in node_modules/.store, link in place, + unhoisted. + `, + flatten, +}) + define('json', { default: false, type: Boolean, @@ -1111,12 +1131,21 @@ define('legacy-bundling', { default: false, type: Boolean, description: ` - Causes npm to install the package such that versions of npm prior to 1.4, - such as the one included with node 0.8, can install the package. This - eliminates all automatic deduping. If used with \`global-style\` this - option will be preferred. + Instead of hoisting package installs in \`node_modules\`, install packages + in the same manner that they are depended on. This may cause very deep + directory structures and duplicate package installs as there is no + de-duplicating. + Sets \`--install-strategy=nested\`. `, - flatten, + deprecated: ` + This option has been deprecated in favor of \`--install-strategy=nested\` + `, + flatten (key, obj, flatOptions) { + if (obj[key]) { + obj['install-strategy'] = 'nested' + flatOptions.installStrategy = 'nested' + } + }, }) define('legacy-peer-deps', { @@ -1523,8 +1552,8 @@ define('prefix', { short: 'C', default: '', defaultDescription: ` - In global mode, the folder where the node executable is installed. In - local mode, the nearest parent folder containing either a package.json + In global mode, the folder where the node executable is installed. + Otherwise, the nearest parent folder containing either a package.json file or a node_modules folder. `, description: ` diff --git a/smoke-tests/tap-snapshots/test/index.js.test.cjs b/smoke-tests/tap-snapshots/test/index.js.test.cjs index 5a08980433547..98030692de8e4 100644 --- a/smoke-tests/tap-snapshots/test/index.js.test.cjs +++ b/smoke-tests/tap-snapshots/test/index.js.test.cjs @@ -56,7 +56,8 @@ npm ERR! npm ci npm ERR! npm ERR! Options: npm ERR! [-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle] -npm ERR! [-E|--save-exact] [-g|--global] [--global-style] [--legacy-bundling] +npm ERR! [-E|--save-exact] [-g|--global] [--install-strategy ] +npm ERR! [--legacy-bundling] [--global-style] npm ERR! [--omit [--omit ...]] npm ERR! [--strict-peer-deps] [--no-package-lock] [--foreground-scripts] npm ERR! [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] diff --git a/tap-snapshots/test/lib/commands/config.js.test.cjs b/tap-snapshots/test/lib/commands/config.js.test.cjs index 9f7b31d7a94b9..4170dd9078c86 100644 --- a/tap-snapshots/test/lib/commands/config.js.test.cjs +++ b/tap-snapshots/test/lib/commands/config.js.test.cjs @@ -60,8 +60,8 @@ exports[`test/lib/commands/config.js TAP config list --json > output matches sna "git": "git", "git-tag-version": true, "global": false, - "global-style": false, "globalconfig": "{GLOBALPREFIX}/npmrc", + "global-style": false, "heading": "npm", "https-proxy": null, "if-present": false, @@ -82,6 +82,7 @@ exports[`test/lib/commands/config.js TAP config list --json > output matches sna "init.module": "{HOME}/.npm-init.js", "init.version": "1.0.0", "install-links": true, + "install-strategy": "hoisted", "key": null, "legacy-bundling": false, "legacy-peer-deps": false, @@ -234,6 +235,7 @@ init.license = "ISC" init.module = "{HOME}/.npm-init.js" init.version = "1.0.0" install-links = true +install-strategy = "hoisted" json = false key = null legacy-bundling = false diff --git a/tap-snapshots/test/lib/docs.js.test.cjs b/tap-snapshots/test/lib/docs.js.test.cjs index 81be4ec21dd49..15ceed5c16d3a 100644 --- a/tap-snapshots/test/lib/docs.js.test.cjs +++ b/tap-snapshots/test/lib/docs.js.test.cjs @@ -1034,18 +1034,6 @@ folder instead of the current working directory. See * bin files are linked to \`{prefix}/bin\` * man pages are linked to \`{prefix}/share/man\` -#### \`global-style\` - -* Default: false -* Type: Boolean - -Causes npm to install the package into your local \`node_modules\` folder with -the same layout it uses with the global \`node_modules\` folder. Only your -direct dependencies will show in \`node_modules\` and everything they depend -on will be flattened in their \`node_modules\` folders. This obviously will -eliminate some deduping. If used with \`legacy-bundling\`, \`legacy-bundling\` -will be preferred. - #### \`globalconfig\` * Default: The global --prefix setting plus 'etc/npmrc'. For example, @@ -1188,6 +1176,18 @@ When set file: protocol dependencies will be packed and installed as regular dependencies instead of creating a symlink. This option has no effect on workspaces. +#### \`install-strategy\` + +* Default: "hoisted" +* Type: "hoisted", "nested", or "shallow" + +Sets the strategy for installing packages in node_modules. hoisted +(default): Install non-duplicated in top-level, and duplicated as necessary +within directory structure. nested: (formerly --legacy-bundling) install in +place, no hoisting. shallow (formerly --global-style) only install direct +deps at top-level. linked: (coming soon) install in node_modules/.store, +link in place, unhoisted. + #### \`json\` * Default: false @@ -1215,16 +1215,6 @@ key="-----BEGIN PRIVATE KEY-----\\nXXXX\\nXXXX\\n-----END PRIVATE KEY-----" It is _not_ the path to a key file, though you can set a registry-scoped "keyfile" path like "//other-registry.tld/:keyfile=/path/to/key.pem". -#### \`legacy-bundling\` - -* Default: false -* Type: Boolean - -Causes npm to install the package such that versions of npm prior to 1.4, -such as the one included with node 0.8, can install the package. This -eliminates all automatic deduping. If used with \`global-style\` this option -will be preferred. - #### \`legacy-peer-deps\` * Default: false @@ -1483,8 +1473,8 @@ look for updates immediately even for fresh package data. #### \`prefix\` * Default: In global mode, the folder where the node executable is installed. - In local mode, the nearest parent folder containing either a package.json - file or a node_modules folder. + Otherwise, the nearest parent folder containing either a package.json file + or a node_modules folder. * Type: Path The location to install global items. If set on the command line, then it @@ -1993,6 +1983,16 @@ When set to \`dev\` or \`development\`, this is an alias for \`--include=dev\`. Alias for \`--include=dev\`. +#### \`global-style\` + +* Default: false +* Type: Boolean +* DEPRECATED: This option has been deprecated in favor of + \`--install-strategy=shallow\` + +Only install direct dependencies in the top level \`node_modules\`, but hoist +on deeper dependendencies. Sets \`--install-strategy=shallow\`. + #### \`init.author.email\` * Default: "" @@ -2041,6 +2041,18 @@ Alias for \`--init-module\` Alias for \`--init-version\` +#### \`legacy-bundling\` + +* Default: false +* Type: Boolean +* DEPRECATED: This option has been deprecated in favor of + \`--install-strategy=nested\` + +Instead of hoisting package installs in \`node_modules\`, install packages in +the same manner that they are depended on. This may cause very deep +directory structures and duplicate package installs as there is no +de-duplicating. Sets \`--install-strategy=nested\`. + #### \`only\` * Default: null @@ -2139,8 +2151,8 @@ Array [ "git", "git-tag-version", "global", - "global-style", "globalconfig", + "global-style", "heading", "https-proxy", "if-present", @@ -2161,6 +2173,7 @@ Array [ "init.module", "init.version", "install-links", + "install-strategy", "json", "key", "legacy-bundling", @@ -2290,8 +2303,8 @@ Array [ "git", "git-tag-version", "global", - "global-style", "globalconfig", + "global-style", "heading", "https-proxy", "if-present", @@ -2300,6 +2313,7 @@ Array [ "include-staged", "include-workspace-root", "install-links", + "install-strategy", "json", "key", "legacy-bundling", @@ -2589,7 +2603,8 @@ npm ci Options: [-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle] -[-E|--save-exact] [-g|--global] [--global-style] [--legacy-bundling] +[-E|--save-exact] [-g|--global] [--install-strategy ] +[--legacy-bundling] [--global-style] [--omit [--omit ...]] [--strict-peer-deps] [--no-package-lock] [--foreground-scripts] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] @@ -2609,8 +2624,9 @@ aliases: clean-install, ic, install-clean, isntall-clean #### \`save\` #### \`save-exact\` #### \`global\` -#### \`global-style\` +#### \`install-strategy\` #### \`legacy-bundling\` +#### \`global-style\` #### \`omit\` #### \`strict-peer-deps\` #### \`package-lock\` @@ -2685,7 +2701,8 @@ Usage: npm dedupe Options: -[--global-style] [--legacy-bundling] [--strict-peer-deps] [--no-package-lock] +[--install-strategy ] [--legacy-bundling] +[--global-style] [--strict-peer-deps] [--no-package-lock] [--omit [--omit ...]] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace [-w|--workspace ...]] @@ -2701,8 +2718,9 @@ npm dedupe alias: ddp \`\`\` -#### \`global-style\` +#### \`install-strategy\` #### \`legacy-bundling\` +#### \`global-style\` #### \`strict-peer-deps\` #### \`package-lock\` #### \`omit\` @@ -2946,7 +2964,8 @@ Usage: npm find-dupes Options: -[--global-style] [--legacy-bundling] [--strict-peer-deps] [--no-package-lock] +[--install-strategy ] [--legacy-bundling] +[--global-style] [--strict-peer-deps] [--no-package-lock] [--omit [--omit ...]] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [-w|--workspace [-w|--workspace ...]] @@ -2958,8 +2977,9 @@ Run "npm help find-dupes" for more info npm find-dupes \`\`\` -#### \`global-style\` +#### \`install-strategy\` #### \`legacy-bundling\` +#### \`global-style\` #### \`strict-peer-deps\` #### \`package-lock\` #### \`omit\` @@ -3117,7 +3137,8 @@ npm install [ ...] Options: [-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle] -[-E|--save-exact] [-g|--global] [--global-style] [--legacy-bundling] +[-E|--save-exact] [-g|--global] [--install-strategy ] +[--legacy-bundling] [--global-style] [--omit [--omit ...]] [--strict-peer-deps] [--no-package-lock] [--foreground-scripts] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] @@ -3137,8 +3158,9 @@ aliases: add, i, in, ins, inst, insta, instal, isnt, isnta, isntal, isntall #### \`save\` #### \`save-exact\` #### \`global\` -#### \`global-style\` +#### \`install-strategy\` #### \`legacy-bundling\` +#### \`global-style\` #### \`omit\` #### \`strict-peer-deps\` #### \`package-lock\` @@ -3162,7 +3184,8 @@ npm install-ci-test Options: [-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle] -[-E|--save-exact] [-g|--global] [--global-style] [--legacy-bundling] +[-E|--save-exact] [-g|--global] [--install-strategy ] +[--legacy-bundling] [--global-style] [--omit [--omit ...]] [--strict-peer-deps] [--no-package-lock] [--foreground-scripts] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] @@ -3182,8 +3205,9 @@ alias: cit #### \`save\` #### \`save-exact\` #### \`global\` -#### \`global-style\` +#### \`install-strategy\` #### \`legacy-bundling\` +#### \`global-style\` #### \`omit\` #### \`strict-peer-deps\` #### \`package-lock\` @@ -3207,7 +3231,8 @@ npm install-test [ ...] Options: [-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle] -[-E|--save-exact] [-g|--global] [--global-style] [--legacy-bundling] +[-E|--save-exact] [-g|--global] [--install-strategy ] +[--legacy-bundling] [--global-style] [--omit [--omit ...]] [--strict-peer-deps] [--no-package-lock] [--foreground-scripts] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] @@ -3227,8 +3252,9 @@ alias: it #### \`save\` #### \`save-exact\` #### \`global\` -#### \`global-style\` +#### \`install-strategy\` #### \`legacy-bundling\` +#### \`global-style\` #### \`omit\` #### \`strict-peer-deps\` #### \`package-lock\` @@ -3252,8 +3278,8 @@ npm link [] Options: [-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle] -[-E|--save-exact] [-g|--global] [--global-style] [--legacy-bundling] -[--strict-peer-deps] [--no-package-lock] +[-E|--save-exact] [-g|--global] [--install-strategy ] +[--legacy-bundling] [--global-style] [--strict-peer-deps] [--no-package-lock] [--omit [--omit ...]] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace [-w|--workspace ...]] @@ -3272,8 +3298,9 @@ alias: ln #### \`save\` #### \`save-exact\` #### \`global\` -#### \`global-style\` +#### \`install-strategy\` #### \`legacy-bundling\` +#### \`global-style\` #### \`strict-peer-deps\` #### \`package-lock\` #### \`omit\` @@ -4124,8 +4151,8 @@ npm update [...] Options: [-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle] -[-g|--global] [--global-style] [--legacy-bundling] -[--omit [--omit ...]] +[-g|--global] [--install-strategy ] [--legacy-bundling] +[--global-style] [--omit [--omit ...]] [--strict-peer-deps] [--no-package-lock] [--foreground-scripts] [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] [-w|--workspace [-w|--workspace ...]] @@ -4143,8 +4170,9 @@ aliases: up, upgrade, udpate #### \`save\` #### \`global\` -#### \`global-style\` +#### \`install-strategy\` #### \`legacy-bundling\` +#### \`global-style\` #### \`omit\` #### \`strict-peer-deps\` #### \`package-lock\` diff --git a/test/lib/utils/config/definitions.js b/test/lib/utils/config/definitions.js index 07d029c0290bb..21eba1617affd 100644 --- a/test/lib/utils/config/definitions.js +++ b/test/lib/utils/config/definitions.js @@ -908,3 +908,19 @@ t.test('loglevel silent', t => { t.match(flat.silent, true, 'flattens to assign silent') t.end() }) + +t.test('remap legacy-bundling', t => { + const obj = { 'legacy-bundling': true } + const flat = {} + mockDefs()['legacy-bundling'].flatten('legacy-bundling', obj, flat) + t.strictSame(flat, { installStrategy: 'nested' }) + t.end() +}) + +t.test('remap global-style', t => { + const obj = { 'global-style': true } + const flat = {} + mockDefs()['global-style'].flatten('global-style', obj, flat) + t.strictSame(flat, { installStrategy: 'shallow' }) + t.end() +}) diff --git a/workspaces/arborist/lib/arborist/build-ideal-tree.js b/workspaces/arborist/lib/arborist/build-ideal-tree.js index cc873dca9f676..3b502acd10287 100644 --- a/workspaces/arborist/lib/arborist/build-ideal-tree.js +++ b/workspaces/arborist/lib/arborist/build-ideal-tree.js @@ -46,7 +46,6 @@ const _flagsSuspect = Symbol.for('flagsSuspect') const _workspaces = Symbol.for('workspaces') const _prune = Symbol('prune') const _preferDedupe = Symbol('preferDedupe') -const _legacyBundling = Symbol('legacyBundling') const _parseSettings = Symbol('parseSettings') const _initTree = Symbol('initTree') const _applyUserRequests = Symbol('applyUserRequests') @@ -77,7 +76,7 @@ const _loadFailures = Symbol('loadFailures') const _pruneFailedOptional = Symbol('pruneFailedOptional') const _linkNodes = Symbol('linkNodes') const _follow = Symbol('follow') -const _globalStyle = Symbol('globalStyle') +const _installStrategy = Symbol('installStrategy') const _globalRootNode = Symbol('globalRootNode') const _usePackageLock = Symbol.for('usePackageLock') const _rpcache = Symbol.for('realpathCache') @@ -112,7 +111,7 @@ module.exports = cls => class IdealTreeBuilder extends cls { follow = false, force = false, global = false, - globalStyle = false, + installStrategy = 'hoisted', idealTree = null, includeWorkspaceRoot = false, installLinks = false, @@ -132,7 +131,7 @@ module.exports = cls => class IdealTreeBuilder extends cls { this[_usePackageLock] = packageLock this[_global] = !!global - this[_globalStyle] = this[_global] || globalStyle + this[_installStrategy] = global ? 'shallow' : installStrategy this[_follow] = !!follow if (this[_workspaces].length && this[_global]) { @@ -141,7 +140,6 @@ module.exports = cls => class IdealTreeBuilder extends cls { this[_explicitRequests] = new Set() this[_preferDedupe] = false - this[_legacyBundling] = false this[_depsSeen] = new Set() this[_depsQueue] = [] this[_currentDep] = null @@ -250,7 +248,6 @@ module.exports = cls => class IdealTreeBuilder extends cls { this[_complete] = !!options.complete this[_preferDedupe] = !!options.preferDedupe - this[_legacyBundling] = !!options.legacyBundling // validates list of update names, they must // be dep names only, no semver ranges are supported @@ -950,11 +947,10 @@ This is a one-time fix-up, please be patient... auditReport: this.auditReport, force: this[_force], preferDedupe: this[_preferDedupe], - legacyBundling: this[_legacyBundling], strictPeerDeps: this[_strictPeerDeps], installLinks: this.installLinks, legacyPeerDeps: this.legacyPeerDeps, - globalStyle: this[_globalStyle], + installStrategy: this[_installStrategy], })) const promises = [] diff --git a/workspaces/arborist/lib/arborist/index.js b/workspaces/arborist/lib/arborist/index.js index 6bffd843186ea..091e0b46574cc 100644 --- a/workspaces/arborist/lib/arborist/index.js +++ b/workspaces/arborist/lib/arborist/index.js @@ -76,6 +76,7 @@ class Arborist extends Base { workspacesEnabled: options.workspacesEnabled !== false, replaceRegistryHost: options.replaceRegistryHost, lockfileVersion: lockfileVersion(options.lockfileVersion), + installStrategy: options.global ? 'shallow' : (options.installStrategy ? options.installStrategy : 'hoisted'), } this.replaceRegistryHost = this.options.replaceRegistryHost = (!this.options.replaceRegistryHost || this.options.replaceRegistryHost === 'npmjs') ? diff --git a/workspaces/arborist/lib/place-dep.js b/workspaces/arborist/lib/place-dep.js index 9d84d3f1b08a5..2e37e35f6014b 100644 --- a/workspaces/arborist/lib/place-dep.js +++ b/workspaces/arborist/lib/place-dep.js @@ -43,11 +43,10 @@ class PlaceDep { explicitRequest, updateNames, auditReport, - legacyBundling, strictPeerDeps, installLinks, legacyPeerDeps, - globalStyle, + installStrategy, } = parent || options Object.assign(this, { preferDedupe, @@ -55,11 +54,10 @@ class PlaceDep { explicitRequest, updateNames, auditReport, - legacyBundling, strictPeerDeps, installLinks, + installStrategy, legacyPeerDeps, - globalStyle, }) this.children = [] @@ -78,10 +76,9 @@ class PlaceDep { edge, dep, preferDedupe, - globalStyle, - legacyBundling, explicitRequest, updateNames, + installStrategy, checks, } = this @@ -170,13 +167,13 @@ class PlaceDep { // nest packages like npm v1 and v2 // very disk-inefficient - if (legacyBundling) { + if (installStrategy === 'nested') { break } // when installing globally, or just in global style, we never place // deps above the first level. - if (globalStyle) { + if (installStrategy === 'shallow') { const rp = target.resolveParent if (rp && rp.isProjectRoot) { break @@ -463,7 +460,7 @@ class PlaceDep { // prune all the nodes in a branch of the tree that can be safely removed // This is only the most basic duplication detection; it finds if there // is another satisfying node further up the tree, and if so, dedupes. - // Even in legacyBundling mode, we do this amount of deduplication. + // Even in installStategy is nested, we do this amount of deduplication. pruneDedupable (node, descend = true) { if (node.canDedupe(this.preferDedupe)) { // gather up all deps that have no valid edges in from outside diff --git a/workspaces/arborist/test/arborist/build-ideal-tree.js b/workspaces/arborist/test/arborist/build-ideal-tree.js index 15378964b3eca..10a291065dfc2 100644 --- a/workspaces/arborist/test/arborist/build-ideal-tree.js +++ b/workspaces/arborist/test/arborist/build-ideal-tree.js @@ -364,7 +364,7 @@ t.test('dedupe example - deduped because preferDedupe=true', t => { t.test('dedupe example - nested because legacyBundling=true', t => { const path = resolve(fixtures, 'dedupe-tests') return t.resolveMatchSnapshot(printIdeal(path, { - legacyBundling: true, + installStrategy: 'nested', preferDedupe: true, })) }) @@ -607,7 +607,7 @@ t.test('link dep within node_modules and outside root', t => { }) t.test('global style', t => t.resolveMatchSnapshot(printIdeal(t.testdir(), { - globalStyle: true, + installStrategy: 'shallow', add: ['rimraf'], }))) @@ -1136,7 +1136,7 @@ t.test('resolve links in global mode', async t => { t.test('dont get confused if root matches duped metadep', async t => { const path = resolve(fixtures, 'test-root-matches-metadep') - const arb = new Arborist({ path, ...OPT }) + const arb = new Arborist({ path, installStrategy: 'hoisted', ...OPT }) const tree = await arb.buildIdealTree() t.matchSnapshot(printTree(tree)) }) diff --git a/workspaces/arborist/test/arborist/index.js b/workspaces/arborist/test/arborist/index.js index 7f69eb36ef74f..88da04b94ffed 100644 --- a/workspaces/arborist/test/arborist/index.js +++ b/workspaces/arborist/test/arborist/index.js @@ -213,7 +213,7 @@ t.test('excludeSet includes nonworkspace metadeps', async t => { spec: 'file:pkgs/b', }) - const arb = new Arborist() + const arb = new Arborist({}) const filter = arb.excludeWorkspacesDependencySet(tree) t.equal(filter.size, 3) @@ -245,3 +245,11 @@ t.test('valid replaceRegistryHost values', t => { t.equal(new Arborist({ replaceRegistryHost: 'never' }).options.replaceRegistryHost, 'never') t.end() }) + +t.test('valid global/installStrategy values', t => { + t.equal(new Arborist({ global: true }).options.installStrategy, 'shallow') + t.equal(new Arborist({ global: false }).options.installStrategy, 'hoisted') + t.equal(new Arborist({}).options.installStrategy, 'hoisted') + t.equal(new Arborist({ installStrategy: 'hoisted' }).options.installStrategy, 'hoisted') + t.end() +}) diff --git a/workspaces/arborist/test/arborist/reify.js b/workspaces/arborist/test/arborist/reify.js index d3c9fa12b40ca..0c68bdd4dd748 100644 --- a/workspaces/arborist/test/arborist/reify.js +++ b/workspaces/arborist/test/arborist/reify.js @@ -515,7 +515,7 @@ t.test('update a child of a node with bundled deps', t => { const path = fixture(t, 'testing-bundledeps-legacy-bundling') return t.resolveMatchSnapshot(printReified(path, { update: ['@isaacs/testing-bundledeps-c'], - legacyBundling: true, + installStrategy: 'nested', })) }) @@ -604,7 +604,7 @@ t.test('warn on reifying deprecated dependency', t => { t.test('rollbacks', { buffered: false }, t => { t.test('fail retiring shallow nodes', t => { const path = fixture(t, 'testing-bundledeps-3') - const a = newArb({ path, legacyBundling: true }) + const a = newArb({ path, installStrategy: 'nested' }) const expect = new Error('rename fail') const kRenamePath = Symbol.for('renamePath') const renamePath = a[kRenamePath] @@ -631,7 +631,7 @@ t.test('rollbacks', { buffered: false }, t => { t.test('fail retiring nodes because rm fails after eexist', t => { const path = fixture(t, 'testing-bundledeps-3') - const a = newArb({ path, legacyBundling: true }) + const a = newArb({ path, installStrategy: 'nested' }) const eexist = new Error('rename fail') eexist.code = 'EEXIST' const kRenamePath = Symbol.for('renamePath') @@ -668,7 +668,7 @@ t.test('rollbacks', { buffered: false }, t => { t.test('fail retiring node, but then rm fixes it', async t => { const path = fixture(t, 'testing-bundledeps-3') - const a = newArb({ path, legacyBundling: true }) + const a = newArb({ path, installStrategy: 'nested' }) const eexist = new Error('rename fail') eexist.code = 'EEXIST' const kRenamePath = Symbol.for('renamePath') @@ -696,7 +696,7 @@ t.test('rollbacks', { buffered: false }, t => { t.test('fail creating sparse tree', t => { t.teardown(() => failMkdir = null) const path = fixture(t, 'testing-bundledeps-3') - const a = newArb({ path, legacyBundling: true }) + const a = newArb({ path, installStrategy: 'nested' }) const kCreateST = Symbol.for('createSparseTree') const createSparseTree = a[kCreateST] a[kCreateST] = () => { @@ -721,7 +721,7 @@ t.test('rollbacks', { buffered: false }, t => { failMkdir = null failRm = null const path = fixture(t, 'testing-bundledeps-3') - const a = newArb({ path, legacyBundling: true }) + const a = newArb({ path, installStrategy: 'nested' }) const kCreateST = Symbol.for('createSparseTree') const kRetireShallowNodes = Symbol.for('retireShallowNodes') @@ -769,7 +769,7 @@ t.test('rollbacks', { buffered: false }, t => { t.test('fail loading shrinkwraps and updating trees', t => { const path = fixture(t, 'shrinkwrapped-dep-no-lock-empty') - const a = newArb({ path, legacyBundling: true }) + const a = newArb({ path, installStrategy: 'nested' }) const kLoadSW = Symbol.for('loadShrinkwrapsAndUpdateTrees') const loadShrinkwrapsAndUpdateTrees = a[kLoadSW] a[kLoadSW] = seen => { @@ -795,7 +795,7 @@ t.test('rollbacks', { buffered: false }, t => { t.test('fail loading bundles and updating trees', t => { const path = fixture(t, 'two-bundled-deps') - const a = newArb({ path, legacyBundling: true }) + const a = newArb({ path, installStrategy: 'nested' }) const kLoadBundles = Symbol.for('loadBundlesAndUpdateTrees') const loadBundlesAndUpdateTrees = a[kLoadBundles] a[kLoadBundles] = (depth, bundlesByDepth) => { @@ -813,7 +813,7 @@ t.test('rollbacks', { buffered: false }, t => { t.test('fail unpacking new modules', t => { const path = fixture(t, 'two-bundled-deps') - const a = newArb({ path, legacyBundling: true }) + const a = newArb({ path, installStrategy: 'nested' }) const kUnpack = Symbol.for('unpackNewModules') const unpackNewModules = a[kUnpack] a[kUnpack] = () => { @@ -831,7 +831,7 @@ t.test('rollbacks', { buffered: false }, t => { t.test('fail moving back retired unchanged', t => { const path = fixture(t, 'testing-bundledeps-3') - const a = newArb({ path, legacyBundling: true }) + const a = newArb({ path, installStrategy: 'nested' }) const kMoveback = Symbol.for('moveBackRetiredUnchanged') const moveBackRetiredUnchanged = a[kMoveback] @@ -859,7 +859,7 @@ t.test('rollbacks', { buffered: false }, t => { t.test('fail removing retired and deleted nodes', t => { const path = fixture(t, 'testing-bundledeps-3') - const a = newArb({ path, legacyBundling: true }) + const a = newArb({ path, installStrategy: 'nested' }) const kRemove = Symbol.for('removeTrash') const removeRetiredAndDeletedNodes = a[kRemove] a[kRemove] = () => { @@ -1123,7 +1123,7 @@ t.test('global style', t => { const rbinPart = '.bin/rimraf' + (process.platform === 'win32' ? '.cmd' : '') const rbin = resolve(nm, rbinPart) - return reify(path, { add: ['rimraf@2'], globalStyle: true }) + return reify(path, { add: ['rimraf@2'], installStrategy: 'shallow' }) .then(() => fs.statSync(rbin)) .then(() => t.strictSame(fs.readdirSync(nm).sort(), ['.bin', '.package-lock.json', 'rimraf'])) }) diff --git a/workspaces/arborist/test/place-dep.js b/workspaces/arborist/test/place-dep.js index 418d22884ca17..292a2c8e23907 100644 --- a/workspaces/arborist/test/place-dep.js +++ b/workspaces/arborist/test/place-dep.js @@ -39,14 +39,12 @@ t.test('placement tests', t => { updateNames = [], // an audit report, telling us which nodes are vulnerable auditReport = null, - // --legacy-bundling set? - legacyBundling = false, // --strict-peer-deps set? strictPeerDeps = false, // --legacy-peer-deps set? legacyPeerDeps = false, // installing with --global or --global-style? - globalStyle = false, + installStrategy = 'hoisted', } = options const node = tree.inventory.get(nodeLoc) @@ -80,10 +78,9 @@ t.test('placement tests', t => { explicitRequest, updateNames, auditReport, - legacyBundling, strictPeerDeps, legacyPeerDeps, - globalStyle, + installStrategy, }) } @@ -271,7 +268,7 @@ t.test('placement tests', t => { }), dep: new Node({ pkg: { name: 'bar', version: '1.0.0' } }), nodeLoc: 'node_modules/foo', - legacyBundling: true, + installStrategy: 'nested', test: (t, tree) => { const foobar = tree.children.get('foo').resolve('bar') t.equal(foobar.location, 'node_modules/foo/node_modules/bar') @@ -291,7 +288,7 @@ t.test('placement tests', t => { }), dep: new Node({ pkg: { name: 'bar', version: '1.0.0' } }), nodeLoc: 'node_modules/foo', - globalStyle: true, + installStrategy: 'shallow', test: (t, tree) => { const foobar = tree.children.get('foo').resolve('bar') t.equal(foobar.location, 'node_modules/foo/node_modules/bar') @@ -323,7 +320,7 @@ t.test('placement tests', t => { }), dep: new Node({ pkg: { name: 'baz', version: '1.0.0' } }), nodeLoc: 'node_modules/foo/node_modules/bar', - globalStyle: true, + installStrategy: 'shallow', test: (t, tree) => { const foobar = tree.children.get('foo').resolve('bar') const foobarbaz = foobar.resolve('baz')