feat(core): return the list of dependencies that require a build (#8371)

This commit is contained in:
Zoltan Kochan
2024-08-02 23:37:23 +02:00
committed by GitHub
parent 64e2e4f86f
commit 09876c931f
4 changed files with 50 additions and 1 deletions

View File

@@ -0,0 +1,5 @@
---
"@pnpm/core": minor
---
Add an option to return the list of dependencies that require a build.

View File

@@ -154,6 +154,7 @@ export interface StrictInstallOptions {
virtualStoreDirMaxLength: number
peersSuffixMaxLength: number
prepareExecutionEnv?: PrepareExecutionEnv
returnListOfDepsRequiringBuild?: boolean
}
export type InstallOptions =

View File

@@ -225,6 +225,7 @@ export async function mutateModulesInSingleProject (
export interface MutateModulesResult {
updatedProjects: UpdatedProject[]
stats: InstallationResultStats
depsRequiringBuild?: DepPath[]
}
export async function mutateModules (
@@ -295,9 +296,10 @@ export async function mutateModules (
return {
updatedProjects: result.updatedProjects,
stats: result.stats ?? { added: 0, removed: 0, linkedToRoot: 0 },
depsRequiringBuild: result.depsRequiringBuild,
}
async function _install (): Promise<{ updatedProjects: UpdatedProject[], stats?: InstallationResultStats }> {
async function _install (): Promise<{ updatedProjects: UpdatedProject[], stats?: InstallationResultStats, depsRequiringBuild?: DepPath[] }> {
const scriptsOpts: RunLifecycleHooksConcurrentlyOptions = {
extraBinPaths: opts.extraBinPaths,
extraNodePaths: ctx.extraNodePaths,
@@ -735,6 +737,7 @@ Note that in CI environments, this setting is enabled by default.`,
return {
updatedProjects: result.projects,
stats: result.stats,
depsRequiringBuild: result.depsRequiringBuild,
}
}
}
@@ -948,6 +951,7 @@ interface InstallFunctionResult {
newLockfile: Lockfile
projects: UpdatedProject[]
stats?: InstallationResultStats
depsRequiringBuild: DepPath[]
}
type InstallFunction = (
@@ -1413,6 +1417,15 @@ const _installInContext: InstallFunction = async (projects, ctx, opts) => {
}
await waitTillAllFetchingsFinish()
const depsRequiringBuild: DepPath[] = []
if (opts.returnListOfDepsRequiringBuild) {
await Promise.all(Object.entries(dependenciesGraph).map(async ([depPath, { fetching }]) => {
const { files } = await fetching()
if (files.requiresBuild) {
depsRequiringBuild.push(depPath as DepPath)
}
}))
}
summaryLogger.debug({ prefix: opts.lockfileDir })
@@ -1437,6 +1450,7 @@ const _installInContext: InstallFunction = async (projects, ctx, opts) => {
rootDir,
})),
stats,
depsRequiringBuild,
}
}

View File

@@ -56,6 +56,35 @@ test('run pre/postinstall scripts', async () => {
}
})
test('return the list of packages that should be build', async () => {
prepareEmpty()
const allProjects = [
{
buildIndex: 0,
manifest: {
name: 'project',
version: '1.0.0',
dependencies: {
'@pnpm.e2e/pre-and-postinstall-scripts-example': '1.0.0',
},
},
rootDir: path.resolve('project') as ProjectRootDir,
},
]
const importers: MutatedProject[] = [
{
mutation: 'install',
rootDir: path.resolve('project') as ProjectRootDir,
},
]
const { depsRequiringBuild } = await mutateModules(importers,
testDefaults({ allProjects, enableModulesDir: false, returnListOfDepsRequiringBuild: true })
)
expect(depsRequiringBuild).toStrictEqual(['@pnpm.e2e/pre-and-postinstall-scripts-example@1.0.0'])
})
test('run pre/postinstall scripts, when PnP is used and no symlinks', async () => {
prepareEmpty()
await addDependenciesToPackage({},