
























@@ -71,6 +71,39 @@ async function createStagedNpmInstall(
7171};
7272}
737374+async function prepareStagedNpmInstall(
75+installTarget: ResolvedGlobalInstallTarget,
76+packageName: string,
77+): Promise<{
78+stagedInstall: StagedNpmInstall | null;
79+failedStep: PackageUpdateStepResult | null;
80+}> {
81+const startedAt = Date.now();
82+try {
83+return {
84+stagedInstall: await createStagedNpmInstall(installTarget, packageName),
85+failedStep: null,
86+};
87+} catch (err) {
88+const targetLayout =
89+installTarget.manager === "npm"
90+ ? resolveNpmGlobalPrefixLayoutFromGlobalRoot(installTarget.globalRoot)
91+ : null;
92+return {
93+stagedInstall: null,
94+failedStep: {
95+name: "global install stage",
96+command: "prepare staged npm install",
97+cwd: targetLayout?.prefix ?? installTarget.globalRoot ?? process.cwd(),
98+durationMs: Date.now() - startedAt,
99+exitCode: 1,
100+stdoutTail: null,
101+stderrTail: formatError(err),
102+},
103+};
104+}
105+}
106+74107async function cleanupStagedNpmInstall(stage: StagedNpmInstall | null): Promise<void> {
75108if (!stage) {
76109return;
@@ -215,118 +248,147 @@ export async function runGlobalPackageUpdateSteps(params: {
215248}> {
216249const installCwd = params.installCwd === undefined ? {} : { cwd: params.installCwd };
217250const installEnv = params.env === undefined ? {} : { env: params.env };
218-let stagedInstall = await createStagedNpmInstall(params.installTarget, params.packageName);
219-const updateStep = await params.runStep({
220-name: "global update",
221-argv: globalInstallArgs(
222-params.installTarget,
223-params.installSpec,
224-undefined,
225-stagedInstall?.prefix,
226-),
227- ...installCwd,
228- ...installEnv,
229-timeoutMs: params.timeoutMs,
230-});
251+let stagedInstall: StagedNpmInstall | null = null;
231252232-const steps = [updateStep];
233-let finalInstallStep = updateStep;
234-if (updateStep.exitCode !== 0) {
235-await cleanupStagedNpmInstall(stagedInstall);
236-stagedInstall = await createStagedNpmInstall(params.installTarget, params.packageName);
237-const fallbackArgv = globalInstallFallbackArgs(
238-params.installTarget,
239-params.installSpec,
240-undefined,
241-stagedInstall?.prefix,
242-);
243-if (fallbackArgv) {
244-const fallbackStep = await params.runStep({
245-name: "global update (omit optional)",
246-argv: fallbackArgv,
247- ...installCwd,
248- ...installEnv,
249-timeoutMs: params.timeoutMs,
250-});
251-steps.push(fallbackStep);
252-finalInstallStep = fallbackStep;
253-} else {
253+try {
254+const preparedInstall = await prepareStagedNpmInstall(params.installTarget, params.packageName);
255+stagedInstall = preparedInstall.stagedInstall;
256+if (preparedInstall.failedStep) {
257+return {
258+steps: [preparedInstall.failedStep],
259+verifiedPackageRoot: params.packageRoot ?? null,
260+afterVersion: null,
261+failedStep: preparedInstall.failedStep,
262+};
263+}
264+265+const updateStep = await params.runStep({
266+name: "global update",
267+argv: globalInstallArgs(
268+params.installTarget,
269+params.installSpec,
270+undefined,
271+stagedInstall?.prefix,
272+),
273+ ...installCwd,
274+ ...installEnv,
275+timeoutMs: params.timeoutMs,
276+});
277+278+const steps = [updateStep];
279+let finalInstallStep = updateStep;
280+if (updateStep.exitCode !== 0) {
254281await cleanupStagedNpmInstall(stagedInstall);
255282stagedInstall = null;
283+const preparedFallbackInstall = await prepareStagedNpmInstall(
284+params.installTarget,
285+params.packageName,
286+);
287+stagedInstall = preparedFallbackInstall.stagedInstall;
288+if (preparedFallbackInstall.failedStep) {
289+steps.push(preparedFallbackInstall.failedStep);
290+return {
291+ steps,
292+verifiedPackageRoot: params.packageRoot ?? null,
293+afterVersion: null,
294+failedStep: preparedFallbackInstall.failedStep,
295+};
296+}
297+298+const fallbackArgv = globalInstallFallbackArgs(
299+params.installTarget,
300+params.installSpec,
301+undefined,
302+stagedInstall?.prefix,
303+);
304+if (fallbackArgv) {
305+const fallbackStep = await params.runStep({
306+name: "global update (omit optional)",
307+argv: fallbackArgv,
308+ ...installCwd,
309+ ...installEnv,
310+timeoutMs: params.timeoutMs,
311+});
312+steps.push(fallbackStep);
313+finalInstallStep = fallbackStep;
314+} else {
315+await cleanupStagedNpmInstall(stagedInstall);
316+stagedInstall = null;
317+}
256318}
257-}
258319259-let verifiedPackageRoot =
260-stagedInstall?.packageRoot ??
261-(
262-await resolveGlobalInstallTarget({
263-manager: params.installTarget,
264-runCommand: params.runCommand,
265-timeoutMs: params.timeoutMs,
266-})
267-).packageRoot ??
268-params.packageRoot ??
269-null;
320+ let verifiedPackageRoot =
321+ stagedInstall?.packageRoot ??
322+ (
323+ await resolveGlobalInstallTarget({
324+ manager: params.installTarget,
325+ runCommand: params.runCommand,
326+ timeoutMs: params.timeoutMs,
327+ })
328+ ).packageRoot ??
329+ params.packageRoot ??
330+ null;
270331271-let afterVersion: string | null = null;
272-if (finalInstallStep.exitCode === 0 && verifiedPackageRoot) {
273-afterVersion = await readPackageVersion(verifiedPackageRoot);
274-const expectedVersion = resolveExpectedInstalledVersionFromSpec(
275-params.packageName,
276-params.installSpec,
277-);
278-const verificationErrors = await collectInstalledGlobalPackageErrors({
279-packageRoot: verifiedPackageRoot,
280- expectedVersion,
281-});
282-if (verificationErrors.length > 0) {
283-steps.push({
284-name: "global install verify",
285-command: `verify ${verifiedPackageRoot}`,
286-cwd: verifiedPackageRoot,
287-durationMs: 0,
288-exitCode: 1,
289-stderrTail: verificationErrors.join("\n"),
290-stdoutTail: null,
332+let afterVersion: string | null = null;
333+if (finalInstallStep.exitCode === 0 && verifiedPackageRoot) {
334+afterVersion = await readPackageVersion(verifiedPackageRoot);
335+const expectedVersion = resolveExpectedInstalledVersionFromSpec(
336+params.packageName,
337+params.installSpec,
338+);
339+const verificationErrors = await collectInstalledGlobalPackageErrors({
340+packageRoot: verifiedPackageRoot,
341+ expectedVersion,
291342});
292-}
343+if (verificationErrors.length > 0) {
344+steps.push({
345+name: "global install verify",
346+command: `verify ${verifiedPackageRoot}`,
347+cwd: verifiedPackageRoot,
348+durationMs: 0,
349+exitCode: 1,
350+stderrTail: verificationErrors.join("\n"),
351+stdoutTail: null,
352+});
353+}
293354294-if (stagedInstall && verificationErrors.length === 0) {
295-const swapStep = await swapStagedNpmInstall({
296-stage: stagedInstall,
297-installTarget: params.installTarget,
298-packageName: params.packageName,
299-});
300-steps.push(swapStep);
301-if (swapStep.exitCode === 0) {
302-verifiedPackageRoot = params.installTarget.packageRoot ?? verifiedPackageRoot;
355+if (stagedInstall && verificationErrors.length === 0) {
356+const swapStep = await swapStagedNpmInstall({
357+stage: stagedInstall,
358+installTarget: params.installTarget,
359+packageName: params.packageName,
360+});
361+steps.push(swapStep);
362+if (swapStep.exitCode === 0) {
363+verifiedPackageRoot = params.installTarget.packageRoot ?? verifiedPackageRoot;
364+}
303365}
304-}
305366306-const failedVerifyOrSwap = steps.find(
307-(step) =>
308-(step.name === "global install verify" || step.name === "global install swap") &&
309-step.exitCode !== 0,
310-);
311-const postVerifyStep = failedVerifyOrSwap
312- ? null
313- : await params.postVerifyStep?.(verifiedPackageRoot);
314-if (postVerifyStep) {
315-steps.push(postVerifyStep);
367+const failedVerifyOrSwap = steps.find(
368+(step) =>
369+(step.name === "global install verify" || step.name === "global install swap") &&
370+step.exitCode !== 0,
371+);
372+const postVerifyStep = failedVerifyOrSwap
373+ ? null
374+ : await params.postVerifyStep?.(verifiedPackageRoot);
375+if (postVerifyStep) {
376+steps.push(postVerifyStep);
377+}
316378}
317-}
318-319-await cleanupStagedNpmInstall(stagedInstall);
320379321-const failedStep =
322-finalInstallStep.exitCode !== 0
323- ? finalInstallStep
324- : (steps.find((step) => step !== updateStep && step.exitCode !== 0) ?? null);
380+ const failedStep =
381+ finalInstallStep.exitCode !== 0
382+ ? finalInstallStep
383+ : (steps.find((step) => step !== updateStep && step.exitCode !== 0) ?? null);
325384326-return {
327- steps,
328- verifiedPackageRoot,
329- afterVersion,
330- failedStep,
331-};
385+return {
386+ steps,
387+ verifiedPackageRoot,
388+ afterVersion,
389+ failedStep,
390+};
391+} finally {
392+await cleanupStagedNpmInstall(stagedInstall);
393+}
332394}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。