Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 4x 1x 4x 1x 4x 1x 6x 3x 1x 2x 2x 6x 6x 6x 15x 10x 10x 6x 2x 10x 2x 1x 2x 2x 2x 2x 21x 2x 2x 1x 2x 2x 6x 6x 2x 2x 6x 2x 1x 1x 1x 1x 1x 1x | 'use strict' const { readdir } = require('fs') const { resolve } = require('path') const Arborist = require('@npmcli/arborist') const npa = require('npm-package-arg') const rpj = require('read-package-json-fast') const semver = require('semver') const npm = require('./npm.js') const usageUtil = require('./utils/usage.js') const reifyFinish = require('./utils/reify-finish.js') const completion = (opts, cb) => { const dir = npm.globalDir readdir(dir, (er, files) => cb(er, files.filter(f => !/^[._-]/.test(f)))) } const usage = usageUtil( 'link', 'npm link (in package dir)' + '\nnpm link [<@scope>/]<pkg>[@<version>]' ) const cmd = (args, cb) => link(args).then(() => cb()).catch(cb) const link = async args => { if (npm.config.get('global')) { throw Object.assign( new Error( 'link should never be --global.\n' + 'Please re-run this command with --local' ), { code: 'ELINKGLOBAL' } ) } // link with no args: symlink the folder to the global location // link with package arg: symlink the global to the local args = args.filter(a => resolve(a) !== npm.prefix) return args.length ? linkInstall(args) : linkPkg() } // Returns a list of items that can't be fulfilled by // things found in the current arborist inventory const missingArgsFromTree = (tree, args) => { const foundNodes = [] const missing = args.filter(a => { const arg = npa(a) const nodes = tree.children.values() const argFound = [...nodes].every(node => { // TODO: write tests for unmatching version specs, this is hard to test // atm but should be simple once we have a mocked registry again if (arg.name !== node.name /* istanbul ignore next */ || ( arg.version && !semver.satisfies(node.version, arg.version) )) { foundNodes.push(node) return true } }) return argFound }) // remote nodes from the loaded tree in order // to avoid dropping them later when reifying for (const node of foundNodes) node.parent = null return missing } const linkInstall = async args => { // load current packages from the global space, // and then add symlinks installs locally const globalTop = resolve(npm.globalDir, '..') const globalOpts = { ...npm.flatOptions, path: globalTop, global: true, prune: false, } const globalArb = new Arborist(globalOpts) // get only current top-level packages from the global space const globals = await globalArb.loadActual({ filter: (node, kid) => !node.isRoot || args.some(a => npa(a).name === kid), }) // any extra arg that is missing from the current // global space should be reified there first const missing = missingArgsFromTree(globals, args) if (missing.length) { await globalArb.reify({ ...globalOpts, add: missing, }) } // get a list of module names that should be linked in the local prefix const names = [] for (const a of args) { const arg = npa(a) names.push( arg.type === 'directory' ? (await rpj(resolve(arg.fetchSpec, 'package.json'))).name : arg.name ) } // create a new arborist instance for the local prefix and // reify all the pending names as symlinks there const localArb = new Arborist({ ...npm.flatOptions, path: npm.prefix, }) await localArb.reify({ add: names.map(l => `file:${resolve(globalTop, 'node_modules', l)}`), }) await reifyFinish(localArb) } const linkPkg = async () => { const globalTop = resolve(npm.globalDir, '..') const arb = new Arborist({ ...npm.flatOptions, path: globalTop, global: true, }) await arb.reify({ add: [`file:${npm.prefix}`] }) await reifyFinish(arb) } module.exports = Object.assign(cmd, { completion, usage }) |