test: resolvePeers()

This commit is contained in:
Zoltan Kochan
2020-09-08 00:14:21 +03:00
parent 7a22607bb2
commit e60088f0be
10 changed files with 212 additions and 145 deletions

View File

@@ -21,10 +21,11 @@
"homepage": "https://github.com/pnpm/pnpm/blob/master/packages/resolve-dependencies#readme",
"scripts": {
"start": "pnpm run tsc -- --watch",
"test": "pnpm run compile",
"lint": "eslint -c ../../eslint.json src/**/*.ts",
"test": "pnpm run compile && pnpm run _test",
"lint": "eslint -c ../../eslint.json src/**/*.ts test/**/*.ts",
"prepublishOnly": "pnpm run compile",
"compile": "rimraf lib tsconfig.tsbuildinfo && tsc --build"
"compile": "rimraf lib tsconfig.tsbuildinfo && tsc --build",
"_test": "cd ../.. && c8 --reporter lcov --reports-dir packages/resolve-dependencies/coverage ts-node packages/resolve-dependencies/test --type-check"
},
"dependencies": {
"@pnpm/constants": "workspace:^4.0.0",

View File

@@ -24,17 +24,24 @@ import resolveDependencyTree, {
LinkedDependency,
ResolveDependenciesOptions,
ResolvedDirectDependency,
ResolvedPackage,
} from './resolveDependencyTree'
import resolvePeers, { DependenciesGraph, DependenciesGraphNode } from './resolvePeers'
import resolvePeers, {
GenericDependenciesGraph,
GenericDependenciesGraphNode,
} from './resolvePeers'
import updateLockfile from './updateLockfile'
import updateProjectManifest from './updateProjectManifest'
import path = require('path')
import R = require('ramda')
export type DependenciesGraph = GenericDependenciesGraph<ResolvedPackage>
export type DependenciesGraphNode = GenericDependenciesGraphNode & ResolvedPackage
export {
DependenciesGraph,
DependenciesGraphNode,
LinkedDependency,
ResolvedPackage,
}
interface ProjectToLink {

View File

@@ -69,22 +69,22 @@ export interface ChildrenMap {
[alias: string]: string
}
export type DependenciesTreeNode = {
export type DependenciesTreeNode<T> = {
children: (() => ChildrenMap) | ChildrenMap
installable: boolean
} & ({
resolvedPackage: ResolvedPackage
resolvedPackage: T & { version: string }
depth: number
} | {
resolvedPackage: { version: string }
depth: -1
})
export interface DependenciesTree {
export interface DependenciesTree<T> {
// a node ID is the join of the package's keypath with a colon
// E.g., a subdeps node ID which parent is `foo` will be
// registry.npmjs.org/foo/1.0.0:registry.npmjs.org/bar/1.0.0
[nodeId: string]: DependenciesTreeNode
[nodeId: string]: DependenciesTreeNode<T>
}
export type ResolvedPackagesByDepPath = Record<string, ResolvedPackage>
@@ -133,7 +133,7 @@ export interface ResolutionContext {
storeController: StoreController
// the IDs of packages that are not installable
skipped: Set<string>
dependenciesTree: DependenciesTree
dependenciesTree: DependenciesTree<ResolvedPackage>
force: boolean
prefix: string
readPackageHook?: ReadPackageHook
@@ -180,6 +180,7 @@ export interface ResolvedPackage {
name: string
version: string
peerDependencies: Dependencies
peerDependenciesMeta?: PeerDependenciesMeta
optionalDependencies: Set<string>
hasBin: boolean
hasBundledDependencies: boolean
@@ -188,8 +189,6 @@ export interface ResolvedPackage {
requiresBuild: boolean | undefined // added to fix issue #1201
additionalInfo: {
deprecated?: string
peerDependencies?: Dependencies
peerDependenciesMeta?: PeerDependenciesMeta
bundleDependencies?: string[]
bundledDependencies?: string[]
engines?: {
@@ -796,8 +795,6 @@ function getResolvedPackage (
deprecated: options.pkg.deprecated,
engines: options.pkg.engines,
os: options.pkg.os,
peerDependencies,
peerDependenciesMeta: options.pkg.peerDependenciesMeta,
},
depPath: options.depPath,
dev: options.wantedDependency.dev,
@@ -812,6 +809,7 @@ function getResolvedPackage (
optional: options.wantedDependency.optional,
optionalDependencies: new Set(R.keys(options.pkg.optionalDependencies)),
peerDependencies: peerDependencies ?? {},
peerDependenciesMeta: options.pkg.peerDependenciesMeta,
prepare: options.prepare,
prod: !options.wantedDependency.dev && !options.wantedDependency.optional,
requiresBuild: options.dependencyLockfile && Boolean(options.dependencyLockfile.requiresBuild),

View File

@@ -78,7 +78,7 @@ export default async function<T> (
childrenByParentDepPath: {} as ChildrenByParentDepPath,
currentLockfile: opts.currentLockfile,
defaultTag: opts.tag,
dependenciesTree: {} as DependenciesTree,
dependenciesTree: {} as DependenciesTree<ResolvedPackage>,
dryRun: opts.dryRun,
engineStrict: opts.engineStrict,
force: opts.force,
@@ -201,7 +201,7 @@ export default async function<T> (
function buildTree (
ctx: {
childrenByParentDepPath: ChildrenByParentDepPath
dependenciesTree: DependenciesTree
dependenciesTree: DependenciesTree<ResolvedPackage>
resolvedPackagesByDepPath: ResolvedPackagesByDepPath
skipped: Set<string>
},

View File

@@ -1,9 +1,7 @@
import PnpmError from '@pnpm/error'
import logger from '@pnpm/logger'
import pkgIdToFilename from '@pnpm/pkgid-to-filename'
import { Resolution } from '@pnpm/resolver-base'
import { PackageFilesResponse } from '@pnpm/store-controller-types'
import { Dependencies, DependencyManifest } from '@pnpm/types'
import { Dependencies } from '@pnpm/types'
import {
createNodeId,
splitNodeId,
@@ -19,50 +17,31 @@ import path = require('path')
import R = require('ramda')
import semver = require('semver')
export interface DependenciesGraphNode {
name: string
export interface GenericDependenciesGraphNode {
// at this point the version is really needed only for logging
version: string
hasBin: boolean
hasBundledDependencies: boolean
modules: string
fetchingBundledManifest?: () => Promise<DependencyManifest>
fetchingFiles: () => Promise<PackageFilesResponse>
filesIndexFile: string
resolution: Resolution
dir: string
children: {[alias: string]: string}
optionalDependencies: Set<string>
depth: number
depPath: string
prod: boolean
dev: boolean
optional: boolean
packageId: string
peerDependencies?: Dependencies
installable: boolean
additionalInfo: {
deprecated?: string
peerDependencies?: Dependencies
bundleDependencies?: string[]
bundledDependencies?: string[]
engines?: {
node?: string
npm?: string
}
cpu?: string[]
os?: string[]
}
isBuilt?: boolean
requiresBuild?: boolean
prepare: boolean
isPure: boolean
}
export interface DependenciesGraph {
[depPath: string]: DependenciesGraphNode
type PartialResolvedPackage = Pick<ResolvedPackage,
| 'depPath'
| 'name'
| 'peerDependencies'
| 'peerDependenciesMeta'
| 'version'
>
export interface GenericDependenciesGraph<T extends PartialResolvedPackage> {
[depPath: string]: T & GenericDependenciesGraphNode
}
export default function (
export default function<T extends PartialResolvedPackage> (
opts: {
projects: Array<{
directNodeIdsByAlias: {[alias: string]: string}
@@ -72,16 +51,16 @@ export default function (
rootDir: string // is only needed for logging
id: string
}>
dependenciesTree: DependenciesTree
dependenciesTree: DependenciesTree<T>
virtualStoreDir: string
lockfileDir: string
strictPeerDependencies: boolean
}
): {
dependenciesGraph: DependenciesGraph
dependenciesGraph: GenericDependenciesGraph<T>
dependenciesByProjectId: {[id: string]: {[alias: string]: string}}
} {
const depGraph: DependenciesGraph = {}
const depGraph: GenericDependenciesGraph<T> = {}
const pathsByNodeId = {}
for (const { directNodeIdsByAlias, topParents, rootDir } of opts.projects) {
@@ -152,13 +131,13 @@ interface PeersResolution {
resolvedPeers: Record<string, string>
}
function resolvePeersOfNode (
function resolvePeersOfNode<T extends PartialResolvedPackage> (
nodeId: string,
parentParentPkgs: ParentRefs,
ctx: {
dependenciesTree: DependenciesTree
dependenciesTree: DependenciesTree<T>
pathsByNodeId: {[nodeId: string]: string}
depGraph: DependenciesGraph
depGraph: GenericDependenciesGraph<T>
virtualStoreDir: string
peersCache: PeersCache
purePkgs: Set<string> // pure packages are those that don't rely on externally resolved peers
@@ -169,7 +148,7 @@ function resolvePeersOfNode (
): PeersResolution {
const node = ctx.dependenciesTree[nodeId]
if (node.depth === -1) return { resolvedPeers: {}, missingPeers: [] }
const resolvedPackage = node.resolvedPackage as ResolvedPackage
const resolvedPackage = node.resolvedPackage as T
if (ctx.purePkgs.has(resolvedPackage.depPath) && ctx.depGraph[resolvedPackage.depPath].depth <= node.depth) {
ctx.pathsByNodeId[nodeId] = resolvedPackage.depPath
return { resolvedPeers: {}, missingPeers: [] }
@@ -200,9 +179,9 @@ function resolvePeersOfNode (
ctx.pathsByNodeId[cachedNodeId] &&
ctx.pathsByNodeId[cachedNodeId] === ctx.pathsByNodeId[parentPkgs[name].nodeId!]
) return true
const parentDepPath = (ctx.dependenciesTree[parentPkgNodeId].resolvedPackage as ResolvedPackage).depPath
const parentDepPath = (ctx.dependenciesTree[parentPkgNodeId].resolvedPackage as T).depPath
if (!ctx.purePkgs.has(parentDepPath)) return false
const cachedDepPath = (ctx.dependenciesTree[cachedNodeId].resolvedPackage as ResolvedPackage).depPath
const cachedDepPath = (ctx.dependenciesTree[cachedNodeId].resolvedPackage as T).depPath
return parentDepPath === cachedDepPath
}) && cache.missingPeers.every((missingPeer) => !parentPkgs[missingPeer])
)
@@ -268,22 +247,20 @@ function resolvePeersOfNode (
}
ctx.pathsByNodeId[nodeId] = depPath
const peerDependencies = { ...resolvedPackage.peerDependencies }
if (!ctx.depGraph[depPath] || ctx.depGraph[depPath].depth > node.depth) {
const dir = path.join(modules, resolvedPackage.name)
const unknownPeers = Object.keys(unknownResolvedPeersOfChildren)
if (unknownPeers.length) {
if (!resolvedPackage.additionalInfo.peerDependencies) {
resolvedPackage.additionalInfo.peerDependencies = {}
}
for (const unknownPeer of unknownPeers) {
if (!resolvedPackage.additionalInfo.peerDependencies[unknownPeer]) {
resolvedPackage.additionalInfo.peerDependencies[unknownPeer] = '*'
if (!peerDependencies[unknownPeer]) {
peerDependencies[unknownPeer] = '*'
}
}
}
ctx.depGraph[depPath] = {
additionalInfo: resolvedPackage.additionalInfo,
...(node.resolvedPackage as T),
children: Object.assign(
getPreviouslyResolvedChildren(nodeId, ctx.dependenciesTree),
children,
@@ -291,25 +268,11 @@ function resolvePeersOfNode (
),
depPath,
depth: node.depth,
dev: resolvedPackage.dev,
dir,
fetchingBundledManifest: resolvedPackage.fetchingBundledManifest,
fetchingFiles: resolvedPackage.fetchingFiles,
filesIndexFile: resolvedPackage.filesIndexFile,
hasBin: resolvedPackage.hasBin,
hasBundledDependencies: resolvedPackage.hasBundledDependencies,
installable: node.installable,
isPure,
modules,
name: resolvedPackage.name,
optional: resolvedPackage.optional,
optionalDependencies: resolvedPackage.optionalDependencies,
packageId: resolvedPackage.id,
prepare: resolvedPackage.prepare,
prod: resolvedPackage.prod,
requiresBuild: resolvedPackage.requiresBuild,
resolution: resolvedPackage.resolution,
version: resolvedPackage.version,
peerDependencies,
}
}
return { resolvedPeers: allResolvedPeers, missingPeers: allMissingPeers }
@@ -321,7 +284,7 @@ function resolvePeersOfNode (
// from the dependencies of the parent package.
// So we need to merge all the children of all the parent packages with same ID as the resolved package.
// This way we get all the children that were removed, when ending cycles.
function getPreviouslyResolvedChildren (nodeId: string, dependenciesTree: DependenciesTree) {
function getPreviouslyResolvedChildren<T extends PartialResolvedPackage> (nodeId: string, dependenciesTree: DependenciesTree<T>) {
const parentIds = splitNodeId(nodeId)
const ownId = parentIds.pop()
const allChildren = {}
@@ -342,7 +305,7 @@ function getPreviouslyResolvedChildren (nodeId: string, dependenciesTree: Depend
return allChildren
}
function resolvePeersOfChildren (
function resolvePeersOfChildren<T extends PartialResolvedPackage> (
children: {
[alias: string]: string
},
@@ -352,8 +315,8 @@ function resolvePeersOfChildren (
peersCache: PeersCache
virtualStoreDir: string
purePkgs: Set<string>
depGraph: DependenciesGraph
dependenciesTree: DependenciesTree
depGraph: GenericDependenciesGraph<T>
dependenciesTree: DependenciesTree<T>
rootDir: string
lockfileDir: string
strictPeerDependencies: boolean
@@ -378,13 +341,13 @@ function resolvePeersOfChildren (
return { resolvedPeers: unknownResolvedPeersOfChildren, missingPeers: Array.from(allMissingPeers) }
}
function resolvePeers (
function resolvePeers<T extends PartialResolvedPackage> (
ctx: {
currentDepth: number
nodeId: string
parentPkgs: ParentRefs
resolvedPackage: ResolvedPackage
dependenciesTree: DependenciesTree
resolvedPackage: T
dependenciesTree: DependenciesTree<T>
rootDir: string
strictPeerDependencies: boolean
}
@@ -406,7 +369,7 @@ function resolvePeers (
} catch (err) {
missingPeers.push(peerName)
if (
ctx.resolvedPackage.additionalInfo.peerDependenciesMeta?.[peerName]?.optional === true
ctx.resolvedPackage.peerDependenciesMeta?.[peerName]?.optional === true
) {
continue
}
@@ -452,7 +415,7 @@ function packageFriendlyId (manifest: {name: string, version: string}) {
return `${manifest.name}@${manifest.version}`
}
function nodeIdToFriendlyPath (nodeId: string, dependenciesTree: DependenciesTree) {
function nodeIdToFriendlyPath<T extends PartialResolvedPackage> (nodeId: string, dependenciesTree: DependenciesTree<T>) {
const parts = splitNodeId(nodeId).slice(0, -1)
const result = R.scan((prevNodeId, pkgId) => createNodeId(prevNodeId, pkgId), '>', parts)
.slice(2)
@@ -472,7 +435,7 @@ interface ParentRef {
nodeId?: string
}
function toPkgByName (nodes: Array<{alias: string, nodeId: string, node: DependenciesTreeNode}>): ParentRefs {
function toPkgByName<T extends PartialResolvedPackage> (nodes: Array<{alias: string, nodeId: string, node: DependenciesTreeNode<T>}>): ParentRefs {
const pkgsByName: ParentRefs = {}
for (const { alias, node, nodeId } of nodes) {
pkgsByName[alias] = {

View File

@@ -7,16 +7,13 @@ import {
ResolvedDependencies,
} from '@pnpm/prune-lockfile'
import { Resolution } from '@pnpm/resolver-base'
import {
Dependencies,
PeerDependenciesMeta,
Registries,
} from '@pnpm/types'
import { Registries } from '@pnpm/types'
import * as dp from 'dependency-path'
import getNpmTarballUrl from 'get-npm-tarball-url'
import * as R from 'ramda'
import depPathToRef from './depPathToRef'
import { DependenciesGraph } from './resolvePeers'
import { DependenciesGraph } from '.'
import { ResolvedPackage } from './resolveDependencies'
export default function (
depGraph: DependenciesGraph,
@@ -35,7 +32,7 @@ export default function (
(child) => depNode.optionalDependencies.has(child.alias),
Object.keys(depNode.children).map((alias) => ({ alias, depPath: depNode.children[alias] }))
)
lockfile.packages[depPath] = toLockfileDependency(pendingRequiresBuilds, depNode.additionalInfo, {
lockfile.packages[depPath] = toLockfileDependency(pendingRequiresBuilds, depNode, {
depGraph,
depPath,
prevSnapshot: lockfile.packages[depPath],
@@ -54,19 +51,7 @@ export default function (
function toLockfileDependency (
pendingRequiresBuilds: string[],
pkg: {
deprecated?: string
peerDependencies?: Dependencies
peerDependenciesMeta?: PeerDependenciesMeta
bundleDependencies?: string[]
bundledDependencies?: string[]
engines?: {
node?: string
npm?: string
}
cpu?: string[]
os?: string[]
},
pkg: ResolvedPackage,
opts: {
depPath: string
registry: string
@@ -77,11 +62,10 @@ function toLockfileDependency (
prevSnapshot?: PackageSnapshot
}
): PackageSnapshot {
const depNode = opts.depGraph[opts.depPath]
const lockfileResolution = toLockfileResolution(
{ name: depNode.name, version: depNode.version },
{ name: pkg.name, version: pkg.version },
opts.depPath,
depNode.resolution,
pkg.resolution,
opts.registry
)
const newResolvedDeps = updateResolvedDeps(
@@ -101,12 +85,12 @@ function toLockfileDependency (
}
/* eslint-disable @typescript-eslint/dot-notation */
if (dp.isAbsolute(opts.depPath)) {
result['name'] = depNode.name
result['name'] = pkg.name
// There is no guarantee that a non-npmjs.org-hosted package
// is going to have a version field
if (depNode.version) {
result['version'] = depNode.version
if (pkg.version) {
result['version'] = pkg.version
}
}
if (!R.isEmpty(newResolvedDeps)) {
@@ -115,18 +99,18 @@ function toLockfileDependency (
if (!R.isEmpty(newResolvedOptionalDeps)) {
result['optionalDependencies'] = newResolvedOptionalDeps
}
if (depNode.dev && !depNode.prod) {
if (pkg.dev && !pkg.prod) {
result['dev'] = true
} else if (depNode.prod && !depNode.dev) {
} else if (pkg.prod && !pkg.dev) {
result['dev'] = false
}
if (depNode.optional) {
if (pkg.optional) {
result['optional'] = true
}
if (opts.depPath[0] !== '/' && !depNode.packageId.endsWith(opts.depPath)) {
result['id'] = depNode.packageId
if (opts.depPath[0] !== '/' && !pkg.id.endsWith(opts.depPath)) {
result['id'] = pkg.id
}
if (pkg.peerDependencies) {
if (!R.isEmpty(pkg.peerDependencies ?? {})) {
result['peerDependencies'] = pkg.peerDependencies
}
if (pkg.peerDependenciesMeta) {
@@ -140,26 +124,26 @@ function toLockfileDependency (
result['peerDependenciesMeta'] = normalizedPeerDependenciesMeta
}
}
if (pkg.engines) {
for (const engine of R.keys(pkg.engines)) {
if (pkg.engines[engine] === '*') continue
if (pkg.additionalInfo.engines) {
for (const engine of R.keys(pkg.additionalInfo.engines)) {
if (pkg.additionalInfo.engines[engine] === '*') continue
result['engines'] = result['engines'] || {}
result['engines'][engine] = pkg.engines[engine]
result['engines'][engine] = pkg.additionalInfo.engines[engine]
}
}
if (pkg.cpu) {
result['cpu'] = pkg.cpu
if (pkg.additionalInfo.cpu) {
result['cpu'] = pkg.additionalInfo.cpu
}
if (pkg.os) {
result['os'] = pkg.os
if (pkg.additionalInfo.os) {
result['os'] = pkg.additionalInfo.os
}
if (Array.isArray(pkg.bundledDependencies) || Array.isArray(pkg.bundleDependencies)) {
result['bundledDependencies'] = pkg.bundledDependencies ?? pkg.bundleDependencies
if (Array.isArray(pkg.additionalInfo.bundledDependencies) || Array.isArray(pkg.additionalInfo.bundleDependencies)) {
result['bundledDependencies'] = pkg.additionalInfo.bundledDependencies ?? pkg.additionalInfo.bundleDependencies
}
if (pkg.deprecated) {
result['deprecated'] = pkg.deprecated
if (pkg.additionalInfo.deprecated) {
result['deprecated'] = pkg.additionalInfo.deprecated
}
if (depNode.hasBin) {
if (pkg.hasBin) {
result['hasBin'] = true
}
if (opts.prevSnapshot) {
@@ -169,17 +153,17 @@ function toLockfileDependency (
if (opts.prevSnapshot.prepare) {
result['prepare'] = opts.prevSnapshot.prepare
}
} else if (depNode.prepare) {
} else if (pkg.prepare) {
result['prepare'] = true
result['requiresBuild'] = true
} else if (depNode.requiresBuild !== undefined) {
if (depNode.requiresBuild) {
} else if (pkg.requiresBuild !== undefined) {
if (pkg.requiresBuild) {
result['requiresBuild'] = true
}
} else {
pendingRequiresBuilds.push(opts.depPath)
}
depNode.requiresBuild = result['requiresBuild']
pkg.requiresBuild = result['requiresBuild']
/* eslint-enable @typescript-eslint/dot-notation */
return result
}

View File

@@ -0,0 +1,2 @@
/// <reference path="../../../typings/index.d.ts" />
import './resolvePeers'

View File

@@ -0,0 +1,109 @@
import resolvePeers from '@pnpm/resolve-dependencies/lib/resolvePeers'
import test = require('tape')
test('resolve peer dependencies of cyclic dependencies', (t) => {
const fooPkg = {
name: 'foo',
depPath: 'foo/1.0.0',
version: '1.0.0',
peerDependencies: {
qar: '1.0.0',
zoo: '1.0.0',
},
}
const barPkg = {
name: 'bar',
depPath: 'bar/1.0.0',
version: '1.0.0',
peerDependencies: {
foo: '1.0.0',
zoo: '1.0.0',
} as Record<string, string>,
}
const { dependenciesGraph } = resolvePeers({
projects: [
{
directNodeIdsByAlias: {
foo: 'foo/1.0.0',
},
topParents: [],
rootDir: '',
id: '',
},
],
dependenciesTree: {
'foo/1.0.0': {
children: {
bar: 'foo/1.0.0>bar/1.0.0',
},
installable: true,
resolvedPackage: fooPkg,
depth: 0,
},
'foo/1.0.0>bar/1.0.0': {
children: {
qar: 'foo/1.0.0>bar/1.0.0>qar/1.0.0',
},
installable: true,
resolvedPackage: barPkg,
depth: 1,
},
'foo/1.0.0>bar/1.0.0>qar/1.0.0': {
children: {
zoo: 'foo/1.0.0>bar/1.0.0>qar/1.0.0>zoo/1.0.0',
},
installable: true,
resolvedPackage: {
name: 'zoo',
depPath: 'zoo/1.0.0',
version: '1.0.0',
peerDependencies: {
foo: '1.0.0',
bar: '1.0.0',
},
},
depth: 2,
},
'foo/1.0.0>bar/1.0.0>qar/1.0.0>zoo/1.0.0': {
children: {
foo: 'foo/1.0.0>bar/1.0.0>qar/1.0.0>zoo/1.0.0>foo/1.0.0',
bar: 'foo/1.0.0>bar/1.0.0>qar/1.0.0>zoo/1.0.0>bar/1.0.0',
},
installable: true,
resolvedPackage: {
name: 'zoo',
depPath: 'zoo/1.0.0',
version: '1.0.0',
peerDependencies: {
qar: '1.0.0',
},
},
depth: 3,
},
'foo/1.0.0>bar/1.0.0>qar/1.0.0>zoo/1.0.0>foo/1.0.0': {
children: {},
installable: true,
resolvedPackage: fooPkg,
depth: 4,
},
'foo/1.0.0>bar/1.0.0>qar/1.0.0>zoo/1.0.0>bar/1.0.0': {
children: {},
installable: true,
resolvedPackage: barPkg,
depth: 4,
},
},
virtualStoreDir: '',
lockfileDir: '',
strictPeerDependencies: false,
})
t.deepEqual(Object.keys(dependenciesGraph), [
'foo/1.0.0_qar@1.0.0+zoo@1.0.0',
'bar/1.0.0_foo@1.0.0+zoo@1.0.0',
'zoo/1.0.0_qar@1.0.0+zoo@1.0.0',
'zoo/1.0.0_bar@1.0.0+foo@1.0.0+qar@1.0.0',
'bar/1.0.0_bar@1.0.0+foo@1.0.0',
'foo/1.0.0_foo@1.0.0',
])
t.end()
})

View File

@@ -9,6 +9,9 @@
"../../typings/**/*.d.ts"
],
"references": [
{
"path": "../constants"
},
{
"path": "../core-loggers"
},

View File

@@ -66,12 +66,12 @@ export default async function linkPackages (
newHoistedDependencies: HoistedDependencies
removedDepPaths: Set<string>
}> {
let depNodes = R.values(depGraph).filter(({ depPath, packageId }) => {
let depNodes = R.values(depGraph).filter(({ depPath, id }) => {
if (opts.wantedLockfile.packages?.[depPath] && !opts.wantedLockfile.packages[depPath].optional) {
opts.skipped.delete(depPath)
return true
}
if (opts.wantedToBeSkippedPackageIds.has(packageId)) {
if (opts.wantedToBeSkippedPackageIds.has(id)) {
opts.skipped.add(depPath)
return false
}
@@ -158,8 +158,8 @@ export default async function linkPackages (
rootLogger.debug({
added: {
dependencyType: isDev && 'dev' || isOptional && 'optional' || 'prod',
id: depGraphNode.packageId,
latest: opts.outdatedDependencies[depGraphNode.packageId],
id: depGraphNode.id,
latest: opts.outdatedDependencies[depGraphNode.id],
name: rootAlias,
realName: depGraphNode.name,
version: depGraphNode.version,