-
-
Notifications
You must be signed in to change notification settings - Fork 931
/
readLockfiles.ts
147 lines (145 loc) · 4.58 KB
/
readLockfiles.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import {
LOCKFILE_VERSION,
LOCKFILE_VERSION_V6,
WANTED_LOCKFILE,
} from '@pnpm/constants'
import {
createLockfileObject,
existsNonEmptyWantedLockfile,
isEmptyLockfile,
type Lockfile,
readCurrentLockfile,
readWantedLockfile,
readWantedLockfileAndAutofixConflicts,
} from '@pnpm/lockfile-file'
import { logger } from '@pnpm/logger'
import { isCI } from 'ci-info'
import clone from 'ramda/src/clone'
import equals from 'ramda/src/equals'
export interface PnpmContext {
currentLockfile: Lockfile
existsCurrentLockfile: boolean
existsWantedLockfile: boolean
existsNonEmptyWantedLockfile: boolean
wantedLockfile: Lockfile
}
export async function readLockfiles (
opts: {
autoInstallPeers: boolean
excludeLinksFromLockfile: boolean
force: boolean
forceSharedLockfile: boolean
frozenLockfile: boolean
projects: Array<{
id: string
rootDir: string
}>
lockfileDir: string
registry: string
useLockfile: boolean
useGitBranchLockfile?: boolean
mergeGitBranchLockfiles?: boolean
virtualStoreDir: string
}
): Promise<{
currentLockfile: Lockfile
currentLockfileIsUpToDate: boolean
existsCurrentLockfile: boolean
existsWantedLockfile: boolean
existsNonEmptyWantedLockfile: boolean
wantedLockfile: Lockfile
wantedLockfileIsModified: boolean
lockfileHadConflicts: boolean
}> {
const wantedLockfileVersion = LOCKFILE_VERSION_V6
// ignore `pnpm-lock.yaml` on CI servers
// a latest pnpm should not break all the builds
const lockfileOpts = {
ignoreIncompatible: opts.force || isCI,
wantedVersions: [LOCKFILE_VERSION.toString(), LOCKFILE_VERSION_V6],
useGitBranchLockfile: opts.useGitBranchLockfile,
mergeGitBranchLockfiles: opts.mergeGitBranchLockfiles,
}
const fileReads = [] as Array<Promise<Lockfile | undefined | null>>
let lockfileHadConflicts: boolean = false
if (opts.useLockfile) {
if (!opts.frozenLockfile) {
fileReads.push(
(async () => {
try {
const { lockfile, hadConflicts } = await readWantedLockfileAndAutofixConflicts(opts.lockfileDir, lockfileOpts)
lockfileHadConflicts = hadConflicts
return lockfile
} catch (err: any) { // eslint-disable-line
logger.warn({
message: `Ignoring broken lockfile at ${opts.lockfileDir}: ${err.message as string}`,
prefix: opts.lockfileDir,
})
return undefined
}
})()
)
} else {
fileReads.push(readWantedLockfile(opts.lockfileDir, lockfileOpts))
}
} else {
if (await existsNonEmptyWantedLockfile(opts.lockfileDir, lockfileOpts)) {
logger.warn({
message: `A ${WANTED_LOCKFILE} file exists. The current configuration prohibits to read or write a lockfile`,
prefix: opts.lockfileDir,
})
}
fileReads.push(Promise.resolve(undefined))
}
fileReads.push(
(async () => {
try {
return await readCurrentLockfile(opts.virtualStoreDir, lockfileOpts)
} catch (err: any) { // eslint-disable-line
logger.warn({
message: `Ignoring broken lockfile at ${opts.virtualStoreDir}: ${err.message as string}`,
prefix: opts.lockfileDir,
})
return undefined
}
})()
)
const files = await Promise.all<Lockfile | null | undefined>(fileReads)
const sopts = {
autoInstallPeers: opts.autoInstallPeers,
excludeLinksFromLockfile: opts.excludeLinksFromLockfile,
lockfileVersion: wantedLockfileVersion,
}
const importerIds = opts.projects.map((importer) => importer.id)
const currentLockfile = files[1] ?? createLockfileObject(importerIds, sopts)
for (const importerId of importerIds) {
if (!currentLockfile.importers[importerId]) {
currentLockfile.importers[importerId] = {
specifiers: {},
}
}
}
const wantedLockfile = files[0] ??
(currentLockfile && clone(currentLockfile)) ??
createLockfileObject(importerIds, sopts)
let wantedLockfileIsModified = false
for (const importerId of importerIds) {
if (!wantedLockfile.importers[importerId]) {
wantedLockfileIsModified = true
wantedLockfile.importers[importerId] = {
specifiers: {},
}
}
}
const existsWantedLockfile = files[0] != null
return {
currentLockfile,
currentLockfileIsUpToDate: equals(currentLockfile, wantedLockfile),
existsCurrentLockfile: files[1] != null,
existsWantedLockfile,
existsNonEmptyWantedLockfile: existsWantedLockfile && !isEmptyLockfile(wantedLockfile),
wantedLockfile,
wantedLockfileIsModified,
lockfileHadConflicts,
}
}