From 380830e1a10a03a0e5c98372d939172010741d64 Mon Sep 17 00:00:00 2001 From: mshanemc Date: Mon, 29 Jan 2024 23:40:53 -0600 Subject: [PATCH] fix: another 15/18 edge case (yay, nuts!) --- src/commands/project/deploy/cancel.ts | 4 +-- src/commands/project/deploy/report.ts | 2 +- src/commands/project/deploy/resume.ts | 11 ++++--- src/utils/deployCache.ts | 41 ++++++++++++++++++--------- 4 files changed, 35 insertions(+), 23 deletions(-) diff --git a/src/commands/project/deploy/cancel.ts b/src/commands/project/deploy/cancel.ts index 20af243f..0dfc39af 100644 --- a/src/commands/project/deploy/cancel.ts +++ b/src/commands/project/deploy/cancel.ts @@ -63,7 +63,7 @@ export default class DeployMetadataCancel extends SfCommand { const jobId = cache.resolveLatest(flags['use-most-recent'], flags['job-id']); // cancel don't care about your tracking conflicts - const deployOpts = { ...cache.get(jobId), 'ignore-conflicts': true }; + const deployOpts = { ...cache.maybeGet(jobId), 'ignore-conflicts': true }; // we may already know the job finished if ( deployOpts.status && @@ -80,7 +80,7 @@ export default class DeployMetadataCancel extends SfCommand { if (!this.jsonEnabled()) formatter.display(); return formatter.getJson(); } else { - const wait = flags.wait ?? Duration.minutes(deployOpts.wait); + const wait = flags.wait ?? Duration.minutes(deployOpts.wait ?? 33); const result = await cancelDeploy({ ...deployOpts, wait }, jobId); const formatter = new DeployCancelResultFormatter(result); if (!this.jsonEnabled()) formatter.display(); diff --git a/src/commands/project/deploy/report.ts b/src/commands/project/deploy/report.ts index 07dfc809..cde43b68 100644 --- a/src/commands/project/deploy/report.ts +++ b/src/commands/project/deploy/report.ts @@ -82,7 +82,7 @@ export default class DeployMetadataReport extends SfCommand { // if we're using mdapi we won't have a component set let componentSet = new ComponentSet(); if (!deployOpts?.isMdapi) { - if (!cache.get(jobId)) { + if (!cache.maybeGet(jobId)) { // If the cache file isn't there, use the project package directories for the CompSet try { this.project = await SfProject.resolve(); diff --git a/src/commands/project/deploy/resume.ts b/src/commands/project/deploy/resume.ts index d4c1c147..d8557af1 100644 --- a/src/commands/project/deploy/resume.ts +++ b/src/commands/project/deploy/resume.ts @@ -5,8 +5,6 @@ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ - - import chalk from 'chalk'; import { EnvironmentVariable, Messages, Org, SfError } from '@salesforce/core'; import { SfCommand, toHelpSection, Flags } from '@salesforce/sf-plugins-core'; @@ -20,7 +18,7 @@ import { DeployCache } from '../../../utils/deployCache.js'; import { DEPLOY_STATUS_CODES_DESCRIPTIONS } from '../../../utils/errorCodes.js'; import { coverageFormattersFlag } from '../../../utils/flags.js'; -Messages.importMessagesDirectoryFromMetaUrl(import.meta.url) +Messages.importMessagesDirectoryFromMetaUrl(import.meta.url); const messages = Messages.loadMessages('@salesforce/plugin-deploy-retrieve', 'deploy.metadata.resume'); const testFlags = 'Test'; @@ -83,10 +81,10 @@ export default class DeployMetadataResume extends SfCommand { public async run(): Promise { const [{ flags }, cache] = await Promise.all([this.parse(DeployMetadataResume), DeployCache.create()]); - const jobId = cache.resolveLatest(flags['use-most-recent'], flags['job-id']); + const jobId = cache.resolveLatest(flags['use-most-recent'], flags['job-id'], true); // if it was async before, then it should not be async now. - const deployOpts = { ...cache.get(jobId), async: false }; + const deployOpts = { ...cache.maybeGet(jobId), async: false }; let result: DeployResult; @@ -108,7 +106,7 @@ export default class DeployMetadataResume extends SfCommand { const deployStatus = await mdapiDeploy.checkStatus(); result = new DeployResult(deployStatus, componentSet); } else { - const wait = flags.wait ?? Duration.minutes(deployOpts.wait); + const wait = flags.wait ?? Duration.minutes(deployOpts.wait ?? 33); const { deploy } = await executeDeploy( // there will always be conflicts on a resume if anything deployed--the changes on the server are not synced to local { @@ -134,6 +132,7 @@ export default class DeployMetadataResume extends SfCommand { if (!deploy.id) { throw new SfError('The deploy id is not available.'); } + cache.update(deploy.id, { status: result.response.status }); await cache.write(); } diff --git a/src/utils/deployCache.ts b/src/utils/deployCache.ts index db7dea0b..b6f149cd 100644 --- a/src/utils/deployCache.ts +++ b/src/utils/deployCache.ts @@ -41,16 +41,21 @@ export class DeployCache extends TTLConfig { public static async unset(key: string): Promise { const cache = await DeployCache.create(); - cache.unset(key); + cache.unset(ensure18(key, cache)); await Promise.all([cache.write(), maybeDestroyManifest(key)]); } public static async update(key: string, obj: JsonMap): Promise { const cache = await DeployCache.create(); - cache.update(key, obj); + cache.update(ensure18(key, cache), obj); await cache.write(); } + public update(key: string, obj: JsonMap): void { + super.update(ensure18(key, this), obj); + } + + /** will return an 18 character ID if throwOnNotFound is true (because the cache can be used to shift 15 to 18) */ public resolveLatest(useMostRecent: boolean, key: string | undefined, throwOnNotFound?: boolean): string { const resolvedKey = useMostRecent ? this.getLatestKey() : key; if (!resolvedKey) throw cacheMessages.createError('error.NoRecentJobId'); @@ -61,7 +66,7 @@ export class DeployCache extends TTLConfig { throw cacheMessages.createError('error.NoMatchingJobId', [resolvedKey]); } - return resolvedKey; + return throwOnNotFound ? ensure18(resolvedKey, this) : resolvedKey; } /** @@ -70,17 +75,7 @@ export class DeployCache extends TTLConfig { * returns 15-char ID if it matches a key in the cache, otherwise throws */ public resolveLongId(jobId: string): string { - if (jobId.length === 18) { - return jobId; - } else if (jobId.length === 15) { - const match = this.keys().find((k) => k.startsWith(jobId)); - if (match) { - return match; - } - throw cacheMessages.createError('error.NoMatchingJobId', [jobId]); - } else { - throw cacheMessages.createError('error.InvalidJobId', [jobId]); - } + return ensure18(jobId, this); } /** @@ -107,3 +102,21 @@ export class DeployCache extends TTLConfig { throw cacheMessages.createError('error.InvalidJobId', [jobId]); } } + +/** + * if the jobId is 15 characters, use the cache to convert to 18 + * will throw if the value is not in the cache + */ +const ensure18 = (jobId: string, cache: DeployCache): string => { + if (jobId.length === 18) { + return jobId; + } else if (jobId.length === 15) { + const match = cache.keys().find((k) => k.startsWith(jobId)); + if (match) { + return match; + } + throw cacheMessages.createError('error.NoMatchingJobId', [jobId]); + } else { + throw cacheMessages.createError('error.InvalidJobId', [jobId]); + } +};