Skip to content

Commit 9d258fc

Browse files
mshanemcshetzel
andauthored
feat: modify fileResponse for not found in org on Deletes (#472)
* feat: modify fileResponse for not found in org on Deletes * test: verify for matchingContentType * refactor: pr feedback (jsdoc, named type for object) * refactor: handle various destructive filenames Co-authored-by: Steve Hetzel <[email protected]>
1 parent e3a10d3 commit 9d258fc

File tree

4 files changed

+98
-5
lines changed

4 files changed

+98
-5
lines changed

CHANGELOG.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,15 @@ All notable changes to this project will be documented in this file. See [standa
88

99
### [5.1.1](https://github.com/forcedotcom/source-deploy-retrieve/compare/v5.1.0...v5.1.1) (2021-10-28)
1010

11-
1211
### Bug Fixes
1312

14-
* ensure component.content is always assigned ([#485](https://github.com/forcedotcom/source-deploy-retrieve/issues/485)) ([d77f475](https://github.com/forcedotcom/source-deploy-retrieve/commit/d77f47502634206ac59181362b7f17da82ed01e7))
13+
- ensure component.content is always assigned ([#485](https://github.com/forcedotcom/source-deploy-retrieve/issues/485)) ([d77f475](https://github.com/forcedotcom/source-deploy-retrieve/commit/d77f47502634206ac59181362b7f17da82ed01e7))
1514

1615
## [5.1.0](https://github.com/forcedotcom/source-deploy-retrieve/compare/v5.0.3...v5.1.0) (2021-10-28)
1716

18-
1917
### Features
2018

21-
* construct virtual tree from array of paths ([#480](https://github.com/forcedotcom/source-deploy-retrieve/issues/480)) ([99954dc](https://github.com/forcedotcom/source-deploy-retrieve/commit/99954dc731d078e99283eed940b98ee63688a024))
19+
- construct virtual tree from array of paths ([#480](https://github.com/forcedotcom/source-deploy-retrieve/issues/480)) ([99954dc](https://github.com/forcedotcom/source-deploy-retrieve/commit/99954dc731d078e99283eed940b98ee63688a024))
2220

2321
### [5.0.3](https://github.com/forcedotcom/source-deploy-retrieve/compare/v5.0.2...v5.0.3) (2021-10-28)
2422

src/client/metadataApiDeploy.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export class DeployResult implements MetadataTransferResult {
5454
}
5555
}
5656

57-
return fileResponses;
57+
return fileResponses.concat(this.deleteNotFoundToFileResponses(messages));
5858
}
5959

6060
private createResponses(component: SourceComponent, messages: DeployMessage[]): FileResponse[] {
@@ -146,6 +146,41 @@ export class DeployResult implements MetadataTransferResult {
146146
return messageMap;
147147
}
148148

149+
/**
150+
* If a components fails to delete because it doesn't exist in the org, you get a message like
151+
* key: 'ApexClass#destructiveChanges.xml'
152+
* value:[{
153+
* fullName: 'destructiveChanges.xml',
154+
* fileName: 'destructiveChanges.xml',
155+
* componentType: 'ApexClass',
156+
* problem: 'No ApexClass named: test1 found',
157+
* problemType: 'Warning'
158+
* }]
159+
*/
160+
private deleteNotFoundToFileResponses(messageMap: Map<string, DeployMessage[]>): FileResponse[] {
161+
const fileResponses: FileResponse[] = [];
162+
messageMap.forEach((messages, key) => {
163+
if (key.includes('destructiveChanges') && key.endsWith('.xml')) {
164+
messages.forEach((message) => {
165+
if (message.problemType === 'Warning' && message.problem.startsWith(`No ${message.componentType} named: `)) {
166+
const fullName = message.problem.replace(`No ${message.componentType} named: `, '').replace(' found', '');
167+
this.components
168+
.getComponentFilenamesByNameAndType({ fullName, type: message.componentType })
169+
.forEach((fileName) => {
170+
fileResponses.push({
171+
fullName,
172+
type: message.componentType,
173+
filePath: fileName,
174+
state: ComponentStatus.Deleted,
175+
});
176+
});
177+
}
178+
});
179+
}
180+
});
181+
return fileResponses;
182+
}
183+
149184
/**
150185
* Fix any issues with the deploy message returned by the api.
151186
* TODO: remove cases if fixes are made in the api.

src/collections/componentSet.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
TreeContainer,
2525
} from '../resolve';
2626
import { MetadataType, RegistryAccess } from '../registry';
27+
import { MetadataMember } from '../resolve/types';
2728
import {
2829
DestructiveChangesType,
2930
FromManifestOptions,
@@ -477,6 +478,27 @@ export class ComponentSet extends LazyCollection<MetadataComponent> {
477478
return false;
478479
}
479480

481+
/**
482+
* For a fullName and type, this returns the filenames the matching component, or an empty array if the component is not present
483+
*
484+
* @param param Object with fullName and type properties
485+
* @returns string[]
486+
*/
487+
public getComponentFilenamesByNameAndType({ fullName, type }: MetadataMember): string[] {
488+
const key = this.simpleKey({ fullName, type });
489+
const componentMap = this.components.get(key);
490+
if (!componentMap) {
491+
return [];
492+
}
493+
const output = new Set<string>();
494+
componentMap.forEach((component) => {
495+
[...component.walkContent(), component.content, component.xml]
496+
.filter(Boolean)
497+
.map((filename) => output.add(filename));
498+
});
499+
return Array.from(output);
500+
}
501+
480502
public *[Symbol.iterator](): Iterator<MetadataComponent> {
481503
for (const [key, sourceComponents] of this.components.entries()) {
482504
if (sourceComponents.size === 0) {

test/client/metadataApiDeploy.test.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
DECOMPOSED_CHILD_COMPONENT_2,
2626
DECOMPOSED_COMPONENT,
2727
} from '../mock/registry/type-constants/decomposedConstants';
28+
import { COMPONENT } from '../mock/registry/type-constants/matchingContentFileConstants';
2829
import { MissingJobIdError } from '../../src/errors';
2930

3031
const env = createSandbox();
@@ -714,6 +715,43 @@ describe('MetadataApiDeploy', () => {
714715

715716
expect(responses).to.deep.equal(expected);
716717
});
718+
719+
it('should report "Deleted" when no component in org', () => {
720+
const component = COMPONENT;
721+
const deployedSet = new ComponentSet([component]);
722+
const apiStatus: Partial<MetadataApiDeployStatus> = {
723+
details: {
724+
componentFailures: {
725+
changed: 'false',
726+
created: 'false',
727+
deleted: 'false',
728+
fullName: 'destructiveChanges.xml',
729+
componentType: component.type.name,
730+
problem: `No ${component.type.name} named: ${component.fullName} found`,
731+
problemType: 'Warning',
732+
} as DeployMessage,
733+
},
734+
};
735+
const result = new DeployResult(apiStatus as MetadataApiDeployStatus, deployedSet);
736+
737+
const responses = result.getFileResponses();
738+
const expected: FileResponse[] = [
739+
{
740+
fullName: component.fullName,
741+
type: component.type.name,
742+
state: ComponentStatus.Deleted,
743+
filePath: component.content,
744+
},
745+
{
746+
fullName: component.fullName,
747+
type: component.type.name,
748+
state: ComponentStatus.Deleted,
749+
filePath: component.xml,
750+
},
751+
];
752+
753+
expect(responses).to.deep.equal(expected);
754+
});
717755
});
718756
});
719757

0 commit comments

Comments
 (0)