Skip to content

Commit 63f6808

Browse files
authored
Merge pull request #351 from shaurabh-tiwari-git/enableLWCwithApexEnhancements
@W-19092866 - Enabling LWC and some apex enhancements
2 parents a5c8335 + 6d485c2 commit 63f6808

File tree

12 files changed

+405
-228
lines changed

12 files changed

+405
-228
lines changed

messages/assess.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@
7878
"foundApexFilesInDirectory": "Found %s Apex files in directory: %s",
7979
"skippingNonApexFile": "Skipping non-Apex file: %s",
8080
"processingApexFile": "Processing Apex file: %s",
81-
"skippingApexFileFewChanges": "Skipping Apex file: %s as it has less than 3 changes",
81+
"skippingApexFileNoChanges": "Skipping Apex file: %s as it has no changes",
8282
"successfullyProcessedApexFile": "Successfully processed Apex file: %s",
8383
"fileNoOmnistudioCalls": "File %s does not have any omnistudio calls or remote calls. No changes will be applied.",
8484
"fileAlreadyImplementsCallable": "file %s already implements callable no changes will be applied",

src/commands/omnistudio/migration/assess.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ export default class Assess extends OmniStudioBaseCommand {
7575
const conn = this.org.getConnection();
7676
let objectsToProcess: string[];
7777
// To-Do: Add LWC to valid options when GA is released
78-
const validOptions = [Constants.Apex, Constants.ExpSites, Constants.FlexiPage];
78+
const validOptions = [Constants.Apex, Constants.ExpSites, Constants.FlexiPage, Constants.LWC];
7979
if (apiVersion) {
8080
conn.setApiVersion(apiVersion);
8181
} else {
@@ -140,6 +140,8 @@ export default class Assess extends OmniStudioBaseCommand {
140140

141141
// Assess related objects if specified
142142
if (relatedObjects) {
143+
objectsToProcess = relatedObjects.split(',').map((obj) => obj.trim());
144+
143145
// Validate input
144146
for (const obj of objectsToProcess) {
145147
if (!validOptions.includes(obj)) {

src/commands/omnistudio/migration/migrate.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,7 @@ export default class Migrate extends OmniStudioBaseCommand {
135135
const preMigrate: PreMigrate = new PreMigrate(this.org, namespace, conn, this.logger, messages, this.ux);
136136
const isExperienceBundleMetadataAPIProgramaticallyEnabled: { value: boolean } = { value: false };
137137
if (relatedObjects) {
138-
// To-Do: Add LWC to valid options when GA is released
139-
const validOptions = [Constants.Apex, Constants.ExpSites, Constants.FlexiPage];
138+
const validOptions = [Constants.Apex, Constants.ExpSites, Constants.FlexiPage, Constants.LWC];
140139
objectsToProcess = relatedObjects.split(',').map((obj) => obj.trim());
141140
// Validate input
142141
for (const obj of objectsToProcess) {

src/migration/base.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ import { Logger } from '../utils/logger';
88
import { TransformData, UploadRecordResult } from './interfaces';
99

1010
export type ComponentType = 'Data Mapper' | 'Flexcard' | 'Omniscript and Integration Procedure' | 'GlobalAutoNumber';
11-
12-
export type RelatedObjectType = 'Flexipage' | 'ExperienceSites';
11+
export type RelatedObjectType = 'Flexipage' | 'ExperienceSites' | 'Lightning Web Components' | 'Apex Classes';
1312

1413
/**
1514
* Creates a progress bar for migration/assessment operations

src/migration/related/ApexMigration.ts

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,19 @@ import {
1313
SingleTokenUpdate,
1414
TokenUpdater,
1515
} from '../../utils/apex/parser/apexparser';
16-
import { sfProject } from '../../utils/sfcli/project/sfProject';
1716
import { FileUtil, File } from '../../utils/file/fileUtil';
1817
import { Logger } from '../../utils/logger';
1918
import { ApexAssessmentInfo } from '../../utils';
2019
import { FileDiffUtil } from '../../utils/lwcparser/fileutils/FileDiffUtil';
2120
import { Stringutil } from '../../utils/StringValue/stringutil';
2221
import { Constants } from '../../utils/constants/stringContants';
22+
import { ComponentType, createProgressBar } from '../base';
2323
import { BaseRelatedObjectMigration } from './BaseRealtedObjectMigration';
2424

2525
Messages.importMessagesDirectory(__dirname);
2626
const assessMessages = Messages.loadMessages('@salesforce/plugin-omnistudio-migration-tool', 'assess');
2727
const migrateMessages = Messages.loadMessages('@salesforce/plugin-omnistudio-migration-tool', 'migrate');
2828

29-
const APEXCLASS = 'Apexclass';
3029
const APEX_CLASS_PATH = '/force-app/main/default/classes';
3130
const CALLABLE = 'System.Callable';
3231
const VLOCITY_OPEN_INTERFACE2 = 'VlocityOpenInterface2';
@@ -57,15 +56,12 @@ export class ApexMigration extends BaseRelatedObjectMigration {
5756
Logger.logVerbose(migrateMessages.getMessage('startingApexMigration', [this.projectPath]));
5857
const pwd = shell.pwd();
5958
shell.cd(this.projectPath);
60-
// const targetOrg: Org = this.org;
61-
// sfProject.retrieve(APEXCLASS, targetOrg.getUsername());
6259
Logger.info(migrateMessages.getMessage('processingApexFilesForMigration'));
6360
const apexAssessmentInfos = this.processApexFiles(this.projectPath, 'migration');
6461
Logger.info(migrateMessages.getMessage('successfullyProcessedApexFilesForMigration', [apexAssessmentInfos.length]));
6562
Logger.logVerbose(
6663
migrateMessages.getMessage('apexMigrationResults', [JSON.stringify(apexAssessmentInfos, null, 2)])
6764
);
68-
// sfProject.deploy(APEXCLASS, targetOrg.getUsername());
6965
shell.cd(pwd);
7066
return apexAssessmentInfos;
7167
}
@@ -74,7 +70,6 @@ export class ApexMigration extends BaseRelatedObjectMigration {
7470
Logger.logVerbose(assessMessages.getMessage('startingApexAssessment', [this.projectPath]));
7571
const pwd = shell.pwd();
7672
shell.cd(this.projectPath);
77-
sfProject.retrieve(APEXCLASS, this.org.getUsername());
7873
Logger.info(assessMessages.getMessage('processingApexFilesForAssessment'));
7974
const apexAssessmentInfos = this.processApexFiles(this.projectPath, 'assessment');
8075
Logger.info(assessMessages.getMessage('successfullyProcessedApexFilesForAssessment', [apexAssessmentInfos.length]));
@@ -89,25 +84,40 @@ export class ApexMigration extends BaseRelatedObjectMigration {
8984
let files: File[] = [];
9085
files = FileUtil.readFilesSync(dir);
9186
Logger.logVerbose(assessMessages.getMessage('foundApexFilesInDirectory', [files.length, dir]));
87+
const progressBar =
88+
type.toLowerCase() === 'migration'
89+
? createProgressBar('Migrating', Constants.ApexComponentName as ComponentType)
90+
: createProgressBar('Assessing', Constants.ApexComponentName as ComponentType);
91+
let progressCounter = 0;
92+
// Only show progress bar if verbose mode is disabled
93+
progressBar.start(files.length, progressCounter);
9294
const fileAssessmentInfo: ApexAssessmentInfo[] = [];
95+
const processingErrorsList: string[] = [];
9396
for (const file of files) {
9497
if (file.ext !== '.cls') {
9598
Logger.logVerbose(assessMessages.getMessage('skippingNonApexFile', [file.name]));
99+
progressBar.update(++progressCounter);
96100
continue;
97101
}
98102
try {
99103
Logger.logVerbose(assessMessages.getMessage('processingApexFile', [file.name]));
100104
const apexAssementInfo = this.processApexFile(file, type);
101105
if (apexAssementInfo && apexAssementInfo.diff.length < 3) {
102-
Logger.logVerbose(assessMessages.getMessage('skippingApexFileFewChanges', [file.name]));
106+
Logger.logVerbose(assessMessages.getMessage('skippingApexFileNoChanges', [file.name]));
107+
progressBar.update(++progressCounter);
103108
continue;
104109
}
105110
fileAssessmentInfo.push(apexAssementInfo);
106111
Logger.logVerbose(assessMessages.getMessage('successfullyProcessedApexFile', [file.name]));
112+
progressBar.update(++progressCounter);
107113
} catch (err) {
108-
Logger.error(assessMessages.getMessage('errorProcessingApexFile', [file.name]), err);
114+
processingErrorsList.push(assessMessages.getMessage('errorProcessingApexFile', [file.name]));
115+
progressBar.update(++progressCounter);
109116
}
110-
Logger.logVerbose(assessMessages.getMessage('successfullyProcessedApexFile', [file.name]));
117+
}
118+
progressBar.stop();
119+
if (processingErrorsList.length > 0) {
120+
Logger.error(processingErrorsList.join('\n'));
111121
}
112122
return fileAssessmentInfo;
113123
}
@@ -191,7 +201,10 @@ export class ApexMigration extends BaseRelatedObjectMigration {
191201
tokenUpdates.push(new RangeTokenUpdate(CALLABLE, tokens[0], tokens[1]));
192202
tokenUpdates.push(new InsertAfterTokenUpdate(this.callMethodBody(), parser.classDeclaration));
193203
} else if (implementsInterface.has(this.vlocityOpenInterface)) {
194-
Logger.error(assessMessages.getMessage('fileImplementsVlocityOpenInterface', [file.name]));
204+
Logger.logger.info(assessMessages.getMessage('fileImplementsVlocityOpenInterface', [file.name]));
205+
const tokens = implementsInterface.get(this.vlocityOpenInterface);
206+
tokenUpdates.push(new RangeTokenUpdate(CALLABLE, tokens[0], tokens[1]));
207+
tokenUpdates.push(new InsertAfterTokenUpdate(this.callMethodBody(), parser.classDeclaration));
195208
}
196209
return tokenUpdates;
197210
}
@@ -260,7 +273,6 @@ export class ApexMigration extends BaseRelatedObjectMigration {
260273
const newName = `'${Stringutil.cleanName(token.text)}'`;
261274
if (token.text === newName) continue;
262275
Logger.info(assessMessages.getMessage('inApexDrNameWillBeUpdated', [file.name, token.text, newName]));
263-
Logger.log(assessMessages.getMessage('inApexDrNameWillBeUpdated', [file.name, token.text, newName]));
264276
tokenUpdates.push(new SingleTokenUpdate(newName, token));
265277
}
266278
}

src/migration/related/LwcMigration.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
/* eslint-disable @typescript-eslint/no-shadow */
22
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
3-
import * as shell from 'shelljs';
43
import { Messages } from '@salesforce/core';
4+
import * as shell from 'shelljs';
55
import { FileUtil, File } from '../../utils/file/fileUtil';
6-
import { sfProject } from '../../utils/sfcli/project/sfProject';
76
import { Logger } from '../../utils/logger';
87
import { FileProcessorFactory } from '../../utils/lwcparser/fileutils/FileProcessorFactory';
98
import { FileChangeInfo, LWCAssessmentInfo } from '../../utils';
109
import { Constants } from '../../utils/constants/stringContants';
10+
import { ComponentType, createProgressBar } from '../base';
1111
import { BaseRelatedObjectMigration } from './BaseRealtedObjectMigration';
1212

1313
Messages.importMessagesDirectory(__dirname);
1414
const assessMessages = Messages.loadMessages('@salesforce/plugin-omnistudio-migration-tool', 'assess');
1515
const migrateMessages = Messages.loadMessages('@salesforce/plugin-omnistudio-migration-tool', 'migrate');
1616

1717
const LWC_DIR_PATH = '/force-app/main/default/lwc';
18-
const LWCTYPE = 'LightningComponentBundle';
1918

2019
export class LwcMigration extends BaseRelatedObjectMigration {
2120
public processObjectType(): string {
@@ -33,7 +32,6 @@ export class LwcMigration extends BaseRelatedObjectMigration {
3332
const type = 'assessment';
3433
const pwd = shell.pwd();
3534
shell.cd(this.projectPath);
36-
sfProject.retrieve(LWCTYPE, this.org.getUsername());
3735
Logger.info(assessMessages.getMessage('processingLwcsForAssessment'));
3836
const filesMap = this.processLwcFiles(this.projectPath);
3937
Logger.info(assessMessages.getMessage('successfullyProcessedLwcsForAssessment', [filesMap.size]));
@@ -46,14 +44,11 @@ export class LwcMigration extends BaseRelatedObjectMigration {
4644
Logger.logVerbose(migrateMessages.getMessage('startingLwcMigration', [this.projectPath]));
4745
const pwd = shell.pwd();
4846
shell.cd(this.projectPath);
49-
// const targetOrg: Org = this.org;
50-
// sfProject.retrieve(LWCTYPE, targetOrg.getUsername());
5147
Logger.info(migrateMessages.getMessage('processingLwcsForMigration'));
5248
const filesMap = this.processLwcFiles(this.projectPath);
5349
const LWCAssessmentInfos = this.processFiles(filesMap, 'migration');
5450
Logger.info(migrateMessages.getMessage('successfullyProcessedLwcsForMigration', [LWCAssessmentInfos.length]));
5551
Logger.logVerbose(migrateMessages.getMessage('lwcMigrationResults', [JSON.stringify(LWCAssessmentInfos, null, 2)]));
56-
// sfProject.deploy(LWCTYPE, targetOrg.getUsername());
5752
shell.cd(pwd);
5853
return LWCAssessmentInfos;
5954
}
@@ -72,6 +67,12 @@ export class LwcMigration extends BaseRelatedObjectMigration {
7267

7368
// This method to process the parsing and return the LWCAssessmentInfo[]
7469
private processFiles(fileMap: Map<string, File[]>, type: string): LWCAssessmentInfo[] {
70+
const progressBar =
71+
type.toLowerCase() === 'migration'
72+
? createProgressBar('Migrating', Constants.LWCComponentName as ComponentType)
73+
: createProgressBar('Assessing', Constants.LWCComponentName as ComponentType);
74+
progressBar.start(fileMap.size, 0);
75+
let progressCounter = 0;
7576
try {
7677
const jsonData: LWCAssessmentInfo[] = [];
7778
fileMap.forEach((fileList, dir) => {
@@ -116,9 +117,12 @@ export class LwcMigration extends BaseRelatedObjectMigration {
116117
jsonData.push(assesmentInfo);
117118
}
118119
}
120+
progressBar.update(++progressCounter);
119121
});
122+
progressBar.stop();
120123
return jsonData;
121124
} catch (error) {
125+
progressBar.stop();
122126
Logger.error(assessMessages.getMessage('errorProcessingFiles'), error);
123127
}
124128
}

src/migration/related/OmnistudioRelatedObjectMigrationFacade.ts

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ Messages.importMessagesDirectory(__dirname);
2424
const assessMessages = Messages.loadMessages('@salesforce/plugin-omnistudio-migration-tool', 'assess');
2525
const migrateMessages = Messages.loadMessages('@salesforce/plugin-omnistudio-migration-tool', 'migrate');
2626

27-
// TODO: Uncomment code once MVP for migration is completed
28-
// const LWCTYPE = 'LightningComponentBundle';
27+
const LWCTYPE = 'LightningComponentBundle';
2928
const APEXCLASS = 'Apexclass';
3029
const EXPERIENCEBUNDLE = 'EXPERIENCEBUNDLE';
3130

@@ -62,8 +61,7 @@ export default class OmnistudioRelatedObjectMigrationFacade {
6261
// Initialize migration instances
6362
this.apexMigration = new ApexMigration(this.projectPath, this.namespace, this.org, targetApexNamespace);
6463
this.flexipageMigration = new FlexipageMigration(this.projectPath, this.namespace, this.org, assessMessages);
65-
// TODO: Uncomment code once MVP for migration is completed
66-
// this.lwcMigration = new LwcMigration(this.projectPath, this.namespace, this.org);
64+
this.lwcMigration = new LwcMigration(this.projectPath, this.namespace, this.org);
6765

6866
this.experienceSiteMigration = new ExperienceSiteMigration(
6967
this.projectPath,
@@ -81,10 +79,9 @@ export default class OmnistudioRelatedObjectMigrationFacade {
8179
private retrieveMetadata(relatedObjects: string[]): void {
8280
const pwd = shell.pwd();
8381
shell.cd(this.projectPath);
84-
// TODO: Uncomment code once MVP for migration is completed
85-
// if (relatedObjects.includes(Constants.LWC)) {
86-
// // sfProject.retrieve(LWCTYPE, this.org.getUsername());
87-
// }
82+
if (relatedObjects.includes(Constants.LWC)) {
83+
sfProject.retrieve(LWCTYPE, this.org.getUsername());
84+
}
8885
if (relatedObjects.includes(Constants.Apex)) {
8986
sfProject.retrieve(APEXCLASS, this.org.getUsername());
9087
}
@@ -111,7 +108,7 @@ export default class OmnistudioRelatedObjectMigrationFacade {
111108
debugTimer.start();
112109

113110
let apexAssessmentInfos: ApexAssessmentInfo[] = [];
114-
const lwcAssessmentInfos: LWCAssessmentInfo[] = [];
111+
let lwcAssessmentInfos: LWCAssessmentInfo[] = [];
115112
let experienceSiteAssessmentInfos: ExperienceSiteAssessmentInfo[] = [];
116113
let flexipageAssessmentInfos: FlexiPageAssessmentInfo[] = [];
117114

@@ -129,19 +126,13 @@ export default class OmnistudioRelatedObjectMigrationFacade {
129126
if (relatedObjects.includes(Constants.FlexiPage)) {
130127
flexipageAssessmentInfos = isMigration ? this.flexipageMigration.migrate() : this.flexipageMigration.assess();
131128
}
129+
if (relatedObjects.includes(Constants.LWC)) {
130+
lwcAssessmentInfos = isMigration ? this.lwcMigration.migrate() : this.lwcMigration.assessment();
131+
}
132132
} catch (error) {
133133
// Log the error
134134
Logger.error('Error processing related objects', error);
135135
}
136-
// TODO: Uncomment code once MVP for migration is completed
137-
// try {
138-
// if (relatedObjects.includes(Constants.LWC)) {
139-
// Logger.logVerbose(migrateMessages.getMessage('startingLwcMigration', [this.projectPath]));
140-
// lwcAssessmentInfos = isMigration ? this.lwcMigration.migrate() : this.lwcMigration.assessment();
141-
// }
142-
// } catch (Error) {
143-
// Logger.error(Error.message);
144-
// }
145136

146137
// Stop the debug timer
147138
const timer = debugTimer.stop();

src/utils/constants/stringContants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,6 @@ export const Constants = {
2222
GlobalAutoNumberComponentName: 'GlobalAutoNumber',
2323
GlobalAutoNumberPluralName: 'GlobalAutoNumbers',
2424
ApexRemoteComponentName: 'ApexRemote',
25+
LWCComponentName: 'Lightning Web Component',
26+
ApexComponentName: 'Apex Classes',
2527
};

src/utils/resultsbuilder/ApexAssessmentReporter.ts

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ export class ApexAssessmentReporter {
7878
1,
7979
false,
8080
undefined,
81-
undefined,
81+
apexAssessmentInfo.warnings.length > 0 ? 'Has Warnings' : 'Can be Automated',
8282
apexAssessmentInfo.warnings.length > 0 ? 'text-error' : 'text-success'
8383
),
8484
createRowDataParam(
@@ -117,16 +117,11 @@ export class ApexAssessmentReporter {
117117

118118
private static getFilterGroupsForReport(apexAssessmentInfos: ApexAssessmentInfo[]): FilterGroupParam[] {
119119
return [
120-
createFilterGroupParam(
121-
'Filter By Summary',
122-
'comments',
123-
Array.from(new Set(apexAssessmentInfos.map((row: ApexAssessmentInfo) => row.infos.join(', '))))
124-
),
125-
createFilterGroupParam(
126-
'Filter By Errors',
127-
'errors',
128-
Array.from(new Set(apexAssessmentInfos.map((row: ApexAssessmentInfo) => row.warnings.join(', '))))
129-
),
120+
createFilterGroupParam('Filter By Assessment Status', 'status', [
121+
'Can be Automated',
122+
'Has Warnings',
123+
'Has Errors',
124+
]),
130125
];
131126
}
132127

0 commit comments

Comments
 (0)