Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions command-snapshot.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@
"flags-dir",
"job-id",
"json",
"no-progress",
"quiet",
"target-org",
"use-most-recent",
"verbose",
Expand Down Expand Up @@ -151,6 +153,8 @@
"job-id",
"json",
"junit",
"no-progress",
"quiet",
"results-dir",
"use-most-recent",
"verbose",
Expand Down Expand Up @@ -178,9 +182,11 @@
"manifest",
"metadata",
"metadata-dir",
"no-progress",
"post-destructive-changes",
"pre-destructive-changes",
"purge-on-delete",
"quiet",
"results-dir",
"single-package",
"source-dir",
Expand Down Expand Up @@ -209,9 +215,11 @@
"manifest",
"metadata",
"metadata-dir",
"no-progress",
"post-destructive-changes",
"pre-destructive-changes",
"purge-on-delete",
"quiet",
"results-dir",
"single-package",
"source-dir",
Expand Down Expand Up @@ -289,8 +297,10 @@
"json",
"manifest",
"metadata",
"no-progress",
"output-dir",
"package-name",
"quiet",
"single-package",
"source-dir",
"target-metadata-dir",
Expand Down
29 changes: 28 additions & 1 deletion messages/deploy.metadata.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@ If your org allows source tracking, then this command tracks the changes in your

To deploy multiple metadata components, either set multiple --metadata <name> flags or a single --metadata flag with multiple names separated by spaces. Enclose names that contain spaces in one set of double quotes. The same syntax applies to --source-dir.

## Output modes

| Switch | Streaming progress | Final report |
| --------------- | ------------------ | ------------------ |
| default | full | full success table |
| `--concise` | full | failures only |
| `--no-progress` | off | full success table |
| `--quiet` | off | one-line summary |

`--quiet` builds on the same streaming-suppression primitive as `--no-progress`. For token-sensitive workflows, `--json --concise` is already a near-minimal machine-readable payload.

# examples

- Deploy local changes not in the org; uses your default org:
Expand All @@ -22,6 +33,14 @@ To deploy multiple metadata components, either set multiple --metadata <name> fl

<%= config.bin %> <%= command.id %> --source-dir force-app --target-org my-scratch --concise

- Deploy all source files in the "force-app" directory to an org with alias "my-scratch"; emit the trimmed JSON payload instead of the full success table:

<%= config.bin %> <%= command.id %> --source-dir force-app --target-org my-scratch --json --concise

- Deploy all source files in the "force-app" directory to an org with alias "my-scratch"; suppress live progress and collapse the final report to one summary line:

<%= config.bin %> <%= command.id %> --source-dir force-app --target-org my-scratch --quiet

- Deploy all the Apex classes and custom objects that are in the "force-app" directory. The list views, layouts, etc, that are associated with the custom objects are also deployed. Both examples are equivalent:

<%= config.bin %> <%= command.id %> --source-dir force-app/main/default/classes force-app/main/default/objects
Expand Down Expand Up @@ -170,7 +189,15 @@ Show verbose output of the deploy result.

# flags.concise.summary

Show concise output of the deploy result.
Show concise output of the deploy result by omitting the full success table.

# flags.quiet.summary

Show a one-line deploy summary and suppress live progress to minimize stdout.

# flags.no-progress.summary

Hide the live deploy progress stream while keeping the full final report.

# flags.api-version.summary

Expand Down
12 changes: 10 additions & 2 deletions messages/deploy.metadata.quick.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,19 @@ If the command continues to run after the wait period, the CLI returns control o

# flags.verbose.summary

Show verbose output of the deploy result.
Show verbose output of the quick deploy result.

# flags.concise.summary

Show concise output of the deploy result.
Show concise output of the quick deploy result by omitting the full success table.

# flags.quiet.summary

Show a one-line quick deploy summary. Quick deploy has no live progress stream, so this only trims the final output.

# flags.no-progress.summary

Accepted for parity with other deploy commands; quick deploy has no live progress stream to hide.

# flags.async.summary

Expand Down
10 changes: 9 additions & 1 deletion messages/deploy.metadata.resume.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,15 @@ Show verbose output of the deploy operation result.

# flags.concise.summary

Show concise output of the deploy operation result.
Show concise output of the deploy operation result by omitting the full success table.

# flags.quiet.summary

Show a one-line deploy resume summary and suppress live progress to minimize stdout.

# flags.no-progress.summary

Hide the live deploy resume progress stream while keeping the full final report.

# warning.DeployNotResumable

Expand Down
10 changes: 9 additions & 1 deletion messages/deploy.metadata.validate.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,15 @@ Show verbose output of the validation result.

# flags.concise.summary

Show concise output of the validation result.
Show concise output of the validation result by omitting the full success table.

# flags.quiet.summary

Show a one-line validation summary and suppress live progress to minimize stdout.

# flags.no-progress.summary

Hide the live validation progress stream while keeping the full final report.

# flags.api-version.summary

Expand Down
16 changes: 16 additions & 0 deletions messages/retrieve.start.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,20 @@ If your org allows source tracking, then this command tracks the changes in your

To retrieve multiple metadata components, either use multiple --metadata <name> flags or use a single --metadata flag with multiple names separated by spaces. Enclose names that contain spaces in one set of double quotes. The same syntax applies to --source-dir.

## Output modes

`--quiet` suppresses the live retrieve progress stream and collapses the final output to a single summary line. `--no-progress` only hides the streaming block; it keeps the normal final output.

# examples

- Retrieve all remote changes from your default org:

<%= config.bin %> <%= command.id %>

- Retrieve all remote changes from your default org and keep the output to a single summary line:

<%= config.bin %> <%= command.id %> --quiet

- Retrieve the source files in the "force-app" directory from an org with alias "my-scratch":

<%= config.bin %> <%= command.id %> --source-dir force-app --target-org my-scratch
Expand Down Expand Up @@ -177,6 +185,14 @@ Running the command multiple times with the same target adds new files and overw

Directory root for the retrieved source files.

# flags.quiet.summary

Show a one-line retrieve summary and suppress live progress to minimize stdout.

# flags.no-progress.summary

Hide the live retrieve progress stream while keeping the final result.

# retrieveTargetDirOverlapsPackage

The retrieve target directory [%s] overlaps one of your package directories. Specify a different retrieve target directory and try again.
Expand Down
43 changes: 34 additions & 9 deletions src/commands/project/deploy/quick.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/

import ansis from 'ansis';
import { Messages, Org } from '@salesforce/core';
import { EnvironmentVariable, Messages, Org } from '@salesforce/core';
import { SfCommand, toHelpSection, Flags } from '@salesforce/sf-plugins-core';
import { MetadataApiDeploy, RequestStatus } from '@salesforce/source-deploy-retrieve';
import { Duration } from '@salesforce/kit';
Expand Down Expand Up @@ -44,7 +44,7 @@ export default class DeployMetadataQuick extends SfCommand<DeployResultJson> {
}),
concise: Flags.boolean({
summary: messages.getMessage('flags.concise.summary'),
exclusive: ['verbose'],
exclusive: ['verbose', 'quiet'],
}),
'job-id': Flags.salesforceId({
char: 'i',
Expand All @@ -63,7 +63,14 @@ export default class DeployMetadataQuick extends SfCommand<DeployResultJson> {
}),
verbose: Flags.boolean({
summary: messages.getMessage('flags.verbose.summary'),
exclusive: ['concise'],
exclusive: ['concise', 'quiet'],
}),
quiet: Flags.boolean({
summary: messages.getMessage('flags.quiet.summary'),
exclusive: ['verbose', 'concise'],
}),
'no-progress': Flags.boolean({
summary: messages.getMessage('flags.no-progress.summary'),
}),
wait: Flags.duration({
char: 'w',
Expand All @@ -85,6 +92,13 @@ export default class DeployMetadataQuick extends SfCommand<DeployResultJson> {

public static errorCodes = toHelpSection('ERROR CODES', DEPLOY_STATUS_CODES_DESCRIPTIONS);

public static envVariablesSection = toHelpSection(
'ENVIRONMENT VARIABLES',
EnvironmentVariable.SF_TARGET_ORG,
EnvironmentVariable.SF_USE_PROGRESS_BAR,
'SF_DEPLOY_PROGRESS'
);

private deployUrl?: string;

public async run(): Promise<DeployResultJson> {
Expand All @@ -101,13 +115,21 @@ export default class DeployMetadataQuick extends SfCommand<DeployResultJson> {
id: jobId,
rest: api === API['REST'],
});
this.log(`Deploy ID: ${ansis.bold(deployId)}`);
this.deployUrl = buildDeployUrl(flags['target-org'], deployId);
this.log(`Deploy URL: ${ansis.bold(this.deployUrl)}`);
if (!flags.quiet) {
this.log(`Deploy ID: ${ansis.bold(deployId)}`);
this.log(`Deploy URL: ${ansis.bold(this.deployUrl)}`);
}

if (flags.async) {
const asyncFormatter = new AsyncDeployResultFormatter(deployId);
if (!this.jsonEnabled()) asyncFormatter.display();
if (!this.jsonEnabled()) {
if (flags.quiet) {
this.log(`Deploy ID: ${ansis.bold(deployId)}`);
} else {
asyncFormatter.display();
}
}
return this.mixinUrlMeta(await asyncFormatter.getJson());
}

Expand All @@ -122,17 +144,20 @@ export default class DeployMetadataQuick extends SfCommand<DeployResultJson> {
frequency: Duration.seconds(1),
timeout: flags.wait,
});
const formatter = new DeployResultFormatter(result, flags);
const formatter = new DeployResultFormatter(result, { ...flags, 'target-org': targetOrg });

if (!this.jsonEnabled()) formatter.display();

await DeployCache.update(deployId, { status: result.response.status });

process.exitCode = determineExitCode(result);
if (result.response.status === RequestStatus.Succeeded) {
this.log();
this.logSuccess(messages.getMessage('info.QuickDeploySuccess', [deployId]));
if (!flags.quiet) {
this.log();
this.logSuccess(messages.getMessage('info.QuickDeploySuccess', [deployId]));
}
} else {
// failure detail must survive --quiet; quiet collapses successful output only
this.log(messages.getMessage('error.QuickDeployFailure', [deployId, result.response.status]));
}

Expand Down
40 changes: 33 additions & 7 deletions src/commands/project/deploy/resume.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { EnvironmentVariable, Messages, Org, SfError } from '@salesforce/core';
import { SfCommand, toHelpSection, Flags } from '@salesforce/sf-plugins-core';
import { DeployResult, MetadataApiDeploy } from '@salesforce/source-deploy-retrieve';
import { Duration } from '@salesforce/kit';
import { DeployStages } from '../../../utils/deployStages.js';
import { DeployStages, shouldShowDeployProgress } from '../../../utils/deployStages.js';
import { DeployResultFormatter } from '../../../formatters/deployResultFormatter.js';
import { API, DeployResultJson } from '../../../utils/types.js';
import {
Expand All @@ -37,6 +37,13 @@ const messages = Messages.loadMessages('@salesforce/plugin-deploy-retrieve', 'de

const testFlags = 'Test';

export const resolveResumeVerbose = (
flags: { quiet?: boolean; verbose?: boolean; concise?: boolean },
deployOpts: { verbose?: boolean }
// a current --quiet/--concise request must override cached verbose; only fall back to the
// cache when no explicit verbosity flag is set on this invocation.
): boolean => (flags.quiet ?? flags.concise ? false : flags.verbose ?? deployOpts.verbose ?? false);

export default class DeployMetadataResume extends SfCommand<DeployResultJson> {
public static readonly description = messages.getMessage('description');
public static readonly summary = messages.getMessage('summary');
Expand All @@ -47,7 +54,7 @@ export default class DeployMetadataResume extends SfCommand<DeployResultJson> {
public static readonly flags = {
concise: Flags.boolean({
summary: messages.getMessage('flags.concise.summary'),
exclusive: ['verbose'],
exclusive: ['verbose', 'quiet'],
}),
'job-id': Flags.salesforceId({
char: 'i',
Expand All @@ -65,7 +72,14 @@ export default class DeployMetadataResume extends SfCommand<DeployResultJson> {
}),
verbose: Flags.boolean({
summary: messages.getMessage('flags.verbose.summary'),
exclusive: ['concise'],
exclusive: ['concise', 'quiet'],
}),
quiet: Flags.boolean({
summary: messages.getMessage('flags.quiet.summary'),
exclusive: ['verbose', 'concise'],
}),
'no-progress': Flags.boolean({
summary: messages.getMessage('flags.no-progress.summary'),
}),
// we want this to allow undefined so that we can use the default value from the cache
// eslint-disable-next-line sf-plugin/flag-min-max-default
Expand All @@ -89,7 +103,11 @@ export default class DeployMetadataResume extends SfCommand<DeployResultJson> {
}),
};

public static envVariablesSection = toHelpSection('ENVIRONMENT VARIABLES', EnvironmentVariable.SF_USE_PROGRESS_BAR);
public static envVariablesSection = toHelpSection(
'ENVIRONMENT VARIABLES',
EnvironmentVariable.SF_USE_PROGRESS_BAR,
'SF_DEPLOY_PROGRESS'
);

public static errorCodes = toHelpSection('ERROR CODES', DEPLOY_STATUS_CODES_DESCRIPTIONS);

Expand Down Expand Up @@ -123,6 +141,12 @@ export default class DeployMetadataResume extends SfCommand<DeployResultJson> {
result = new DeployResult(deployStatus, componentSet);
} else {
const wait = flags.wait ?? Duration.minutes(deployOpts.wait ?? 33);
const verbose = resolveResumeVerbose(flags, deployOpts);
const showProgress = shouldShowDeployProgress({
jsonEnabled: this.jsonEnabled(),
quiet: flags.quiet,
noProgress: flags['no-progress'],
});
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
{
Expand All @@ -143,14 +167,15 @@ export default class DeployMetadataResume extends SfCommand<DeployResultJson> {
new DeployStages({
title: 'Resuming Deploy',
jsonEnabled: this.jsonEnabled(),
showProgress,
}).start(
{
deploy,
username: deployOpts['target-org'],
},
{
deployUrl: this.deployUrl,
verbose: flags.verbose ?? deployOpts.verbose,
verbose,
}
);

Expand All @@ -168,8 +193,9 @@ export default class DeployMetadataResume extends SfCommand<DeployResultJson> {

const formatter = new DeployResultFormatter(result, {
...flags,
verbose: deployOpts.verbose,
concise: deployOpts.concise,
verbose: resolveResumeVerbose(flags, deployOpts),
concise: flags.concise ?? deployOpts.concise,
'target-org': org,
});

if (!this.jsonEnabled()) formatter.display();
Expand Down
Loading