ignore processors emitting entities that are their own children

Signed-off-by: Fredrik Adelöw <freben@gmail.com>
This commit is contained in:
Fredrik Adelöw
2022-12-13 16:59:29 +01:00
parent 38c306dc7f
commit b3fac9c107
3 changed files with 28 additions and 2 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend': patch
---
Ignore attempts at emitting the current entity as a child of itself.
@@ -258,13 +258,22 @@ describe('DefaultCatalogProcessingOrchestrator', () => {
},
};
const child: Entity = {
apiVersion: '1',
kind: 'Component',
metadata: {
name: 'Test2',
namespace: 'test1',
},
};
it('enforces catalog rules', async () => {
const integrations = ScmIntegrations.fromConfig(new ConfigReader({}));
const processor: jest.Mocked<CatalogProcessor> = {
getProcessorName: jest.fn(),
validateEntityKind: jest.fn(async () => true),
readLocation: jest.fn(async (_l, _o, emit) => {
emit(processingResult.entity({ type: 't', target: 't' }, entity));
emit(processingResult.entity({ type: 't', target: 't' }, child));
return true;
}),
};
@@ -300,7 +309,7 @@ describe('DefaultCatalogProcessingOrchestrator', () => {
getProcessorName: jest.fn(),
validateEntityKind: jest.fn(async () => true),
readLocation: jest.fn(async (_l, _o, emit) => {
emit(processingResult.entity({ type: 't', target: 't' }, entity));
emit(processingResult.entity({ type: 't', target: 't' }, child));
return true;
}),
};
@@ -19,6 +19,7 @@ import {
ANNOTATION_LOCATION,
ANNOTATION_ORIGIN_LOCATION,
stringifyLocationRef,
stringifyEntityRef,
} from '@backstage/catalog-model';
import { assertError } from '@backstage/errors';
import { Logger } from 'winston';
@@ -89,6 +90,17 @@ export class ProcessorOutputCollector {
return;
}
// The processor contract says you should return the "trunk" (current)
// entity, not emit it. But it happens that this is misunderstood or
// accidentally forgotten. This can lead to circular references which at
// best is wasteful, so we try to be helpful by ignoring such emitted
// entities.
if (
stringifyEntityRef(entity) === stringifyEntityRef(this.parentEntity)
) {
return;
}
// Note that at this point, we have only validated the envelope part of
// the entity data. Annotations are not part of that, so we have to be
// defensive. If the annotations were malformed (e.g. were not a valid