From 2e20518cd2d16940fff1f8069e43593e0702e86a Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 3 May 2024 11:43:07 +0200 Subject: [PATCH] catalog-node: allow location analyzer to be configured as a factory as well Signed-off-by: Patrik Oldsberg --- .../src/service/CatalogPlugin.ts | 26 +++++++++++++++---- plugins/catalog-node/api-report-alpha.md | 8 +++++- plugins/catalog-node/src/extensions.ts | 17 +++++++++--- 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/plugins/catalog-backend/src/service/CatalogPlugin.ts b/plugins/catalog-backend/src/service/CatalogPlugin.ts index 6171ebbc1c..ac869cdc2b 100644 --- a/plugins/catalog-backend/src/service/CatalogPlugin.ts +++ b/plugins/catalog-backend/src/service/CatalogPlugin.ts @@ -38,6 +38,7 @@ import { } from '@backstage/plugin-catalog-node'; import { merge } from 'lodash'; import { Permission } from '@backstage/plugin-permission-common'; +import { ForwardedError } from '@backstage/errors'; class CatalogProcessingExtensionPointImpl implements CatalogProcessingExtensionPoint @@ -164,14 +165,24 @@ export const catalogPlugin = createBackendPlugin({ processingExtensions, ); - let locationAnalyzer: LocationAnalyzer | undefined = undefined; + let locationAnalyzerFactory: + | ((options: { + scmLocationAnalyzers: ScmLocationAnalyzer[]; + }) => Promise<{ locationAnalyzer: LocationAnalyzer }>) + | undefined = undefined; const scmLocationAnalyzers = new Array(); env.registerExtensionPoint(catalogAnalysisExtensionPoint, { - setLocationAnalyzer(analyzer: LocationAnalyzer) { - if (locationAnalyzer) { + setLocationAnalyzer(analyzerOrFactory) { + if (locationAnalyzerFactory) { throw new Error('LocationAnalyzer has already been set'); } - locationAnalyzer = analyzer; + if (typeof analyzerOrFactory === 'function') { + locationAnalyzerFactory = analyzerOrFactory; + } else { + locationAnalyzerFactory = async () => ({ + locationAnalyzer: analyzerOrFactory, + }); + } }, addScmLocationAnalyzer(analyzer: ScmLocationAnalyzer) { scmLocationAnalyzers.push(analyzer); @@ -240,7 +251,12 @@ export const catalogPlugin = createBackendPlugin({ Object.entries(processingExtensions.placeholderResolvers).forEach( ([key, resolver]) => builder.setPlaceholderResolver(key, resolver), ); - if (locationAnalyzer) { + if (locationAnalyzerFactory) { + const { locationAnalyzer } = await locationAnalyzerFactory({ + scmLocationAnalyzers, + }).catch(e => { + throw new ForwardedError('Failed to create LocationAnalyzer', e); + }); builder.setLocationAnalyzer(locationAnalyzer); } else { builder.addLocationAnalyzers(...scmLocationAnalyzers); diff --git a/plugins/catalog-node/api-report-alpha.md b/plugins/catalog-node/api-report-alpha.md index cc3f7e5fb5..b61d1b1d27 100644 --- a/plugins/catalog-node/api-report-alpha.md +++ b/plugins/catalog-node/api-report-alpha.md @@ -22,7 +22,13 @@ import { Validators } from '@backstage/catalog-model'; // @alpha (undocumented) export interface CatalogAnalysisExtensionPoint { addScmLocationAnalyzer(analyzer: ScmLocationAnalyzer): void; - setLocationAnalyzer(analyzer: LocationAnalyzer): void; + setLocationAnalyzer( + analyzerOrFactory: + | LocationAnalyzer + | ((options: { scmLocationAnalyzers: ScmLocationAnalyzer[] }) => Promise<{ + locationAnalyzer: LocationAnalyzer; + }>), + ): void; } // @alpha (undocumented) diff --git a/plugins/catalog-node/src/extensions.ts b/plugins/catalog-node/src/extensions.ts index 56478ec1db..7c1fe6c30d 100644 --- a/plugins/catalog-node/src/extensions.ts +++ b/plugins/catalog-node/src/extensions.ts @@ -81,10 +81,21 @@ export const catalogProcessingExtensionPoint = */ export interface CatalogAnalysisExtensionPoint { /** - * Replaces the entire location analyzer with a new one. This will cause any - * SCM analyzers added through `addScmLocationAnalyzer` to be ignored. + * Replaces the entire location analyzer with a new one. + * + * @remarks + * + * By providing a factory function you can access all the SCM analyzers that + * have been added through `addScmLocationAnalyzer`. If you provide a + * `LocationAnalyzer` directly, the SCM analyzers will be ignored. */ - setLocationAnalyzer(analyzer: LocationAnalyzer): void; + setLocationAnalyzer( + analyzerOrFactory: + | LocationAnalyzer + | ((options: { + scmLocationAnalyzers: ScmLocationAnalyzer[]; + }) => Promise<{ locationAnalyzer: LocationAnalyzer }>), + ): void; /** * Adds an analyzer for a specific SCM type to the default location analyzer.