Skip to content

Commit f7f495f

Browse files
committed
feat: performance marks
1 parent 4adb3c2 commit f7f495f

File tree

4 files changed

+205
-11
lines changed

4 files changed

+205
-11
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
"node": ">=16.0.0"
4747
},
4848
"dependencies": {
49+
"@oclif/core": "^2.15.0",
4950
"@salesforce/core": "^5.2.0",
5051
"@salesforce/kit": "^3.0.9",
5152
"@salesforce/source-deploy-retrieve": "^9.7.15",

src/shared/localShadowRepo.ts

+18
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import * as fs from 'graceful-fs';
1111
import { NamedPackageDir, Logger, SfError } from '@salesforce/core';
1212
import { env } from '@salesforce/kit';
1313
import * as git from 'isomorphic-git';
14+
import { Performance } from '@oclif/core';
1415
import { chunkArray, isLwcLocalOnlyTest, pathIsInFolder } from './functions';
1516

1617
/** returns the full path to where we store the shadow repo */
@@ -105,6 +106,7 @@ export class ShadowRepo {
105106
*
106107
*/
107108
public async gitInit(): Promise<void> {
109+
this.logger.trace(`initializing git repo at ${this.gitDir}`);
108110
await fs.promises.mkdir(this.gitDir, { recursive: true });
109111
try {
110112
await git.init({ fs, dir: this.projectPath, gitdir: this.gitDir, defaultBranch: 'main' });
@@ -135,7 +137,10 @@ export class ShadowRepo {
135137
* @returns StatusRow[]
136138
*/
137139
public async getStatus(noCache = false): Promise<StatusRow[]> {
140+
this.logger.trace(`start: getStatus (noCache = ${noCache})`);
141+
138142
if (!this.status || noCache) {
143+
const marker = Performance.mark('@salesforce/source-tracking', 'localShadowRepo.getStatus#withoutCache');
139144
// iso-git uses relative, posix paths
140145
// but packageDirs has already resolved / normalized them
141146
// so we need to make them project-relative again and convert if windows
@@ -168,7 +173,9 @@ export class ShadowRepo {
168173
if (this.isWindows) {
169174
this.status = this.status.map((row) => [path.normalize(row[FILE]), row[HEAD], row[WORKDIR], row[3]]);
170175
}
176+
marker?.stop();
171177
}
178+
this.logger.trace(`done: getStatus (noCache = ${noCache})`);
172179
return this.status;
173180
}
174181

@@ -247,16 +254,23 @@ export class ShadowRepo {
247254
return 'no files to commit';
248255
}
249256

257+
const marker = Performance.mark('@salesforce/source-tracking', 'localShadowRepo.commitChanges', {
258+
deployedFiles: deployedFiles.length,
259+
deletedFiles: deletedFiles.length,
260+
});
250261
// these are stored in posix/style/path format. We have to convert inbound stuff from windows
251262
if (os.type() === 'Windows_NT') {
263+
this.logger.trace('start: transforming windows paths to posix');
252264
deployedFiles = deployedFiles.map((filepath) => path.normalize(filepath).split(path.sep).join(path.posix.sep));
253265
deletedFiles = deletedFiles.map((filepath) => path.normalize(filepath).split(path.sep).join(path.posix.sep));
266+
this.logger.trace('done: transforming windows paths to posix');
254267
}
255268

256269
if (deployedFiles.length) {
257270
const chunks = chunkArray([...new Set(deployedFiles)], this.maxFileAdd);
258271
for (const chunk of chunks) {
259272
try {
273+
this.logger.debug(`adding ${chunk.length} files of ${deployedFiles.length} deployedFiles to git`);
260274
// these need to be done sequentially (it's already batched) because isogit manages file locking
261275
// eslint-disable-next-line no-await-in-loop
262276
await git.add({
@@ -296,6 +310,8 @@ export class ShadowRepo {
296310
}
297311

298312
try {
313+
this.logger.trace('start: commitChanges git.commit');
314+
299315
const sha = await git.commit({
300316
fs,
301317
dir: this.projectPath,
@@ -307,9 +323,11 @@ export class ShadowRepo {
307323
if (needsUpdatedStatus) {
308324
await this.getStatus(true);
309325
}
326+
this.logger.trace('done: commitChanges git.commit');
310327
return sha;
311328
} catch (e) {
312329
redirectToCliRepoError(e as Error);
313330
}
331+
marker?.stop();
314332
}
315333
}

src/sourceTracking.ts

+15-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {
2828
} from '@salesforce/source-deploy-retrieve';
2929
// this is not exported by SDR (see the comments in SDR regarding its limitations)
3030
import { filePathsFromMetadataComponent } from '@salesforce/source-deploy-retrieve/lib/src/utils/filePathGenerator';
31+
import { Performance } from '@oclif/core';
3132
import { RemoteSourceTrackingService, remoteChangeElementToChangeResult } from './shared/remoteSourceTrackingService';
3233
import { ShadowRepo } from './shared/localShadowRepo';
3334
import { throwIfConflicts, findConflictsInComponentSet, getDedupedConflictsFromChanges } from './shared/conflicts';
@@ -409,6 +410,9 @@ export class SourceTracking extends AsyncCreatable {
409410
* @param options the files to update
410411
*/
411412
public async updateLocalTracking(options: LocalUpdateOptions): Promise<void> {
413+
this.logger.trace('start: updateLocalTracking', options);
414+
const marker = Performance.mark('@salesforce/source-tracking', 'SourceTracking.updateLocalTracking');
415+
marker?.addDetails({ nonDeletes: options.files?.length ?? 0, deletes: options.deletedFiles?.length ?? 0 });
412416
await this.ensureLocalTracking();
413417

414418
// relative paths make smaller trees AND isogit wants them relative
@@ -444,20 +448,25 @@ export class SourceTracking extends AsyncCreatable {
444448
)
445449
),
446450
});
451+
marker?.stop();
452+
this.logger.trace('done: updateLocalTracking', options);
447453
}
448454

449455
/**
450456
* Mark remote source tracking files so say that we have received the latest version from the server
451457
* Optional skip polling for the SourceMembers to exist on the server and be updated in local files
452458
*/
453459
public async updateRemoteTracking(fileResponses: RemoteSyncInput[], skipPolling = false): Promise<void> {
460+
const marker = Performance.mark('@salesforce/source-tracking', 'SourceTracking.updateRemoteTracking');
461+
marker?.addDetails({ fileResponseCount: fileResponses.length, skipPolling });
454462
// false to explicitly NOT query until we do the polling
455463
await this.ensureRemoteTracking(false);
456464
if (!skipPolling) {
457465
// poll to make sure we have the updates before syncing the ones from metadataKeys
458466
await this.remoteSourceTrackingService.pollForSourceTracking(fileResponses);
459467
}
460468
await this.remoteSourceTrackingService.syncSpecifiedElements(fileResponses);
469+
marker?.stop();
461470
}
462471

463472
public async reReadLocalTrackingCache(): Promise<void> {
@@ -550,6 +559,8 @@ export class SourceTracking extends AsyncCreatable {
550559
* Compares local and remote changes to detect conflicts
551560
*/
552561
public async getConflicts(): Promise<ChangeResult[]> {
562+
const marker = Performance.mark('@salesforce/source-tracking', 'SourceTracking.getConflicts');
563+
553564
// we're going to need have both initialized
554565
await Promise.all([this.ensureRemoteTracking(), this.ensureLocalTracking()]);
555566

@@ -574,12 +585,15 @@ export class SourceTracking extends AsyncCreatable {
574585
}
575586
this.forceIgnore ??= ForceIgnore.findAndCreate(this.project.getDefaultPackage().path);
576587

577-
return getDedupedConflictsFromChanges({
588+
const result = getDedupedConflictsFromChanges({
578589
localChanges,
579590
remoteChanges,
580591
projectPath: this.projectPath,
581592
forceIgnore: this.forceIgnore,
582593
});
594+
595+
marker?.stop();
596+
return result;
583597
}
584598

585599
/**

0 commit comments

Comments
 (0)