Skip to content

Commit f1d0abf

Browse files
Replace force source status (#1197)
* fix: replace force:org:status * chore: cosnt * chore: replace depreacted org short-flag (u with o) * chore: forceignore nuts * test: remove sfdx NUTs * test: add cli back * test: fix NUT (maybe) --------- Co-authored-by: Willie Ruemmele <[email protected]>
1 parent faea743 commit f1d0abf

File tree

10 files changed

+146
-298
lines changed

10 files changed

+146
-298
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@
128128
"test:nuts:specialTypes:translations": "mocha \"test/nuts/specialTypes/translation.nut.ts\" --slow 4500 --timeout 1200000 --retries 0 --jobs 20",
129129
"test:nuts:static": "nyc mocha \"test/commands/**/*.nut.ts\" \"test/nuts/*.nut.ts\" --slow 4500 --timeout 1200000 --parallel --retries 0 --jobs 20",
130130
"test:nuts:tracking": "nyc mocha \"test/nuts/tracking/*.nut.ts\" --slow 4500 --timeout 1200000 --parallel --retries 0 --jobs 20",
131+
"test:nuts:tracking:forceignore": "nyc mocha \"test/nuts/tracking/forceignore.nut.ts\" --slow 4500 --timeout 1200000 --parallel --retries 0 --jobs 20",
131132
"test:only": "wireit",
132133
"version": "oclif readme"
133134
},

test/nuts/delete/source.nut.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ describe('project delete source NUTs', () => {
134134
const query = () =>
135135
execCmd<{ records: Array<{ IsNameObsolete: boolean }> }>(
136136
`data:query -q "SELECT IsNameObsolete FROM SourceMember WHERE MemberType='ApexClass' AND MemberName='${apexName}' LIMIT 1" -t --json`,
137-
{ silent: true, cli: 'sf', ensureExitCode: 0 }
137+
{ silent: true, ensureExitCode: 0, cli: 'sf' }
138138
);
139139

140140
let soql = query().jsonOutput?.result;
@@ -187,7 +187,7 @@ describe('project delete source NUTs', () => {
187187
// use the brokerCard LWC
188188
const lwcPath = path.join(testkit.projectDir, 'force-app', 'main', 'default', 'lwc', 'brokerCard', 'helper.js');
189189
fs.writeFileSync(lwcPath, '//', { encoding: 'utf8' });
190-
execCmd(`project:deploy:start --source-dir ${lwcPath}`, { cli: 'sf', ensureExitCode: 0 });
190+
execCmd(`project:deploy:start --source-dir ${lwcPath}`, { ensureExitCode: 0 });
191191
const deleteResult = execCmd<DeleteSourceJson>(`project:delete:source -p ${lwcPath} --no-prompt --json`).jsonOutput
192192
?.result;
193193
assert(deleteResult?.deletedSource);
@@ -232,7 +232,7 @@ describe('project delete source NUTs', () => {
232232
it('should delete an entire LWC', async () => {
233233
const lwcPath = path.join(testkit.projectDir, 'force-app', 'main', 'default', 'lwc');
234234
const mylwcPath = path.join(lwcPath, 'mylwc');
235-
execCmd(`force:lightning:component:create -n mylwc --type lwc -d ${lwcPath}`, { cli: 'sf', ensureExitCode: 0 });
235+
execCmd(`force:lightning:component:create -n mylwc --type lwc -d ${lwcPath}`, { ensureExitCode: 0, cli: 'sf' });
236236
execCmd(`project:deploy:start --source-dir ${mylwcPath}`);
237237
expect(await isNameObsolete(testkit.username, 'LightningComponentBundle', 'mylwc')).to.be.false;
238238
const deleteResult = execCmd<DeleteSourceJson>(`project:delete:source -p ${mylwcPath} --no-prompt --json`)

test/nuts/tracking/basics.nut.ts

Lines changed: 40 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,10 @@ import * as fs from 'node:fs';
1010
import { expect, assert } from 'chai';
1111
import { execCmd, TestSession } from '@salesforce/cli-plugins-testkit';
1212
import { DeployResultJson, RetrieveResultJson, isSdrFailure, isSdrSuccess } from '../../../src/utils/types.js';
13-
import { PreviewResult } from '../../../src/utils/previewOutput.js';
14-
import type { StatusResult } from './types.js';
13+
import { PreviewFile, PreviewResult } from '../../../src/utils/previewOutput.js';
1514
import { eBikesDeployResultCount } from './constants.js';
1615

17-
const filterIgnored = (r: StatusResult): boolean => r.ignored !== true;
16+
const filterIgnored = (r: PreviewFile): boolean => r.ignored !== true;
1817

1918
describe('end-to-end-test for tracking with an org (single packageDir)', () => {
2019
let session: TestSession;
@@ -48,16 +47,7 @@ describe('end-to-end-test for tracking with an org (single packageDir)', () => {
4847

4948
describe('basic status and pull', () => {
5049
it('detects the initial metadata status', () => {
51-
const result = execCmd<StatusResult[]>('force:source:status --json', {
52-
ensureExitCode: 0,
53-
cli: 'sf',
54-
}).jsonOutput?.result;
55-
assert(Array.isArray(result));
56-
// the fields should be populated
57-
expect(result.every((row) => row.type && row.fullName)).to.equal(true);
58-
});
59-
it('detects the initial metadata status using sf', () => {
60-
const response = execCmd<PreviewResult>('deploy metadata preview --json', {
50+
const response = execCmd<PreviewResult>('project deploy preview --json', {
6151
ensureExitCode: 0,
6252
}).jsonOutput?.result;
6353
assert(response);
@@ -67,7 +57,7 @@ describe('end-to-end-test for tracking with an org (single packageDir)', () => {
6757
expect(response.conflicts).to.be.an.instanceof(Array).with.length(0);
6858
});
6959
it('includes no wildcard entries', () => {
70-
const response = execCmd<PreviewResult>('deploy metadata preview --metadata ApexClass --json', {
60+
const response = execCmd<PreviewResult>('project deploy preview --metadata ApexClass --json', {
7161
ensureExitCode: 0,
7262
}).jsonOutput?.result;
7363
assert(response);
@@ -85,31 +75,28 @@ describe('end-to-end-test for tracking with an org (single packageDir)', () => {
8575
expect(files.every(isSdrSuccess), JSON.stringify(files.filter(isSdrFailure))).to.equal(true);
8676
});
8777
it('sees no local changes (all were committed from push), but profile updated in remote', () => {
88-
const localResult = execCmd<StatusResult[]>('force:source:status --json --local', {
78+
const localResult = execCmd<PreviewResult>('project deploy preview --json', {
8979
ensureExitCode: 0,
90-
cli: 'sf',
9180
}).jsonOutput?.result;
92-
expect(localResult?.filter(filterIgnored)).to.deep.equal([]);
81+
expect(localResult?.toDeploy.filter(filterIgnored)).to.deep.equal([]);
9382

94-
const remoteResult = execCmd<StatusResult[]>('force:source:status --json --remote', {
83+
const remoteResult = execCmd<PreviewResult>('project retrieve preview --json', {
9584
ensureExitCode: 0,
96-
cli: 'sf',
9785
}).jsonOutput?.result;
98-
expect(remoteResult?.some((item) => item.type === 'Profile')).to.equal(true);
86+
expect(remoteResult?.toRetrieve.some((item) => item.type === 'Profile')).to.equal(true);
9987
});
10088

101-
it('sf sees no local changes (all were committed from push)', () => {
102-
const response = execCmd<PreviewResult>('deploy metadata preview --json', {
89+
it('sees no local changes (all were committed from push)', () => {
90+
const response = execCmd<PreviewResult>('project deploy preview --json', {
10391
ensureExitCode: 0,
10492
}).jsonOutput?.result;
10593
expect(response?.toDeploy).to.be.an.instanceof(Array).with.lengthOf(0);
10694
});
107-
it('sf sees no remote changes (all were committed from push) except Profile', () => {
108-
const remoteResult = execCmd<StatusResult[]>('force:source:status --json --remote', {
95+
it('sees no remote changes (all were committed from push) except Profile', () => {
96+
const remoteResult = execCmd<PreviewResult>('project retrieve preview --json', {
10997
ensureExitCode: 0,
110-
cli: 'sf',
11198
}).jsonOutput?.result;
112-
expect(remoteResult?.some((item) => item.type === 'Profile')).to.equal(true);
99+
expect(remoteResult?.toRetrieve.some((item) => item.type === 'Profile')).to.equal(true);
113100
});
114101

115102
it('can pull the remote profile', () => {
@@ -123,23 +110,31 @@ describe('end-to-end-test for tracking with an org (single packageDir)', () => {
123110
});
124111

125112
it('sees no local or remote changes', () => {
126-
const result = execCmd<StatusResult[]>('force:source:status --json', {
113+
const deployResult = execCmd<PreviewResult>('project deploy preview --json', {
114+
ensureExitCode: 0,
115+
}).jsonOutput?.result;
116+
expect(
117+
deployResult?.toDeploy.filter((r) => r.type === 'Profile').filter(filterIgnored),
118+
JSON.stringify(deployResult)
119+
).to.have.length(0);
120+
121+
const retrieveResult = execCmd<PreviewResult>('project retrieve preview --json', {
127122
ensureExitCode: 0,
128-
cli: 'sf',
129123
}).jsonOutput?.result;
130-
expect(result?.filter((r) => r.type === 'Profile').filter(filterIgnored), JSON.stringify(result)).to.have.length(
131-
0
132-
);
124+
expect(
125+
retrieveResult?.toRetrieve.filter((r) => r.type === 'Profile').filter(filterIgnored),
126+
JSON.stringify(retrieveResult)
127+
).to.have.length(0);
133128
});
134129

135-
it('sf no local changes', () => {
136-
const response = execCmd<PreviewResult>('deploy metadata preview --json', {
130+
it('no local changes', () => {
131+
const response = execCmd<PreviewResult>('project deploy preview --json', {
137132
ensureExitCode: 0,
138133
}).jsonOutput?.result;
139134
expect(response?.toDeploy).to.be.an.instanceof(Array).with.lengthOf(0);
140135
});
141136

142-
it('sf deploy no local changes is not an error', () => {
137+
it('deploy no local changes is not an error', () => {
143138
const response = execCmd<DeployResultJson>('project deploy start --json', {
144139
ensureExitCode: 0,
145140
}).jsonOutput?.result;
@@ -152,38 +147,11 @@ describe('end-to-end-test for tracking with an org (single packageDir)', () => {
152147
fs.promises.unlink(path.join(classDir, 'TestOrderController.cls')),
153148
fs.promises.unlink(path.join(classDir, 'TestOrderController.cls-meta.xml')),
154149
]);
155-
const result = execCmd<StatusResult[]>('force:source:status --json --local', {
156-
ensureExitCode: 0,
157-
cli: 'sf',
158-
}).jsonOutput?.result;
159-
expect(result?.filter(filterIgnored)).to.deep.equal([
160-
{
161-
type: 'ApexClass',
162-
state: 'Local Deleted',
163-
fullName: 'TestOrderController',
164-
filePath: path.normalize('force-app/main/default/classes/TestOrderController.cls'),
165-
ignored: false,
166-
actualState: 'Deleted',
167-
origin: 'Local',
168-
},
169-
{
170-
type: 'ApexClass',
171-
state: 'Local Deleted',
172-
fullName: 'TestOrderController',
173-
filePath: path.normalize('force-app/main/default/classes/TestOrderController.cls-meta.xml'),
174-
ignored: false,
175-
actualState: 'Deleted',
176-
origin: 'Local',
177-
},
178-
]);
179-
});
180-
it('sf sees a local delete in local status', () => {
181-
const response = execCmd<PreviewResult>('deploy metadata preview --json', {
150+
const response = execCmd<PreviewResult>('project deploy preview --json', {
182151
ensureExitCode: 0,
183152
}).jsonOutput?.result;
184153
assert(response);
185154
expect(response.toDeploy).to.be.an.instanceof(Array).with.lengthOf(0);
186-
expect(response.toDelete).to.be.an.instanceof(Array).with.lengthOf(1);
187155
expect(response.toDelete).deep.equals([
188156
{
189157
type: 'ApexClass',
@@ -197,16 +165,6 @@ describe('end-to-end-test for tracking with an org (single packageDir)', () => {
197165
]);
198166
});
199167
it('does not see any change in remote status', () => {
200-
const result = execCmd<StatusResult[]>('force:source:status --json --remote', {
201-
ensureExitCode: 0,
202-
cli: 'sf',
203-
}).jsonOutput?.result;
204-
expect(
205-
result?.filter((r) => r.fullName === 'TestOrderController'),
206-
JSON.stringify(result)
207-
).to.have.length(0);
208-
});
209-
it('sf does not see any change in remote status', () => {
210168
const result = execCmd<PreviewResult>('retrieve metadata preview --json', {
211169
ensureExitCode: 0,
212170
}).jsonOutput?.result;
@@ -217,21 +175,14 @@ describe('end-to-end-test for tracking with an org (single packageDir)', () => {
217175
});
218176

219177
it('pushes the local delete to the org', () => {
220-
const result = execCmd<DeployResultJson>('deploy metadata --json', {
178+
const result = execCmd<DeployResultJson>('project:deploy:start --json', {
221179
ensureExitCode: 0,
222180
}).jsonOutput?.result.files;
223181
expect(result, JSON.stringify(result)).to.be.an.instanceof(Array).with.length(2);
224182
});
225-
it('sees no local changes', () => {
226-
const result = execCmd<StatusResult[]>('force:source:status --json --local', {
227-
ensureExitCode: 0,
228-
cli: 'sf',
229-
}).jsonOutput?.result;
230-
expect(result?.filter(filterIgnored), JSON.stringify(result)).to.be.an.instanceof(Array).with.length(0);
231-
});
232183

233-
it('sf no local changes', () => {
234-
const response = execCmd<PreviewResult>('deploy metadata preview --json', {
184+
it('no local changes', () => {
185+
const response = execCmd<PreviewResult>('project deploy preview --json', {
235186
ensureExitCode: 0,
236187
}).jsonOutput?.result;
237188

@@ -243,9 +194,8 @@ describe('end-to-end-test for tracking with an org (single packageDir)', () => {
243194
it('should throw an err when attempting to pull from a non scratch-org', () => {
244195
const hubUsername = session.hubOrg.username;
245196
assert(hubUsername, 'hubUsername should be defined');
246-
const failure = execCmd(`force:source:status -u ${hubUsername} --remote --json`, {
197+
const failure = execCmd(`project retrieve preview -o ${hubUsername} --json`, {
247198
ensureExitCode: 1,
248-
cli: 'sf',
249199
}).jsonOutput as unknown as { name: string };
250200
// command5 is removing `Error` from the end of the error names.
251201
expect(failure.name).to.include('NonSourceTrackedOrg');
@@ -282,14 +232,15 @@ describe('end-to-end-test for tracking with an org (single packageDir)', () => {
282232
});
283233
describe('classes that failed to deploy are still in local status', () => {
284234
it('sees no local changes', () => {
285-
const result = execCmd<StatusResult[]>('force:source:status --json --local', {
235+
const result = execCmd<PreviewResult>('project deploy preview --json', {
286236
ensureExitCode: 0,
287-
cli: 'sf',
288237
}).jsonOutput?.result;
289-
expect(result?.filter(filterIgnored), JSON.stringify(result)).to.be.an.instanceof(Array).with.length(2);
238+
expect(result?.toDeploy.filter(filterIgnored), JSON.stringify(result))
239+
.to.be.an.instanceof(Array)
240+
.with.length(1);
290241
});
291-
it('sf sees no local changes', () => {
292-
const response = execCmd<PreviewResult>('deploy metadata preview --json', {
242+
it('sees no local changes', () => {
243+
const response = execCmd<PreviewResult>('project deploy preview --json', {
293244
ensureExitCode: 0,
294245
}).jsonOutput?.result;
295246
assert(response);

test/nuts/tracking/conflicts.nut.ts

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import { execCmd, TestSession } from '@salesforce/cli-plugins-testkit';
1313
import { AuthInfo, Connection } from '@salesforce/core';
1414
import { DeployResultJson, isSdrFailure, isSdrSuccess, RetrieveResultJson } from '../../../src/utils/types.js';
1515
import { PreviewResult } from '../../../src/utils/previewOutput.js';
16-
import type { StatusResult } from './types.js';
1716
import { eBikesDeployResultCount } from './constants.js';
1817

1918
let session: TestSession;
@@ -70,12 +69,11 @@ describe('conflict detection and resolution', () => {
7069
description: 'modified',
7170
},
7271
});
73-
const result = execCmd<StatusResult[]>('force:source:status --json --remote', {
72+
const result = execCmd<PreviewResult>('project retrieve preview --json', {
7473
ensureExitCode: 0,
75-
cli: 'sf',
7674
}).jsonOutput?.result;
7775
expect(
78-
result?.filter((r) => r.type === 'CustomApplication'),
76+
result?.toRetrieve.filter((r) => r.type === 'CustomApplication'),
7977
JSON.stringify(result)
8078
).to.have.lengthOf(1);
8179
});
@@ -94,36 +92,24 @@ describe('conflict detection and resolution', () => {
9492
);
9593
});
9694
it('can see the conflict in status', () => {
97-
const result = execCmd<StatusResult[]>('force:source:status --json', {
95+
const result = execCmd<PreviewResult>('project deploy preview --json', {
9896
ensureExitCode: 0,
99-
cli: 'sf',
100-
}).jsonOutput?.result.filter((app) => app.type === 'CustomApplication');
97+
}).jsonOutput?.result.conflicts.filter((app) => app.type === 'CustomApplication');
10198
// json is not sorted. This relies on the implementation of getConflicts()
10299
expect(result).to.deep.equal([
103100
{
104101
type: 'CustomApplication',
105-
state: 'Local Changed (Conflict)',
106102
fullName: 'EBikes',
107-
filePath: path.normalize('force-app/main/default/applications/EBikes.app-meta.xml'),
108-
ignored: false,
109103
conflict: true,
110-
origin: 'Local',
111-
actualState: 'Changed',
112-
},
113-
{
114-
type: 'CustomApplication',
115-
state: 'Remote Changed (Conflict)',
116-
fullName: 'EBikes',
117-
filePath: path.normalize('force-app/main/default/applications/EBikes.app-meta.xml'),
118104
ignored: false,
119-
conflict: true,
120-
origin: 'Remote',
121-
actualState: 'Changed',
105+
operation: 'deploy',
106+
path: path.normalize(path.join(session.project.dir, 'force-app/main/default/applications/EBikes.app-meta.xml')),
107+
projectRelativePath: path.normalize('force-app/main/default/applications/EBikes.app-meta.xml'),
122108
},
123109
]);
124110
});
125111

126-
it('sf can see the conflict in status (deploy)', () => {
112+
it('can see the conflict in status (deploy)', () => {
127113
const result = execCmd<PreviewResult>('deploy metadata preview --json', {
128114
ensureExitCode: 0,
129115
}).jsonOutput?.result.conflicts.filter((app) => app.type === 'CustomApplication');
@@ -141,7 +127,7 @@ describe('conflict detection and resolution', () => {
141127
]);
142128
});
143129

144-
it('sf can see the conflict in status (retrieve)', () => {
130+
it('can see the conflict in status (retrieve)', () => {
145131
const result = execCmd<PreviewResult>('retrieve metadata preview --json', {
146132
ensureExitCode: 0,
147133
}).jsonOutput?.result.conflicts.filter((app) => app.type === 'CustomApplication');
@@ -159,7 +145,7 @@ describe('conflict detection and resolution', () => {
159145
]);
160146
});
161147

162-
it('sf can see the conflict in status (deploy) ignoring conflicts', () => {
148+
it('can see the conflict in status (deploy) ignoring conflicts', () => {
163149
const result = execCmd<PreviewResult>('deploy metadata preview --json -c', {
164150
ensureExitCode: 0,
165151
}).jsonOutput?.result.toDeploy.filter((app) => app.type === 'CustomApplication');
@@ -177,7 +163,7 @@ describe('conflict detection and resolution', () => {
177163
]);
178164
});
179165

180-
it('sf can see the conflict in status (retrieve) ignoring conflicts', () => {
166+
it('can see the conflict in status (retrieve) ignoring conflicts', () => {
181167
const result = execCmd<PreviewResult>('retrieve metadata preview --json -c', {
182168
ensureExitCode: 0,
183169
}).jsonOutput?.result.toRetrieve.filter((app) => app.type === 'CustomApplication');

test/nuts/tracking/deleteResetTracking.nut.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { execCmd, TestSession } from '@salesforce/cli-plugins-testkit';
1111
import { expect } from 'chai';
1212
import { AuthInfo, Connection } from '@salesforce/core';
1313
import { DeleteTrackingResult } from '../../../src/commands/project/delete/tracking.js';
14+
import { PreviewResult } from '../../../src/utils/previewOutput.js';
1415

1516
let session: TestSession;
1617
let orgId: string;
@@ -64,11 +65,11 @@ describe('reset and clear tracking', () => {
6465

6566
describe('clearing tracking', () => {
6667
it('runs status to start tracking', () => {
67-
const result = execCmd('force:source:status --json', {
68+
const result = execCmd<PreviewResult>('project deploy preview --json', {
6869
ensureExitCode: 0,
69-
cli: 'sf',
7070
}).jsonOutput?.result;
71-
expect(result).to.have.length.greaterThan(100); // ebikes is big
71+
// dreamhouse-lwc is big
72+
expect(result?.toDeploy).to.have.length.greaterThan(75);
7273
});
7374

7475
it('local tracking file exists', () => {
@@ -110,7 +111,7 @@ describe('reset and clear tracking', () => {
110111
}
111112
});
112113
// gets tracking files from server
113-
execCmd('force:source:status --json --remote', { ensureExitCode: 0, cli: 'sf' });
114+
execCmd('project retrieve preview --json', { ensureExitCode: 0, cli: 'sf' });
114115
const revisions = await getRevisionsAsArray();
115116
const revisionFile = JSON.parse(
116117
await fs.promises.readFile(path.join(trackingFileFolder, 'maxRevision.json'), 'utf8')

0 commit comments

Comments
 (0)