@npmcli/arborist
Advanced tools
Comparing version 6.1.6 to 6.2.0
@@ -1235,2 +1235,3 @@ // mixin implementing the buildIdealTree method | ||
// spec is a directory, link it unless installLinks is set or it's a workspace | ||
// TODO post arborist refactor, will need to check for installStrategy=linked | ||
if (spec.type === 'directory' && (isWorkspace || !installLinks)) { | ||
@@ -1237,0 +1238,0 @@ return this[_linkFromSpec](name, spec, parent, edge) |
@@ -45,2 +45,3 @@ // The arborist manages three trees: | ||
require('./reify.js'), | ||
require('./isolated-reifier.js'), | ||
] | ||
@@ -47,0 +48,0 @@ |
@@ -92,2 +92,3 @@ // Arborist.rebuild({path = this.path}) will do all the binlinks and | ||
linkNodes, | ||
storeNodes, | ||
} = this[_retrieveNodesByType](nodes) | ||
@@ -103,2 +104,6 @@ | ||
} | ||
if (storeNodes.size) { | ||
this[_resetQueues]() | ||
await this[_build](storeNodes, { type: 'storelinks' }) | ||
} | ||
@@ -135,5 +140,8 @@ process.emit('timeEnd', 'build') | ||
const linkNodes = new Set() | ||
const storeNodes = new Set() | ||
for (const node of nodes) { | ||
if (node.isLink) { | ||
if (node.isStoreLink) { | ||
storeNodes.add(node) | ||
} else if (node.isLink) { | ||
linkNodes.add(node) | ||
@@ -160,2 +168,3 @@ } else { | ||
linkNodes, | ||
storeNodes, | ||
} | ||
@@ -162,0 +171,0 @@ } |
// mixin implementing the reify method | ||
const onExit = require('../signal-handling.js') | ||
@@ -13,4 +12,5 @@ const pacote = require('pacote') | ||
const hgi = require('hosted-git-info') | ||
const rpj = require('read-package-json-fast') | ||
const { dirname, resolve, relative } = require('path') | ||
const { dirname, resolve, relative, join } = require('path') | ||
const { depth: dfwalk } = require('treeverse') | ||
@@ -110,2 +110,4 @@ const { | ||
const _createIsolatedTree = Symbol.for('createIsolatedTree') | ||
module.exports = cls => class Reifier extends cls { | ||
@@ -143,2 +145,4 @@ constructor (options) { | ||
async reify (options = {}) { | ||
const linked = (options.installStrategy || this.options.installStrategy) === 'linked' | ||
if (this[_packageLockOnly] && this[_global]) { | ||
@@ -160,4 +164,18 @@ const er = new Error('cannot generate lockfile for global packages') | ||
await this[_loadTrees](options) | ||
const oldTree = this.idealTree | ||
if (linked) { | ||
// swap out the tree with the isolated tree | ||
// this is currently technical debt which will be resolved in a refactor | ||
// of Node/Link trees | ||
log.warn('reify', 'The "linked" install strategy is EXPERIMENTAL and may contain bugs.') | ||
this.idealTree = await this[_createIsolatedTree](this.idealTree) | ||
} | ||
await this[_diffTrees]() | ||
await this[_reifyPackages]() | ||
if (linked) { | ||
// swap back in the idealTree | ||
// so that the lockfile is preserved | ||
this.idealTree = oldTree | ||
} | ||
await this[_saveIdealTree](options) | ||
@@ -641,40 +659,36 @@ await this[_copyIdealToActual]() | ||
async [_extractOrLink] (node) { | ||
// in normal cases, node.resolved should *always* be set by now. | ||
// however, it is possible when a lockfile is damaged, or very old, | ||
// or in some other race condition bugs in npm v6, that a previously | ||
// bundled dependency will have just a version, but no resolved value, | ||
// and no 'bundled: true' setting. | ||
// Do the best with what we have, or else remove it from the tree | ||
// entirely, since we can't possibly reify it. | ||
let res = null | ||
if (node.resolved) { | ||
const registryResolved = this[_registryResolved](node.resolved) | ||
if (registryResolved) { | ||
res = `${node.name}@${registryResolved}` | ||
} | ||
} else if (node.packageName && node.version) { | ||
res = `${node.packageName}@${node.version}` | ||
} | ||
// no idea what this thing is. remove it from the tree. | ||
if (!res) { | ||
const warning = 'invalid or damaged lockfile detected\n' + | ||
'please re-try this operation once it completes\n' + | ||
'so that the damage can be corrected, or perform\n' + | ||
'a fresh install with no lockfile if the problem persists.' | ||
log.warn('reify', warning) | ||
log.verbose('reify', 'unrecognized node in tree', node.path) | ||
node.parent = null | ||
node.fsParent = null | ||
this[_addNodeToTrashList](node) | ||
return | ||
} | ||
const nm = resolve(node.parent.path, 'node_modules') | ||
await this[_validateNodeModules](nm) | ||
if (node.isLink) { | ||
await rm(node.path, { recursive: true, force: true }) | ||
await this[_symlink](node) | ||
} else { | ||
if (!node.isLink) { | ||
// in normal cases, node.resolved should *always* be set by now. | ||
// however, it is possible when a lockfile is damaged, or very old, | ||
// or in some other race condition bugs in npm v6, that a previously | ||
// bundled dependency will have just a version, but no resolved value, | ||
// and no 'bundled: true' setting. | ||
// Do the best with what we have, or else remove it from the tree | ||
// entirely, since we can't possibly reify it. | ||
let res = null | ||
if (node.resolved) { | ||
const registryResolved = this[_registryResolved](node.resolved) | ||
if (registryResolved) { | ||
res = `${node.name}@${registryResolved}` | ||
} | ||
} else if (node.package.name && node.version) { | ||
res = `${node.package.name}@${node.version}` | ||
} | ||
// no idea what this thing is. remove it from the tree. | ||
if (!res) { | ||
const warning = 'invalid or damaged lockfile detected\n' + | ||
'please re-try this operation once it completes\n' + | ||
'so that the damage can be corrected, or perform\n' + | ||
'a fresh install with no lockfile if the problem persists.' | ||
log.warn('reify', warning) | ||
log.verbose('reify', 'unrecognized node in tree', node.path) | ||
node.parent = null | ||
node.fsParent = null | ||
this[_addNodeToTrashList](node) | ||
return | ||
} | ||
await debug(async () => { | ||
@@ -696,3 +710,13 @@ const st = await lstat(node.path).catch(e => null) | ||
}) | ||
// store nodes don't use Node class so node.package doesn't get updated | ||
if (node.isInStore) { | ||
const pkg = await rpj(join(node.path, 'package.json')) | ||
node.package.scripts = pkg.scripts | ||
} | ||
return | ||
} | ||
// node.isLink | ||
await rm(node.path, { recursive: true, force: true }) | ||
await this[_symlink](node) | ||
} | ||
@@ -699,0 +723,0 @@ |
@@ -11,3 +11,3 @@ const relpath = require('./relpath.js') | ||
constructor (options) { | ||
const { root, realpath, target, parent, fsParent } = options | ||
const { root, realpath, target, parent, fsParent, isStoreLink } = options | ||
@@ -27,2 +27,4 @@ if (!realpath && !(target && target.path)) { | ||
this.isStoreLink = isStoreLink || false | ||
if (target) { | ||
@@ -29,0 +31,0 @@ this.target = target |
@@ -94,2 +94,3 @@ // inventory, path, realpath, root, and parent | ||
linksIn, | ||
isInStore = false, | ||
hasShrinkwrap, | ||
@@ -117,2 +118,3 @@ overrides, | ||
this.errors = error ? [error] : [] | ||
this.isInStore = isInStore | ||
@@ -119,0 +121,0 @@ // this will usually be null, except when modeling a |
{ | ||
"name": "@npmcli/arborist", | ||
"version": "6.1.6", | ||
"version": "6.2.0", | ||
"description": "Manage node_modules trees", | ||
@@ -42,3 +42,3 @@ "dependencies": { | ||
"@npmcli/eslint-config": "^4.0.0", | ||
"@npmcli/template-oss": "4.11.0", | ||
"@npmcli/template-oss": "4.11.1", | ||
"benchmark": "^2.1.4", | ||
@@ -49,2 +49,3 @@ "chalk": "^4.1.0", | ||
"tap": "^16.3.2", | ||
"tar-stream": "^3.0.0", | ||
"tcompare": "^5.0.6" | ||
@@ -54,2 +55,3 @@ }, | ||
"test": "tap", | ||
"test-only": "tap --only", | ||
"posttest": "node ../.. run lint", | ||
@@ -106,5 +108,5 @@ "snap": "tap", | ||
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", | ||
"version": "4.11.0", | ||
"version": "4.11.1", | ||
"content": "../../scripts/template-oss/index.js" | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
461760
66
12170
9
18