From 94250fbc6fa00cb8ea916b653bd978e2f57417e2 Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Sun, 29 May 2022 02:32:48 +0300 Subject: [PATCH] refactor: build-modules --- packages/build-modules/src/buildSequence.ts | 67 +++++++++++++++++++++ packages/build-modules/src/index.ts | 62 +------------------ 2 files changed, 70 insertions(+), 59 deletions(-) create mode 100644 packages/build-modules/src/buildSequence.ts diff --git a/packages/build-modules/src/buildSequence.ts b/packages/build-modules/src/buildSequence.ts new file mode 100644 index 0000000000..0279276569 --- /dev/null +++ b/packages/build-modules/src/buildSequence.ts @@ -0,0 +1,67 @@ +import graphSequencer from '@pnpm/graph-sequencer' +import { PackageManifest } from '@pnpm/types' +import filter from 'ramda/src/filter' + +export interface DependenciesGraphNode { + children: {[alias: string]: string} + depPath: string + dir: string + fetchingBundledManifest?: () => Promise + filesIndexFile: string + hasBin: boolean + hasBundledDependencies: boolean + installable?: boolean + isBuilt?: boolean + optional: boolean + optionalDependencies: Set + requiresBuild?: boolean +} + +export interface DependenciesGraph { + [depPath: string]: DependenciesGraphNode +} + +export default function buildSequence ( + depGraph: DependenciesGraph, + rootDepPaths: string[], +) { + const nodesToBuild = new Set() + getSubgraphToBuild(depGraph, rootDepPaths, nodesToBuild, new Set()) + const onlyFromBuildGraph = filter((depPath: string) => nodesToBuild.has(depPath)) + const nodesToBuildArray = Array.from(nodesToBuild) + const graph = new Map( + nodesToBuildArray + .map((depPath) => [depPath, onlyFromBuildGraph(Object.values(depGraph[depPath].children))]) + ) + const graphSequencerResult = graphSequencer({ + graph, + groups: [nodesToBuildArray], + }) + const chunks = graphSequencerResult.chunks as string[][] + return chunks +} + +function getSubgraphToBuild ( + graph: DependenciesGraph, + entryNodes: string[], + nodesToBuild: Set, + walked: Set +) { + let currentShouldBeBuilt = false + for (const depPath of entryNodes) { + if (!graph[depPath]) continue // packages that are already in node_modules are skipped + if (nodesToBuild.has(depPath)) { + currentShouldBeBuilt = true + } + if (walked.has(depPath)) continue + walked.add(depPath) + const childShouldBeBuilt = getSubgraphToBuild(graph, Object.values(graph[depPath].children), nodesToBuild, walked) || + graph[depPath].requiresBuild + if (childShouldBeBuilt) { + nodesToBuild.add(depPath) + currentShouldBeBuilt = true + } + } + return currentShouldBeBuilt +} + diff --git a/packages/build-modules/src/index.ts b/packages/build-modules/src/index.ts index 830aded2a1..1e15ecfee8 100644 --- a/packages/build-modules/src/index.ts +++ b/packages/build-modules/src/index.ts @@ -6,10 +6,9 @@ import linkBins, { linkBinsOfPackages } from '@pnpm/link-bins' import logger from '@pnpm/logger' import { fromDir as readPackageFromDir } from '@pnpm/read-package-json' import { StoreController } from '@pnpm/store-controller-types' -import { DependencyManifest, PackageManifest } from '@pnpm/types' +import { DependencyManifest } from '@pnpm/types' import runGroups from 'run-groups' -import graphSequencer from '@pnpm/graph-sequencer' -import filter from 'ramda/src/filter' +import buildSequence, { DependenciesGraph, DependenciesGraphNode } from './buildSequence' export { DepsStateCache } @@ -38,21 +37,9 @@ export default async ( ) => { const warn = (message: string) => logger.warn({ message, prefix: opts.lockfileDir }) // postinstall hooks - const nodesToBuild = new Set() - getSubgraphToBuild(depGraph, rootDepPaths, nodesToBuild, new Set()) - const onlyFromBuildGraph = filter((depPath: string) => nodesToBuild.has(depPath)) - const nodesToBuildArray = Array.from(nodesToBuild) - const graph = new Map( - nodesToBuildArray - .map((depPath) => [depPath, onlyFromBuildGraph(Object.values(depGraph[depPath].children))]) - ) - const graphSequencerResult = graphSequencer({ - graph, - groups: [nodesToBuildArray], - }) - const chunks = graphSequencerResult.chunks as string[][] const buildDepOpts = { ...opts, warn } + const chunks = buildSequence(depGraph, rootDepPaths) const groups = chunks.map((chunk) => { chunk = chunk.filter((depPath) => depGraph[depPath].requiresBuild && !depGraph[depPath].isBuilt) if (opts.depsToBuild != null) { @@ -145,49 +132,6 @@ async function buildDependency ( } } -function getSubgraphToBuild ( - graph: DependenciesGraph, - entryNodes: string[], - nodesToBuild: Set, - walked: Set -) { - let currentShouldBeBuilt = false - for (const depPath of entryNodes) { - if (!graph[depPath]) continue // packages that are already in node_modules are skipped - if (nodesToBuild.has(depPath)) { - currentShouldBeBuilt = true - } - if (walked.has(depPath)) continue - walked.add(depPath) - const childShouldBeBuilt = getSubgraphToBuild(graph, Object.values(graph[depPath].children), nodesToBuild, walked) || - graph[depPath].requiresBuild - if (childShouldBeBuilt) { - nodesToBuild.add(depPath) - currentShouldBeBuilt = true - } - } - return currentShouldBeBuilt -} - -export interface DependenciesGraphNode { - children: {[alias: string]: string} - depPath: string - dir: string - fetchingBundledManifest?: () => Promise - filesIndexFile: string - hasBin: boolean - hasBundledDependencies: boolean - installable?: boolean - isBuilt?: boolean - optional: boolean - optionalDependencies: Set - requiresBuild?: boolean -} - -export interface DependenciesGraph { - [depPath: string]: DependenciesGraphNode -} - export async function linkBinsOfDependencies ( depNode: DependenciesGraphNode, depGraph: DependenciesGraph,