Skip to content

Commit

Permalink
feat: report progress when deploying datapacks in direct deploy mode …
Browse files Browse the repository at this point in the history
…for datapacks
  • Loading branch information
Codeneos committed Aug 7, 2023
1 parent f5a7139 commit 3890ec1
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 25 deletions.
34 changes: 17 additions & 17 deletions packages/salesforce/src/deploymentPackageBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,12 @@ export class SalesforcePackageBuilder {
const isInStaticResourceFolder = file.split(/\/|\\/).includes('staticresources');
if (!isInStaticResourceFolder) {
// This is just here to avoid complaining on static resources that are part of an extracted zip file
this.logger.warn(`Adding ${file} (xmlName: ${xmlName ?? '?'}) is not a known Salesforce metadata type`);
this.logger.warn(`${file} (xmlName: ${xmlName ?? '?'}) is not a known Salesforce metadata type`);
}
continue;
}

if (metadataType.xmlName != xmlName) {
if (metadataType.name != xmlName) {
// Support for SFDX formatted source code
childMetadataFiles.push([ file, xmlName, metadataType]);
continue;
Expand Down Expand Up @@ -139,7 +139,7 @@ export class SalesforcePackageBuilder {

private sortXmlFragments(fragments: Array<[string, string, MetadataType]>) : Array<[string, string, MetadataType]> {
return fragments.sort(([, fragmentTypeA, parentTypeA], [, fragmentTypeB, parentTypeB]) => {
const metaTypeCompare = parentTypeA.xmlName.localeCompare(parentTypeB.xmlName);
const metaTypeCompare = parentTypeA.name.localeCompare(parentTypeB.name);
if (metaTypeCompare != 0) {
return metaTypeCompare;
}
Expand Down Expand Up @@ -238,19 +238,19 @@ export class SalesforcePackageBuilder {
}

if (this.type === SalesforcePackageType.destruct) {
this.mdPackage.addDestructiveChange(metadataType.xmlName, componentName);
this.mdPackage.addDestructiveChange(metadataType.name, componentName);
} else {
const packagePath = await this.getPackagePath(file, metadataType);
this.mdPackage.add({
componentType: metadataType.xmlName,
componentType: metadataType.name,
componentName,
packagePath,
data: await this.fs.readFile(file),
fsPath: file
});
}

this.logger.verbose(`Added ${path.basename(file)} (${componentName}) as [${chalk.green(metadataType.xmlName)}]`);
this.logger.verbose(`Added %s (%s) as [%s]`, path.basename(file), componentName, chalk.green(metadataType.name));
}

/**
Expand Down Expand Up @@ -334,12 +334,12 @@ export class SalesforcePackageBuilder {
if (fragmentType.isAddressable) {
this.mdPackage.addManifestEntry(fragmentTypeName, `${parentComponentName}.${childComponentName}`);
} else {
this.mdPackage.addManifestEntry(parentType.xmlName, parentComponentName);
this.mdPackage.addManifestEntry(parentType.name, parentComponentName);
}
this.mdPackage.addSourceMap(sourceFile, { componentType: fragmentTypeName, componentName: `${parentComponentName}.${childComponentName}`, packagePath: parentPackagePath });
}

this.logger.verbose(`Adding ${path.basename(sourceFile)} as ${parentComponentName}.${childComponentName}`);
this.logger.verbose(`Added %s (%s.%s) as [%s]`, path.basename(sourceFile), parentComponentName, childComponentName, chalk.green(fragmentTypeName));
}

/**
Expand Down Expand Up @@ -370,7 +370,7 @@ export class SalesforcePackageBuilder {

// Merge child metadata into parent metadata
const metadata = await this.readComposedMetadata(packagePath, fragmentFile, metadataType);
this.mergeMetadata(metadata[metadataType.xmlName], { [decomposition.directoryName]: fragmentMetadata });
this.mergeMetadata(metadata[metadataType.name], { [decomposition.directoryName]: fragmentMetadata });
}

private async readComposedMetadata(packagePath: string, fragmentFile: string, metadataType: MetadataType): Promise<any> {
Expand All @@ -391,16 +391,16 @@ export class SalesforcePackageBuilder {

const existingMetadata = existingPackageData
? XML.parse(existingPackageData, { trimValues: true })
: { [metadataType.xmlName]: {} };
: { [metadataType.name]: {} };
this.composedData.set(packagePath, { data: existingMetadata, type: metadataType });
return existingMetadata;
}

private async persistComposedMetadata() {
for (const [ packagePath, { data, type } ] of this.composedData.entries()) {
this.mdPackage.setPackageData(packagePath, {
data: this.buildMetadataXml(type.xmlName, data[type.xmlName]),
componentType: type.xmlName,
data: this.buildMetadataXml(type.name, data[type.name]),
componentType: type.name,
componentName: path.basename(packagePath, `.${type.suffix}`)
});
}
Expand Down Expand Up @@ -487,7 +487,7 @@ export class SalesforcePackageBuilder {

private getMetadataType(xmlName: string) {
const metadataTypes = this.metadataRegistry.getMetadataTypes();
return metadataTypes.find(type => type.xmlName == xmlName || type.childXmlNames?.includes(xmlName));
return metadataTypes.find(type => type.name == xmlName || type.childXmlNames?.includes(xmlName));
}

private async getComponentType(file: string) : Promise<string| undefined> {
Expand All @@ -506,18 +506,18 @@ export class SalesforcePackageBuilder {
if (type.isBundle) {
// match parent folder only for bundles
if (parentFolder == type.directoryName){
return type.xmlName;
return type.name;
}
} else if (folder == type.directoryName) {
return type.xmlName;
return type.name;
}
}
}

// Suffix check
const fileSuffix = this.getFileSuffix(file)?.toLocaleLowerCase();
if (fileSuffix) {
return this.metadataRegistry.getMetadataTypeBySuffix(fileSuffix)?.xmlName;
return this.metadataRegistry.getMetadataTypeBySuffix(fileSuffix)?.name;
}
}

Expand Down Expand Up @@ -555,7 +555,7 @@ export class SalesforcePackageBuilder {
return xmlName;
}

const metadataType = xmlName && metadataTypes.find(type => type.xmlName == xmlName || type.childXmlNames?.includes(xmlName!));
const metadataType = xmlName && metadataTypes.find(type => type.name == xmlName || type.childXmlNames?.includes(xmlName!));
if (metadataType) {
return xmlName;
}
Expand Down
5 changes: 4 additions & 1 deletion packages/util/src/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@ interface EventEmitOptions {
/**
* Propagate exceptions to the emitting class, only works the handler is not-async. Whne async is passed as true exceptions are always hidden.
* _Note: even when exceptions are hidden they will still be logged using console.error log for debugging purposes._
* @default false
*/
hideExceptions?: boolean;
/**
* Queues handler execution util after the next event loop processing using `setImmediatePromise`. Async processing of the event forces `hideExceptions` to `true`.
* Queues handler execution util after the next event loop processing using `setImmediatePromise`.
* Async processing of the event forces `hideExceptions` to `true`.
* @default false
*/
async?: boolean;
}
Expand Down
23 changes: 22 additions & 1 deletion packages/vlocity-deploy/src/datapackDeployment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface DatapackDeploymentEvents {
afterDeployGroup: Iterable<DatapackDeploymentRecordGroup>;
onError: DatapackDeploymentRecord;
onCancel: DatapackDeployment;
progress: DatapackDeploymentProgress;
}

export interface DatapackDeploymentRecordMessage {
Expand All @@ -22,6 +23,11 @@ export interface DatapackDeploymentRecordMessage {
message: string;
}

export interface DatapackDeploymentProgress {
readonly progress: number;
readonly total: number;
}

type RecordPurgePredicate = (item: {
/**
* The name of the field on the {@link dependentRecord} that references the {@link record}
Expand Down Expand Up @@ -78,6 +84,15 @@ export class DatapackDeployment extends AsyncEventEmitter<DatapackDeploymentEven
return this.deployed.length;
}

public get pendingRecordCount() {
return this.totalRecordCount -
(
this.deployedRecordCount +
this.skippedRecordCount +
this.failedRecordCount
);
}

public get skippedRecordCount() {
return count(this.records.values(), r => r.isSkipped);
}
Expand Down Expand Up @@ -509,7 +524,7 @@ export class DatapackDeployment extends AsyncEventEmitter<DatapackDeploymentEven
}

try {
for await (const result of batch.execute(connection, this.handleProgressReport.bind(this), cancelToken)) {
for await (const result of batch.execute(connection, (progress) => this.handleProgressReport(progress), cancelToken)) {
const datapackRecord = datapackRecords.get(result.ref);

if (!datapackRecord) {
Expand Down Expand Up @@ -575,6 +590,12 @@ export class DatapackDeployment extends AsyncEventEmitter<DatapackDeploymentEven
}

private handleProgressReport({ processed, total }) {
const progress = {
// Currently deployed + records deployed in current batch
progress: this.deployedRecordCount + this.failedRecordCount + this.skippedRecordCount,
total: this.totalRecordCount
}
void this.emit('progress', progress, { hideExceptions: true, async: true });
this.logger.verbose(`Deployment in progress ${processed}/${total}...`);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export class DeployDatapackCommand extends DatapackCommand {
const progressText = await this.getProgressText(datapackHeaders);
await this.vlocode.withCancelableProgress(progressText, async (progress, token) => {
await this.saveUnsavedChangesInDatapacks(datapackHeaders);
await this.strategy.deploy(datapackHeaders, token);
await this.strategy.deploy(datapackHeaders, progress, token);
if (token.isCancellationRequested) {
void vscode.window.showWarningMessage('Datapack deployment cancelled');
}
Expand Down
3 changes: 2 additions & 1 deletion packages/vscode-extension/src/lib/vlocity/vlocityDeploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import * as vscode from 'vscode';
*/
export interface VlocityDeploy {
deploy(
datapackHeaders: vscode.Uri[],
datapackHeaders: vscode.Uri[],
progress?: vscode.Progress<{message?: string, progress?: number; total?: number }>,
cancellationToken?: vscode.CancellationToken
): Promise<void> | void
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ export class VlocityToolsDeployment implements VlocityDeploy {
private readonly logger: Logger) {
}

public async deploy(datapackHeaders: vscode.Uri[], cancellationToken: vscode.CancellationToken) {
async deploy(
datapackHeaders: vscode.Uri[],
progress: vscode.Progress<{ progress?: number; total?: number }>,
cancellationToken: vscode.CancellationToken
) {
const results = await this.datapackService.deploy(datapackHeaders.map(header => header.fsPath), cancellationToken);
if (!cancellationToken.isCancellationRequested) {
this.printDatapackDeployResults(results);
Expand Down
13 changes: 10 additions & 3 deletions packages/vscode-extension/src/lib/vlocity/vlocodeDirectDeploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ export class VlocodeDirectDeployment implements VlocityDeploy {
private readonly logger: Logger) {
}

async deploy(datapackHeaders: vscode.Uri[], cancellationToken: vscode.CancellationToken) {
async deploy(
datapackHeaders: vscode.Uri[],
progress: vscode.Progress<{ progress?: number; total?: number }>,
cancellationToken: vscode.CancellationToken
) {
const datapacks = await this.datapackService.loadAllDatapacks(datapackHeaders, cancellationToken);
const deployment = await this.datapackDeployer.createDeployment(datapacks, {
// TODO: allow user to override these from options
Expand All @@ -25,6 +29,9 @@ export class VlocodeDirectDeployment implements VlocityDeploy {
continueOnError: true,
maxRetries: 1,
}, cancellationToken);
deployment.on('progress', result => {
progress.report({ progress: result.progress, total: result.total });
});
await deployment?.start(cancellationToken);

if (cancellationToken.isCancellationRequested) {
Expand All @@ -45,9 +52,9 @@ export class VlocodeDirectDeployment implements VlocityDeploy {
this.logger.error(` ${i + 1}. ${chalk.underline(messages[i].record.sourceKey)} -- ${this.formatError(messages[i].message)}`);
}
}
void vscode.window.showWarningMessage(`Datapack deployment completed with errors: unable to update/insert ${deployment.failedRecordCount} records`);
void vscode.window.showWarningMessage(`Deployed ${datapacks.length} datapacks with ${deployment.failedRecordCount} errors`);
} else {
void vscode.window.showInformationMessage(`Successfully deployed ${datapacks.length} datapacks`);
void vscode.window.showInformationMessage(`Deployed ${datapacks.length} datapacks`);
}
}

Expand Down

0 comments on commit 3890ec1

Please sign in to comment.