mirror of
https://github.com/pnpm/pnpm.git
synced 2025-12-31 11:08:12 -05:00
feat: add internal lockfileCheck option for lockfile only diff installs (#6404)
This commit is contained in:
6
.changeset/fuzzy-spiders-begin.md
Normal file
6
.changeset/fuzzy-spiders-begin.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@pnpm/plugin-commands-installation": patch
|
||||
"@pnpm/core": patch
|
||||
---
|
||||
|
||||
Add lockfileCheck option for lockfile only diff installs
|
||||
@@ -42,6 +42,7 @@ export interface StrictInstallOptions {
|
||||
ignorePackageManifest: boolean
|
||||
preferFrozenLockfile: boolean
|
||||
saveWorkspaceProtocol: boolean | 'rolling'
|
||||
lockfileCheck?: (prev: Lockfile, next: Lockfile) => void
|
||||
lockfileIncludeTarballUrl: boolean
|
||||
preferWorkspacePackages: boolean
|
||||
preserveWorkspaceProtocol: boolean
|
||||
|
||||
@@ -65,6 +65,7 @@ import pLimit from 'p-limit'
|
||||
import pMapValues from 'p-map-values'
|
||||
import flatten from 'ramda/src/flatten'
|
||||
import mapValues from 'ramda/src/map'
|
||||
import clone from 'ramda/src/clone'
|
||||
import equals from 'ramda/src/equals'
|
||||
import isEmpty from 'ramda/src/isEmpty'
|
||||
import pickBy from 'ramda/src/pickBy'
|
||||
@@ -801,6 +802,19 @@ const _installInContext: InstallFunction = async (projects, ctx, opts) => {
|
||||
})
|
||||
}
|
||||
|
||||
// The wanted lockfile is mutated during installation. To compare changes, a
|
||||
// deep copy before installation is needed. This copy should represent the
|
||||
// original wanted lockfile on disk as close as possible.
|
||||
//
|
||||
// This object can be quite large. Intentionally avoiding an expensive copy
|
||||
// if no lockfileCheck option was passed in.
|
||||
const originalLockfileForCheck = opts.lockfileCheck != null
|
||||
? clone(ctx.wantedLockfile)
|
||||
: null
|
||||
|
||||
// Aliasing for clarity in boolean expressions below.
|
||||
const isInstallationOnlyForLockfileCheck = opts.lockfileCheck != null
|
||||
|
||||
ctx.wantedLockfile.importers = ctx.wantedLockfile.importers || {}
|
||||
for (const { id } of projects) {
|
||||
if (!ctx.wantedLockfile.importers[id]) {
|
||||
@@ -965,7 +979,7 @@ const _installInContext: InstallFunction = async (projects, ctx, opts) => {
|
||||
useGitBranchLockfile: opts.useGitBranchLockfile,
|
||||
mergeGitBranchLockfiles: opts.mergeGitBranchLockfiles,
|
||||
}
|
||||
if (!opts.lockfileOnly && opts.enableModulesDir) {
|
||||
if (!opts.lockfileOnly && !isInstallationOnlyForLockfileCheck && opts.enableModulesDir) {
|
||||
const result = await linkPackages(
|
||||
projects,
|
||||
dependenciesGraph,
|
||||
@@ -1199,7 +1213,7 @@ const _installInContext: InstallFunction = async (projects, ctx, opts) => {
|
||||
}
|
||||
} else {
|
||||
await finishLockfileUpdates()
|
||||
if (opts.useLockfile) {
|
||||
if (opts.useLockfile && !isInstallationOnlyForLockfileCheck) {
|
||||
await writeWantedLockfile(ctx.lockfileDir, newLockfile, lockfileOpts)
|
||||
}
|
||||
|
||||
@@ -1223,6 +1237,14 @@ const _installInContext: InstallFunction = async (projects, ctx, opts) => {
|
||||
strictPeerDependencies: opts.strictPeerDependencies,
|
||||
})
|
||||
|
||||
// Similar to the sequencing for when the original wanted lockfile is
|
||||
// copied, the new lockfile passed here should be as close as possible to
|
||||
// what will eventually be written to disk. Ex: peers should be resolved,
|
||||
// the afterAllResolved hook has been applied, etc.
|
||||
if (originalLockfileForCheck != null) {
|
||||
opts.lockfileCheck?.(originalLockfileForCheck, newLockfile)
|
||||
}
|
||||
|
||||
return {
|
||||
newLockfile,
|
||||
projects: projects.map(({ id, manifest, rootDir }) => ({
|
||||
|
||||
@@ -7,6 +7,7 @@ import { type Config } from '@pnpm/config'
|
||||
import { PnpmError } from '@pnpm/error'
|
||||
import { filterPkgsBySelectorObjects } from '@pnpm/filter-workspace-packages'
|
||||
import { arrayOfWorkspacePackagesToMap, findWorkspacePackages } from '@pnpm/find-workspace-packages'
|
||||
import { type Lockfile } from '@pnpm/lockfile-types'
|
||||
import { rebuildProjects } from '@pnpm/plugin-commands-rebuild'
|
||||
import { createOrConnectStoreController, type CreateStoreControllerOptions } from '@pnpm/store-connection-manager'
|
||||
import { type IncludedDependencies, type Project, type ProjectsGraph } from '@pnpm/types'
|
||||
@@ -88,6 +89,17 @@ export type InstallDepsOptions = Pick<Config,
|
||||
include?: IncludedDependencies
|
||||
includeDirect?: IncludedDependencies
|
||||
latest?: boolean
|
||||
/**
|
||||
* If specified, the installation will only be performed for comparison of the
|
||||
* wanted lockfile. The wanted lockfile will not be updated on disk and no
|
||||
* modules will be linked.
|
||||
*
|
||||
* The given callback is passed the wanted lockfile before installation and
|
||||
* after. This allows functions to reasonably determine whether the wanted
|
||||
* lockfile will change on disk after installation. The lockfile arguments
|
||||
* passed to this callback should not be mutated.
|
||||
*/
|
||||
lockfileCheck?: (prev: Lockfile, next: Lockfile) => void
|
||||
update?: boolean
|
||||
updateMatching?: (pkgName: string) => boolean
|
||||
updatePackageManifest?: boolean
|
||||
|
||||
Reference in New Issue
Block a user