generated from salesforcecli/plugin-template
-
Notifications
You must be signed in to change notification settings - Fork 18
/
progressBar.ts
98 lines (83 loc) · 3.65 KB
/
progressBar.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/*
* Copyright (c) 2022, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import { envVars as env, EnvironmentVariable, Lifecycle, Messages, Logger } from '@salesforce/core';
import { MetadataApiDeploy, MetadataApiDeployStatus } from '@salesforce/source-deploy-retrieve';
import { Progress } from '@salesforce/sf-plugins-core';
import { SourceMemberPollingEvent } from '@salesforce/source-tracking';
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
const mdTransferMessages = Messages.loadMessages('@salesforce/plugin-deploy-retrieve', 'metadata.transfer');
const showBar = Boolean(
process.env.TERM !== 'dumb' && process.stdin.isTTY && env.getBoolean(EnvironmentVariable.SF_USE_PROGRESS_BAR, true)
);
const logger = await Logger.child('deploy-progress');
export class DeployProgress extends Progress {
private static OPTIONS = {
title: 'Status',
format: `%s: {status} ${showBar ? '| {bar} ' : ''}| {value}/{total} Components{errorInfo}{testInfo}{trackingInfo}`,
barCompleteChar: '\u2588',
barIncompleteChar: '\u2591',
linewrap: true,
// people really like to get text output in CI systems
// they won't get the "bar" but will get the remaining template bits this way
noTTYOutput: true,
};
private lifecycle = Lifecycle.getInstance();
public constructor(private deploy: MetadataApiDeploy, jsonEnabled = false) {
super(!jsonEnabled);
}
public start(): void {
super.start(0, { status: 'Waiting', trackingInfo: '', testInfo: '' }, DeployProgress.OPTIONS);
// for sourceMember polling events
this.lifecycle.on<SourceMemberPollingEvent>('sourceMemberPollingEvent', (event: SourceMemberPollingEvent) =>
Promise.resolve(this.updateTrackingProgress(event))
);
this.deploy.onUpdate((data) => this.updateProgress(data));
// any thing else should make one final update, then stop the progress bar
this.deploy.onFinish((data) => {
this.updateProgress(data.response);
this.finish({ status: mdTransferMessages.getMessage(data.response.status) });
});
this.deploy.onCancel(() => this.stop());
this.deploy.onError((error: Error) => {
this.stop();
throw error;
});
}
private updateTrackingProgress(data: SourceMemberPollingEvent): void {
const { remaining, original } = data;
this.update(0, {
status: 'Polling SourceMembers',
trackingInfo: ` | Tracking: ${original - remaining}/${original}`,
});
}
private updateProgress(data: MetadataApiDeployStatus): void {
// the numCompTot. isn't computed right away, wait to start until we know how many we have
const testInfo = data.numberTestsTotal
? ` | ${data.numberTestsCompleted ?? 0}/${data.numberTestsTotal ?? 0} Tests${
data.numberTestErrors ? `(Errors:${data.numberTestErrors})` : ''
}`
: '';
const errorInfo = data.numberComponentErrors > 0 ? ` | Errors: ${data.numberComponentErrors}` : '';
if (data.numberComponentsTotal) {
this.setTotal(data.numberComponentsTotal);
this.update(data.numberComponentsDeployed, {
errorInfo: data.numberComponentErrors > 0 ? ` | Errors: ${data.numberComponentErrors}` : '',
status: mdTransferMessages.getMessage(data.status),
testInfo,
});
} else {
let status;
try {
status = mdTransferMessages.getMessage(data.status);
} catch (e) {
logger.debug(`data.status message lookup failed for: ${data.status}`);
status = 'Waiting';
}
this.update(0, { errorInfo, testInfo, status });
}
}
}