mirror of
https://github.com/pnpm/pnpm.git
synced 2026-03-25 18:41:48 -04:00
test: resolvePeers()
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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>
|
||||
},
|
||||
|
||||
@@ -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] = {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
2
packages/resolve-dependencies/test/index.ts
Normal file
2
packages/resolve-dependencies/test/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
/// <reference path="../../../typings/index.d.ts" />
|
||||
import './resolvePeers'
|
||||
109
packages/resolve-dependencies/test/resolvePeers.ts
Normal file
109
packages/resolve-dependencies/test/resolvePeers.ts
Normal 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()
|
||||
})
|
||||
@@ -9,6 +9,9 @@
|
||||
"../../typings/**/*.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "../constants"
|
||||
},
|
||||
{
|
||||
"path": "../core-loggers"
|
||||
},
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user