Skip to content

Commit 813f265

Browse files
committed
Refine reverting and saving in fix
1 parent 555d39c commit 813f265

3 files changed

Lines changed: 81 additions & 50 deletions

File tree

src/commands/fix/npm-fix.mts

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ export async function npmFix(
145145
{
146146
async beforeInstall(editablePkgJson) {
147147
revertData = {
148+
// Track existing dependencies in the root package.json to revert to later.
148149
...(editablePkgJson.content.dependencies && {
149150
dependencies: { ...editablePkgJson.content.dependencies },
150151
}),
@@ -159,25 +160,34 @@ export async function npmFix(
159160
} as PackageJson
160161
},
161162
async afterUpdate(editablePkgJson, packument, oldVersion, newVersion) {
162-
const isWorkspaceRoot =
163-
editablePkgJson.filename === pkgEnvDetails.editablePkgJson.filename
164-
if (isWorkspaceRoot) {
165-
const arb = new Arborist({
166-
path: pkgEnvDetails.pkgPath,
167-
...flatConfig,
168-
...SAFE_WITH_SAVE_ARBORIST_REIFY_OPTIONS_OVERRIDES,
169-
})
170-
const idealTree = await arb.buildIdealTree()
171-
const node = findPackageNode(idealTree, packument.name, oldVersion)
172-
if (node) {
173-
updateNode(node, newVersion, packument.versions[newVersion]!)
174-
await arb.reify()
175-
}
163+
// Exit early if not the root workspace.
164+
if (
165+
editablePkgJson.filename !== pkgEnvDetails.editablePkgJson.filename
166+
) {
167+
return
168+
}
169+
// Update package-lock.json using @npmcli/arborist.
170+
const arb = new Arborist({
171+
path: pkgEnvDetails.pkgPath,
172+
...flatConfig,
173+
...SAFE_WITH_SAVE_ARBORIST_REIFY_OPTIONS_OVERRIDES,
174+
})
175+
// Build the ideal tree of nodes that are used to generated the saved
176+
// package-lock.json
177+
const idealTree = await arb.buildIdealTree()
178+
const node = findPackageNode(idealTree, packument.name, oldVersion)
179+
if (node) {
180+
// Update the ideal tree node.
181+
updateNode(node, newVersion, packument.versions[newVersion]!)
182+
// Save package-lock.json lockfile.
183+
await arb.reify()
176184
}
177185
},
178186
async revertInstall(editablePkgJson) {
179187
if (revertData) {
188+
// Revert package.json.
180189
editablePkgJson.update(revertData)
190+
await editablePkgJson.save({ ignoreWhitespace: true })
181191
}
182192
},
183193
},

src/commands/fix/pnpm-fix.mts

Lines changed: 55 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ export async function pnpmFix(
9696
spinner?.start()
9797

9898
let actualTree: NodeClass | undefined
99-
let lockSrc: string | null = pkgEnvDetails.lockSrc
99+
let lockSrc: string = pkgEnvDetails.lockSrc
100100
let lockfile = parsePnpmLockfile(lockSrc)
101101
// Update pnpm-lock.yaml if its version is older than what the installed pnpm
102102
// produces.
@@ -109,11 +109,13 @@ export async function pnpmFix(
109109
cwd,
110110
spinner,
111111
})
112-
lockSrc = maybeActualTree
113-
? await readLockfile(pkgEnvDetails.lockPath)
114-
: null
115-
if (lockSrc && maybeActualTree) {
116-
actualTree = maybeActualTree
112+
if (maybeActualTree) {
113+
lockSrc = (await readLockfile(pkgEnvDetails.lockPath)) ?? ''
114+
} else {
115+
lockSrc = ''
116+
}
117+
if (lockSrc) {
118+
actualTree = maybeActualTree!
117119
lockfile = parsePnpmLockfile(lockSrc)
118120
} else {
119121
lockfile = null
@@ -165,23 +167,23 @@ export async function pnpmFix(
165167
vulnerableVersionRange,
166168
options,
167169
) {
168-
const isWorkspaceRoot =
169-
editablePkgJson.filename === pkgEnvDetails.editablePkgJson.filename
170-
// Get current overrides for revert logic.
171-
const { overrides: oldOverrides } = getOverridesDataPnpm(
172-
pkgEnvDetails,
173-
editablePkgJson.content,
174-
)
175-
const oldPnpmSection = editablePkgJson.content[PNPM] as
176-
| StringKeyValueObject
177-
| undefined
178-
const overrideKey = `${packument.name}@${vulnerableVersionRange}`
170+
lockSrc = (await readLockfile(pkgEnvDetails.lockPath)) ?? ''
179171

180-
lockSrc = await readLockfile(pkgEnvDetails.lockPath)
181-
revertOverrides = undefined
182-
revertOverridesSrc = extractOverridesFromPnpmLockSrc(lockSrc)
172+
// Update overrides for the root workspace.
173+
if (
174+
editablePkgJson.filename === pkgEnvDetails.editablePkgJson.filename
175+
) {
176+
const { overrides: oldOverrides } = getOverridesDataPnpm(
177+
pkgEnvDetails,
178+
editablePkgJson.content,
179+
)
180+
const oldPnpmSection = editablePkgJson.content[PNPM] as
181+
| StringKeyValueObject
182+
| undefined
183+
const overrideKey = `${packument.name}@${vulnerableVersionRange}`
183184

184-
if (isWorkspaceRoot) {
185+
revertOverridesSrc = extractOverridesFromPnpmLockSrc(lockSrc)
186+
// Track existing overrides in the root package.json to revert to later.
185187
revertOverrides = {
186188
[PNPM]: oldPnpmSection
187189
? {
@@ -191,9 +193,11 @@ export async function pnpmFix(
191193
...oldOverrides,
192194
[overrideKey]: undefined,
193195
}
194-
: undefined,
196+
: // Properties with undefined values are deleted when saved as JSON.
197+
undefined,
195198
}
196-
: undefined,
199+
: // Properties with undefined values are deleted when saved as JSON.
200+
undefined,
197201
} as PackageJson
198202
// Update overrides in the root package.json so that when `pnpm install`
199203
// generates pnpm-lock.yaml it updates transitive dependencies too.
@@ -210,10 +214,15 @@ export async function pnpmFix(
210214
},
211215
},
212216
})
217+
} else {
218+
revertOverrides = undefined
219+
revertOverridesSrc = ''
213220
}
214-
215221
revertData = {
222+
// If "pnpm" or "pnpm.overrides" fields are undefined they will be
223+
// deleted when saved.
216224
...revertOverrides,
225+
// Track existing dependencies in the root package.json to revert to later.
217226
...(editablePkgJson.content.dependencies && {
218227
dependencies: { ...editablePkgJson.content.dependencies },
219228
}),
@@ -232,22 +241,34 @@ export async function pnpmFix(
232241
// Revert overrides metadata in package.json now that pnpm-lock.yaml
233242
// has been updated.
234243
editablePkgJson.update(revertOverrides)
244+
await editablePkgJson.save({ ignoreWhitespace: true })
235245
}
236-
await editablePkgJson.save({ ignoreWhitespace: true })
237-
238-
lockSrc = await readLockfile(pkgEnvDetails.lockPath)
239-
const updatedOverridesContent = extractOverridesFromPnpmLockSrc(lockSrc)
240-
if (updatedOverridesContent) {
241-
lockSrc = lockSrc!.replace(
242-
updatedOverridesContent,
243-
revertOverridesSrc,
244-
)
245-
await fs.writeFile(pkgEnvDetails.lockPath, lockSrc, 'utf8')
246+
lockSrc = (await readLockfile(pkgEnvDetails.lockPath)) ?? ''
247+
// Remove "overrides" block from pnpm-lock.yaml lockfile when processing
248+
// the root workspace.
249+
if (
250+
editablePkgJson.filename === pkgEnvDetails.editablePkgJson.filename
251+
) {
252+
const updatedOverridesContent =
253+
extractOverridesFromPnpmLockSrc(lockSrc)
254+
if (updatedOverridesContent) {
255+
// Remove "overrides" block from pnpm-lock.yaml lockfile.
256+
lockSrc = lockSrc!.replace(
257+
updatedOverridesContent,
258+
revertOverridesSrc,
259+
)
260+
// Save pnpm-lock.yaml lockfile.
261+
await fs.writeFile(pkgEnvDetails.lockPath, lockSrc, 'utf8')
262+
}
246263
}
247264
},
248265
async revertInstall(editablePkgJson) {
249266
if (revertData) {
267+
// Revert package.json.
250268
editablePkgJson.update(revertData)
269+
await editablePkgJson.save({ ignoreWhitespace: true })
270+
// Revert pnpm-lock.yaml lockfile to be on the safe side.
271+
await fs.writeFile(pkgEnvDetails.lockPath, lockSrc, 'utf8')
251272
}
252273
},
253274
},

src/commands/optimize/update-manifest-by-agent.mts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ function updatePkgJsonField(
7171
},
7272
})
7373
} else {
74-
// Properties with undefined values are omitted when saved as JSON.
74+
// Properties with undefined values are deleted when saved as JSON.
7575
editablePkgJson.update(
7676
(hasKeys(oldValue)
7777
? {
@@ -84,7 +84,7 @@ function updatePkgJsonField(
8484
)
8585
}
8686
} else if (field === OVERRIDES || field === RESOLUTIONS) {
87-
// Properties with undefined values are omitted when saved as JSON.
87+
// Properties with undefined values are deleted when saved as JSON.
8888
editablePkgJson.update({
8989
[field]: hasKeys(value) ? value : undefined,
9090
} as typeof editablePkgJson.content)

0 commit comments

Comments
 (0)