Skip to content

Commit 6e76812

Browse files
committed
feat: typed push
1 parent 5da6648 commit 6e76812

File tree

4 files changed

+26
-9
lines changed

4 files changed

+26
-9
lines changed

README.md

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ You should use the class named sourceTracking
99
## TODO
1010

1111
push: wait and ignoreWarnings logic
12-
consolidate the conflict logic into SourceTrackingOperations. Should return a ChangeResult[] of the conflicts so commands can display.
1312
reorganize the getChanges logic to be more use-friendly (nonDeletes, option or <type> to specify return structure)
1413
can migrate maxRevision.json to its new home
1514
after pushing ebikes, toolbelt shows no remote changes but STL shows the Admin Profile being changed

src/commands/source/push.ts

+19-4
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,32 @@
66
*/
77

88
import { FlagsConfig, flags, SfdxCommand } from '@salesforce/command';
9+
import { Duration } from '@salesforce/kit';
910
import { SfdxProject, Org } from '@salesforce/core';
10-
import { FileResponse } from '@salesforce/source-deploy-retrieve';
11+
import { PushPullResponse } from '../../shared/types';
1112
import { SourceTracking } from '../../sourceTracking';
1213
import { writeConflictTable } from '../../writeConflictTable';
1314
export default class SourcePush extends SfdxCommand {
1415
public static description = 'get local changes';
1516
protected static readonly flagsConfig: FlagsConfig = {
1617
forceoverwrite: flags.boolean({ char: 'f', description: 'overwrite files without prompting' }),
18+
// TODO: use shared flags from plugin-source
19+
wait: flags.minutes({
20+
char: 'w',
21+
default: Duration.minutes(33),
22+
min: Duration.minutes(0), // wait=0 means deploy is asynchronous
23+
description: 'tbd',
24+
}),
1725
};
26+
1827
protected static requiresUsername = true;
1928
protected static requiresProject = true;
29+
2030
protected project!: SfdxProject; // ok because requiresProject
2131
protected org!: Org; // ok because requiresUsername
2232

2333
// eslint-disable-next-line @typescript-eslint/no-explicit-any
24-
public async run(): Promise<FileResponse[]> {
34+
public async run(): Promise<PushPullResponse[]> {
2535
const tracking = new SourceTracking({
2636
org: this.org,
2737
project: this.project,
@@ -35,7 +45,7 @@ export default class SourcePush extends SfdxCommand {
3545
}
3646
const deployResult = await tracking.deployLocalChanges({
3747
ignoreWarnings: this.flags.ignorewarnings as boolean,
38-
wait: this.flags.wait as number,
48+
wait: this.flags.wait as Duration,
3949
});
4050

4151
// TODO: convert deployResult to the proper type
@@ -44,6 +54,11 @@ export default class SourcePush extends SfdxCommand {
4454
this.ux.logJson(deployResult);
4555
}
4656

47-
return deployResult;
57+
return deployResult.map((fileResponse) => ({
58+
state: fileResponse.state,
59+
fullName: fileResponse.fullName,
60+
type: fileResponse.type,
61+
filePath: fileResponse.filePath,
62+
}));
4863
}
4964
}

src/shared/types.ts

+2
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@
88
import { FileResponse } from '@salesforce/source-deploy-retrieve';
99

1010
export type RemoteSyncInput = Pick<FileResponse, 'fullName' | 'filePath' | 'type'>;
11+
12+
export type PushPullResponse = Pick<FileResponse, 'filePath' | 'fullName' | 'state' | 'type'>;

src/sourceTracking.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77
import * as path from 'path';
88
import { NamedPackageDir, Logger, Org, SfdxProject } from '@salesforce/core';
9+
import { Duration } from '@salesforce/kit';
910
import {
1011
ComponentSet,
1112
MetadataResolver,
@@ -29,6 +30,7 @@ export const getKeyFromObject = (element: RemoteChangeElement | ChangeResult): s
2930
// external users of SDR might need to convert a fileResponse to a key
3031
export const getKeyFromStrings = getMetadataKey;
3132

33+
export type ChangeOptionTypes = ChangeResult | SourceComponent | string;
3234
export interface ChangeOptions {
3335
origin?: 'local' | 'remote';
3436
state: 'add' | 'delete' | 'changed' | 'unchanged' | 'moved';
@@ -71,8 +73,7 @@ export class SourceTracking {
7173
this.logger = Logger.childFromRoot('SourceTracking');
7274
}
7375

74-
public async deployLocalChanges({ ignoreWarnings = false, wait = 33 }): Promise<FileResponse[]> {
75-
// TODO: this is basically the logic for a push
76+
public async deployLocalChanges({ ignoreWarnings = false, wait = Duration.minutes(33) }): Promise<FileResponse[]> {
7677
await this.ensureLocalTracking();
7778
const [nonDeletes, deletes] = await Promise.all([
7879
this.localRepo.getNonDeleteFilenames(),
@@ -108,8 +109,8 @@ export class SourceTracking {
108109
.map((component) => componentSet.add(component, true));
109110

110111
// make SourceComponents from deletes and add to toDeploy
111-
const deploy = await componentSet.deploy({ usernameOrConnection: this.username });
112-
const result = await deploy.pollStatus();
112+
const deploy = await componentSet.deploy({ usernameOrConnection: this.username, apiOptions: { ignoreWarnings } });
113+
const result = await deploy.pollStatus(30, wait.seconds);
113114

114115
const successes = result.getFileResponses().filter((fileResponse) => fileResponse.state !== ComponentStatus.Failed);
115116
const successNonDeletes = successes.filter((fileResponse) => fileResponse.state !== ComponentStatus.Deleted);

0 commit comments

Comments
 (0)