From 3be3278942c9fb452fb718e5a87f2bd38c255853 Mon Sep 17 00:00:00 2001 From: Mike Donnalley Date: Wed, 4 Sep 2024 12:12:22 -0600 Subject: [PATCH] fix: human readable output (#1140) * fix: human readable output * fix: source member tracking percentage * fix: bump mso * fix: bump mso * chore(release): 3.11.2-beta.0 [skip ci] * fix: handle zip details * test: update nut --------- Co-authored-by: svc-cli-bot --- README.md | 76 ++++++++++++++------------ src/commands/project/delete/source.ts | 1 + src/commands/project/deploy/start.ts | 73 ++++++++++++------------- src/utils/deployStages.ts | 77 +++++++++++++++------------ test/nuts/deploy/verbose.nut.ts | 8 +-- 5 files changed, 127 insertions(+), 108 deletions(-) diff --git a/README.md b/README.md index 16c09b4b3..417ff5286 100644 --- a/README.md +++ b/README.md @@ -62,23 +62,29 @@ sf plugins -- [`sf project convert mdapi`](#sf-project-convert-mdapi) -- [`sf project convert source`](#sf-project-convert-source) -- [`sf project convert source-behavior`](#sf-project-convert-source-behavior) -- [`sf project delete source`](#sf-project-delete-source) -- [`sf project delete tracking`](#sf-project-delete-tracking) -- [`sf project deploy cancel`](#sf-project-deploy-cancel) -- [`sf project deploy preview`](#sf-project-deploy-preview) -- [`sf project deploy quick`](#sf-project-deploy-quick) -- [`sf project deploy report`](#sf-project-deploy-report) -- [`sf project deploy resume`](#sf-project-deploy-resume) -- [`sf project deploy start`](#sf-project-deploy-start) -- [`sf project deploy validate`](#sf-project-deploy-validate) -- [`sf project generate manifest`](#sf-project-generate-manifest) -- [`sf project list ignored`](#sf-project-list-ignored) -- [`sf project reset tracking`](#sf-project-reset-tracking) -- [`sf project retrieve preview`](#sf-project-retrieve-preview) -- [`sf project retrieve start`](#sf-project-retrieve-start) +- [plugin-deploy-retrieve](#plugin-deploy-retrieve) + - [Install](#install) + - [Contributing](#contributing) + - [CLA](#cla) + - [Build](#build) + - [Commands](#commands) + - [`sf project convert mdapi`](#sf-project-convert-mdapi) + - [`sf project convert source`](#sf-project-convert-source) + - [`sf project convert source-behavior`](#sf-project-convert-source-behavior) + - [`sf project delete source`](#sf-project-delete-source) + - [`sf project delete tracking`](#sf-project-delete-tracking) + - [`sf project deploy cancel`](#sf-project-deploy-cancel) + - [`sf project deploy preview`](#sf-project-deploy-preview) + - [`sf project deploy quick`](#sf-project-deploy-quick) + - [`sf project deploy report`](#sf-project-deploy-report) + - [`sf project deploy resume`](#sf-project-deploy-resume) + - [`sf project deploy start`](#sf-project-deploy-start) + - [`sf project deploy validate`](#sf-project-deploy-validate) + - [`sf project generate manifest`](#sf-project-generate-manifest) + - [`sf project list ignored`](#sf-project-list-ignored) + - [`sf project reset tracking`](#sf-project-reset-tracking) + - [`sf project retrieve preview`](#sf-project-retrieve-preview) + - [`sf project retrieve start`](#sf-project-retrieve-start) ## `sf project convert mdapi` @@ -141,7 +147,7 @@ FLAG DESCRIPTIONS If you specify this parameter, don’t specify --metadata or --source-dir. ``` -_See code: [src/commands/project/convert/mdapi.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.3-dev.0/src/commands/project/convert/mdapi.ts)_ +_See code: [src/commands/project/convert/mdapi.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.2/src/commands/project/convert/mdapi.ts)_ ## `sf project convert source` @@ -153,7 +159,7 @@ USAGE [-p ... | -x | -m ...] FLAGS - -d, --output-dir= [default: metadataPackage_1725465613516] Output directory to store the Metadata + -d, --output-dir= [default: metadataPackage_1725104645659] Output directory to store the Metadata API–formatted files in. -m, --metadata=... Metadata component names to convert. -n, --package-name= Name of the package to associate with the metadata-formatted files. @@ -214,7 +220,7 @@ FLAG DESCRIPTIONS Override the api version used for api requests made by this command ``` -_See code: [src/commands/project/convert/source.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.3-dev.0/src/commands/project/convert/source.ts)_ +_See code: [src/commands/project/convert/source.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.2/src/commands/project/convert/source.ts)_ ## `sf project convert source-behavior` @@ -271,7 +277,7 @@ EXAMPLES $ sf project convert source-behavior --behavior decomposePermissionSetBeta --dry-run --preserve-temp-dir ``` -_See code: [src/commands/project/convert/source-behavior.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.3-dev.0/src/commands/project/convert/source-behavior.ts)_ +_See code: [src/commands/project/convert/source-behavior.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.2/src/commands/project/convert/source-behavior.ts)_ ## `sf project delete source` @@ -411,7 +417,7 @@ FLAG DESCRIPTIONS - Separate the test names with spaces: --tests Test1 Test2 "Test With Space" ``` -_See code: [src/commands/project/delete/source.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.3-dev.0/src/commands/project/delete/source.ts)_ +_See code: [src/commands/project/delete/source.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.2/src/commands/project/delete/source.ts)_ ## `sf project delete tracking` @@ -448,7 +454,7 @@ EXAMPLES $ sf project delete tracking --target-org my-scratch ``` -_See code: [src/commands/project/delete/tracking.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.3-dev.0/src/commands/project/delete/tracking.ts)_ +_See code: [src/commands/project/delete/tracking.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.2/src/commands/project/delete/tracking.ts)_ ## `sf project deploy cancel` @@ -520,7 +526,7 @@ FLAG DESCRIPTIONS project deploy report". ``` -_See code: [src/commands/project/deploy/cancel.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.3-dev.0/src/commands/project/deploy/cancel.ts)_ +_See code: [src/commands/project/deploy/cancel.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.2/src/commands/project/deploy/cancel.ts)_ ## `sf project deploy preview` @@ -603,7 +609,7 @@ FLAG DESCRIPTIONS All child components are included. If you specify this flag, don’t specify --metadata or --source-dir. ``` -_See code: [src/commands/project/deploy/preview.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.3-dev.0/src/commands/project/deploy/preview.ts)_ +_See code: [src/commands/project/deploy/preview.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.2/src/commands/project/deploy/preview.ts)_ ## `sf project deploy quick` @@ -687,7 +693,7 @@ FLAG DESCRIPTIONS deploy report". ``` -_See code: [src/commands/project/deploy/quick.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.3-dev.0/src/commands/project/deploy/quick.ts)_ +_See code: [src/commands/project/deploy/quick.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.2/src/commands/project/deploy/quick.ts)_ ## `sf project deploy report` @@ -779,7 +785,7 @@ FLAG DESCRIPTIONS --coverage-formatters lcov --coverage-formatters clover ``` -_See code: [src/commands/project/deploy/report.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.3-dev.0/src/commands/project/deploy/report.ts)_ +_See code: [src/commands/project/deploy/report.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.2/src/commands/project/deploy/report.ts)_ ## `sf project deploy resume` @@ -864,7 +870,7 @@ FLAG DESCRIPTIONS --coverage-formatters lcov --coverage-formatters clover ``` -_See code: [src/commands/project/deploy/resume.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.3-dev.0/src/commands/project/deploy/resume.ts)_ +_See code: [src/commands/project/deploy/resume.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.2/src/commands/project/deploy/resume.ts)_ ## `sf project deploy start` @@ -1100,7 +1106,7 @@ FLAG DESCRIPTIONS --coverage-formatters lcov --coverage-formatters clover ``` -_See code: [src/commands/project/deploy/start.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.3-dev.0/src/commands/project/deploy/start.ts)_ +_See code: [src/commands/project/deploy/start.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.2/src/commands/project/deploy/start.ts)_ ## `sf project deploy validate` @@ -1273,7 +1279,7 @@ FLAG DESCRIPTIONS --coverage-formatters lcov --coverage-formatters clover ``` -_See code: [src/commands/project/deploy/validate.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.3-dev.0/src/commands/project/deploy/validate.ts)_ +_See code: [src/commands/project/deploy/validate.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.2/src/commands/project/deploy/validate.ts)_ ## `sf project generate manifest` @@ -1350,7 +1356,7 @@ EXAMPLES $ sf project generate manifest --from-org test@myorg.com --include-packages unlocked ``` -_See code: [src/commands/project/generate/manifest.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.3-dev.0/src/commands/project/generate/manifest.ts)_ +_See code: [src/commands/project/generate/manifest.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.2/src/commands/project/generate/manifest.ts)_ ## `sf project list ignored` @@ -1392,7 +1398,7 @@ EXAMPLES $ sf project list ignored --source-dir package.xml ``` -_See code: [src/commands/project/list/ignored.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.3-dev.0/src/commands/project/list/ignored.ts)_ +_See code: [src/commands/project/list/ignored.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.2/src/commands/project/list/ignored.ts)_ ## `sf project reset tracking` @@ -1441,7 +1447,7 @@ EXAMPLES $ sf project reset tracking --revision 30 ``` -_See code: [src/commands/project/reset/tracking.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.3-dev.0/src/commands/project/reset/tracking.ts)_ +_See code: [src/commands/project/reset/tracking.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.2/src/commands/project/reset/tracking.ts)_ ## `sf project retrieve preview` @@ -1495,7 +1501,7 @@ FLAG DESCRIPTIONS production orgs. ``` -_See code: [src/commands/project/retrieve/preview.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.3-dev.0/src/commands/project/retrieve/preview.ts)_ +_See code: [src/commands/project/retrieve/preview.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.2/src/commands/project/retrieve/preview.ts)_ ## `sf project retrieve start` @@ -1664,6 +1670,6 @@ FLAG DESCRIPTIONS If you specify this parameter, don’t specify --metadata or --source-dir. ``` -_See code: [src/commands/project/retrieve/start.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.3-dev.0/src/commands/project/retrieve/start.ts)_ +_See code: [src/commands/project/retrieve/start.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.12.2/src/commands/project/retrieve/start.ts)_ diff --git a/src/commands/project/delete/source.ts b/src/commands/project/delete/source.ts index dfdcd5d3d..103cc03d3 100644 --- a/src/commands/project/delete/source.ts +++ b/src/commands/project/delete/source.ts @@ -266,6 +266,7 @@ export class Source extends SfCommand { stages.start({ deploy, username: this.org.getUsername() }); this.deployResult = await deploy.pollStatus({ timeout: this.flags.wait }); if (!deploy.id) { + stages.error(); throw new SfError('The deploy id is not available.'); } await DeployCache.update(deploy.id, { status: this.deployResult.response.status }); diff --git a/src/commands/project/deploy/start.ts b/src/commands/project/deploy/start.ts index 7277222b5..dc68e04e5 100644 --- a/src/commands/project/deploy/start.ts +++ b/src/commands/project/deploy/start.ts @@ -20,7 +20,6 @@ import { ConfigVars } from '../../../configMeta.js'; import { coverageFormattersFlag, fileOrDirFlag, testLevelFlag, testsFlag } from '../../../utils/flags.js'; import { writeConflictTable } from '../../../utils/conflicts.js'; import { getOptionalProject } from '../../../utils/project.js'; -import { getZipFileSize } from '../../../utils/output.js'; Messages.importMessagesDirectoryFromMetaUrl(import.meta.url); const messages = Messages.loadMessages('@salesforce/plugin-deploy-retrieve', 'deploy.metadata'); @@ -203,44 +202,31 @@ export default class DeployMetadata extends SfCommand { const username = flags['target-org'].getUsername(); const title = flags['dry-run'] ? 'Deploying Metadata (dry-run)' : 'Deploying Metadata'; - this.stages = new DeployStages({ - title, - jsonEnabled: this.jsonEnabled(), - }); const lifecycle = Lifecycle.getInstance(); - // eslint-disable-next-line @typescript-eslint/require-await + let message: string = ''; + + lifecycle.on('apiVersionDeploy', async (apiData: DeployVersionData) => { + message = messages.getMessage('apiVersionMsgDetailed', [ + flags['dry-run'] ? 'Deploying (dry-run)' : 'Deploying', + // technically manifestVersion can be undefined, but only on raw mdapi deployments. + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions + flags['metadata-dir'] ? '' : `v${apiData.manifestVersion}`, + username, + apiData.apiVersion, + apiData.webService, + ]); + + return Promise.resolve(); + }); + lifecycle.on('deployZipData', async (zipData: DeployZipData) => { this.zipSize = zipData.zipSize; - if (flags.verbose && this.zipSize) { - this.stages.update({ - deploySize: `${getZipFileSize(this.zipSize)} of ~39 MB limit`, - }); - } if (zipData.zipFileCount) { this.zipFileCount = zipData.zipFileCount; - if (flags.verbose && this.zipSize) { - this.stages.update({ - deployFileCount: `${this.zipFileCount} of 10,000 limit`, - }); - } } - }); - lifecycle.on('apiVersionDeploy', async (apiData: DeployVersionData) => - Promise.resolve( - this.stages.update({ - message: messages.getMessage('apiVersionMsgDetailed', [ - flags['dry-run'] ? 'Deploying (dry-run)' : 'Deploying', - // technically manifestVersion can be undefined, but only on raw mdapi deployments. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions - flags['metadata-dir'] ? '' : `v${apiData.manifestVersion}`, - username, - apiData.apiVersion, - apiData.webService, - ]), - }) - ) - ); + return Promise.resolve(); + }); const { deploy } = await executeDeploy( { @@ -252,7 +238,6 @@ export default class DeployMetadata extends SfCommand { ); if (!deploy) { - this.stages.stop(); this.log('No changes to deploy'); return { status: 'Nothing to deploy', files: [] }; } @@ -261,7 +246,23 @@ export default class DeployMetadata extends SfCommand { throw new SfError('The deploy id is not available.'); } - this.stages.start({ username, deploy }); + this.stages = new DeployStages({ + title, + jsonEnabled: this.jsonEnabled(), + }); + + this.stages.start( + { username, deploy }, + { + message, + ...(flags.verbose + ? { + deploySize: this.zipSize, + deployFileCount: this.zipFileCount, + } + : {}), + } + ); if (flags.async) { this.stages.done({ status: 'Queued', username }); @@ -292,8 +293,8 @@ export default class DeployMetadata extends SfCommand { protected catch(error: Error | SfError): Promise { if (error instanceof SourceConflictError && error.data) { if (!this.jsonEnabled()) { - this.stages.update({ status: 'Failed' }); - this.stages.stop(error); + this.stages?.update({ status: 'Failed' }); + this.stages?.error(); writeConflictTable(error.data); // set the message and add plugin-specific actions return super.catch({ diff --git a/src/utils/deployStages.ts b/src/utils/deployStages.ts index 3c11adfd3..645812113 100644 --- a/src/utils/deployStages.ts +++ b/src/utils/deployStages.ts @@ -8,6 +8,7 @@ import { MultiStageOutput } from '@oclif/multi-stage-output'; import { Lifecycle, Messages } from '@salesforce/core'; import { MetadataApiDeploy, MetadataApiDeployStatus, RequestStatus } from '@salesforce/source-deploy-retrieve'; import { SourceMemberPollingEvent } from '@salesforce/source-tracking'; +import { getZipFileSize } from './output.js'; Messages.importMessagesDirectoryFromMetaUrl(import.meta.url); const mdTransferMessages = Messages.loadMessages('@salesforce/plugin-deploy-retrieve', 'metadata.transfer'); @@ -24,8 +25,8 @@ type Data = { message: string; username: string; id: string; - deploySize: string; - deployFileCount: string; + deploySize: number; + deployFileCount: number; }; function round(value: number, precision: number): number { @@ -42,10 +43,10 @@ function formatProgress(current: number, total: number): string { } export class DeployStages { - private ms: MultiStageOutput; + private mso: MultiStageOutput; public constructor({ title, jsonEnabled }: Options) { - this.ms = new MultiStageOutput({ + this.mso = new MultiStageOutput({ title, stages: [ 'Preparing', @@ -73,6 +74,7 @@ export class DeployStages { label: 'Deploy ID', get: (data): string | undefined => data?.id, type: 'static-key-value', + neverCollapse: true, }, { label: 'Target Org', @@ -80,13 +82,15 @@ export class DeployStages { type: 'static-key-value', }, { - label: 'Deploy Size', - get: (data): string | undefined => data?.deploySize, + label: 'Size', + get: (data): string | undefined => + data?.deploySize ? `${getZipFileSize(data.deploySize)} of ~39 MB limit` : undefined, type: 'static-key-value', }, { - label: 'Deployed File Count', - get: (data): string | undefined => data?.deployFileCount, + label: 'Files', + get: (data): string | undefined => + data?.deployFileCount ? `${data.deployFileCount} of 10,000 limit` : undefined, type: 'static-key-value', }, ], @@ -128,15 +132,22 @@ export class DeployStages { }); } - public start({ username, deploy }: { username?: string | undefined; deploy: MetadataApiDeploy }): void { + public start( + { username, deploy }: { username?: string | undefined; deploy: MetadataApiDeploy }, + initialData?: Partial + ): void { const lifecycle = Lifecycle.getInstance(); - - this.ms.skipTo('Preparing', { username, id: deploy.id }); + if (initialData) this.mso.updateData(initialData); + this.mso.skipTo('Preparing', { username, id: deploy.id }); // for sourceMember polling events - lifecycle.on('sourceMemberPollingEvent', (event: SourceMemberPollingEvent) => - Promise.resolve(this.ms.skipTo('Updating Source Tracking', { sourceMemberPolling: event })) - ); + lifecycle.on('sourceMemberPollingEvent', (event: SourceMemberPollingEvent) => { + if (event.original > 0) { + return Promise.resolve(this.mso.skipTo('Updating Source Tracking', { sourceMemberPolling: event })); + } + + return Promise.resolve(); + }); deploy.onUpdate((data) => { if ( @@ -144,14 +155,14 @@ export class DeployStages { data.numberTestsTotal > 0 && data.numberComponentsDeployed > 0 ) { - this.ms.skipTo('Running Tests', { mdapiDeploy: data, status: mdTransferMessages.getMessage(data?.status) }); + this.mso.skipTo('Running Tests', { mdapiDeploy: data, status: mdTransferMessages.getMessage(data?.status) }); } else if (data.status === RequestStatus.Pending) { - this.ms.skipTo('Waiting for the org to respond', { + this.mso.skipTo('Waiting for the org to respond', { mdapiDeploy: data, status: mdTransferMessages.getMessage(data?.status), }); } else { - this.ms.skipTo('Deploying Metadata', { + this.mso.skipTo('Deploying Metadata', { mdapiDeploy: data, status: mdTransferMessages.getMessage(data?.status), }); @@ -159,44 +170,44 @@ export class DeployStages { }); deploy.onFinish((data) => { - this.ms.updateData({ mdapiDeploy: data.response, status: mdTransferMessages.getMessage(data.response.status) }); + this.mso.updateData({ mdapiDeploy: data.response, status: mdTransferMessages.getMessage(data.response.status) }); if (data.response.status === RequestStatus.Failed) { - this.ms.error(); + this.mso.error(); } else { - this.ms.skipTo('Done'); - this.ms.stop(); + this.mso.skipTo('Done'); + this.mso.stop(); } }); deploy.onCancel((data) => { - this.ms.updateData({ mdapiDeploy: data, status: mdTransferMessages.getMessage(data?.status ?? 'Canceled') }); + this.mso.updateData({ mdapiDeploy: data, status: mdTransferMessages.getMessage(data?.status ?? 'Canceled') }); - this.ms.error(); + this.mso.error(); }); deploy.onError((error: Error) => { if (error.message.includes('client has timed out')) { - this.ms.updateData({ status: 'Client Timeout' }); + this.mso.updateData({ status: 'Client Timeout' }); } - this.ms.error(); + this.mso.error(); throw error; }); } public update(data: Partial): void { - this.ms.updateData(data); + this.mso.updateData(data); + } + + public stop(): void { + this.mso.stop(); } - public stop(error?: Error): void { - if (error) { - this.ms.error(); - } else { - this.ms.stop(); - } + public error(): void { + this.mso.error(); } public done(data?: Partial): void { - this.ms.goto('Done', data); + this.mso.skipTo('Done', data); } } diff --git a/test/nuts/deploy/verbose.nut.ts b/test/nuts/deploy/verbose.nut.ts index c3a2047be..a650a36ce 100644 --- a/test/nuts/deploy/verbose.nut.ts +++ b/test/nuts/deploy/verbose.nut.ts @@ -45,8 +45,8 @@ describe('Deploy --verbose', () => { } ).shellOutput; - expect(shellOutput.stdout).to.contain('Deploy size: ').and.contain('KB of ~39 MB limit'); - expect(shellOutput.stdout).to.contain('Deployed files count: 5 of 10,000 limit'); + expect(shellOutput.stdout).to.contain('Size: ').and.contain('KB of ~39 MB limit'); + expect(shellOutput.stdout).to.contain('Files: 5 of 10,000 limit'); }); it('should have zip file size and file count returned with --json --async', () => { @@ -69,7 +69,7 @@ describe('Deploy --verbose', () => { } ).shellOutput; - expect(shellOutput.stdout).to.contain('Deploy size: ').and.contain('KB of ~39 MB limit'); - expect(shellOutput.stdout).to.contain('Deployed files count: 5 of 10,000 limit'); + expect(shellOutput.stdout).to.contain('Size: ').and.contain('KB of ~39 MB limit'); + expect(shellOutput.stdout).to.contain('Files: 5 of 10,000 limit'); }); });