Merge pull request #20578 from kuangp/feat/addLocationAnalyzers

feat(catalog): support adding location analyzers in processing extension
This commit is contained in:
Phil Kuang
2023-10-26 10:42:06 -04:00
committed by GitHub
17 changed files with 128 additions and 38 deletions
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/plugin-catalog-backend': minor
'@backstage/plugin-catalog-node': minor
---
Support adding location analyzers in new catalog analysis extension point and move `AnalyzeOptions` and `ScmLocationAnalyzer` types to `@backstage/plugin-catalog-node`
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend-module-github': patch
---
Import `AnalyzeOptions` and `ScmLocationAnalyzer` types from `@backstage/plugin-catalog-node`
@@ -3,7 +3,7 @@
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
import { AnalyzeOptions } from '@backstage/plugin-catalog-backend';
import { AnalyzeOptions } from '@backstage/plugin-catalog-node';
import { CatalogProcessor } from '@backstage/plugin-catalog-node';
import { CatalogProcessorEmit } from '@backstage/plugin-catalog-node';
import { Config } from '@backstage/config';
@@ -21,7 +21,7 @@ import { Logger } from 'winston';
import { PluginEndpointDiscovery } from '@backstage/backend-common';
import { PluginTaskScheduler } from '@backstage/backend-tasks';
import { ScmIntegrationRegistry } from '@backstage/integration';
import { ScmLocationAnalyzer } from '@backstage/plugin-catalog-backend';
import { ScmLocationAnalyzer } from '@backstage/plugin-catalog-node';
import { TaskRunner } from '@backstage/backend-tasks';
import { TokenManager } from '@backstage/backend-common';
import { UserEntity } from '@backstage/catalog-model';
@@ -27,7 +27,7 @@ import parseGitUrl from 'git-url-parse';
import {
AnalyzeOptions,
ScmLocationAnalyzer,
} from '@backstage/plugin-catalog-backend';
} from '@backstage/plugin-catalog-node';
import {
PluginEndpointDiscovery,
TokenManager,
+7 -13
View File
@@ -10,6 +10,7 @@ import { AnalyzeLocationExistingEntity as AnalyzeLocationExistingEntity_2 } from
import { AnalyzeLocationGenerateEntity as AnalyzeLocationGenerateEntity_2 } from '@backstage/plugin-catalog-common';
import { AnalyzeLocationRequest as AnalyzeLocationRequest_2 } from '@backstage/plugin-catalog-common';
import { AnalyzeLocationResponse as AnalyzeLocationResponse_2 } from '@backstage/plugin-catalog-common';
import { AnalyzeOptions as AnalyzeOptions_2 } from '@backstage/plugin-catalog-node';
import { CatalogApi } from '@backstage/catalog-client';
import type { CatalogCollatorEntityTransformer as CatalogCollatorEntityTransformer_2 } from '@backstage/plugin-search-backend-module-catalog';
import { CatalogEntityDocument } from '@backstage/plugin-catalog-common';
@@ -50,6 +51,7 @@ import { PluginEndpointDiscovery } from '@backstage/backend-common';
import { PluginTaskScheduler } from '@backstage/backend-tasks';
import { Router } from 'express';
import { ScmIntegrationRegistry } from '@backstage/integration';
import { ScmLocationAnalyzer as ScmLocationAnalyzer_2 } from '@backstage/plugin-catalog-node';
import { TokenManager } from '@backstage/backend-common';
import { UrlReader } from '@backstage/backend-common';
import { Validators } from '@backstage/catalog-model';
@@ -69,11 +71,8 @@ export type AnalyzeLocationRequest = AnalyzeLocationRequest_2;
// @public @deprecated (undocumented)
export type AnalyzeLocationResponse = AnalyzeLocationResponse_2;
// @public (undocumented)
export type AnalyzeOptions = {
url: string;
catalogFilename?: string;
};
// @public @deprecated (undocumented)
export type AnalyzeOptions = AnalyzeOptions_2;
// @public (undocumented)
export class AnnotateLocationEntityProcessor implements CatalogProcessor_2 {
@@ -134,7 +133,7 @@ export class CatalogBuilder {
...providers: Array<EntityProvider_2 | Array<EntityProvider_2>>
): CatalogBuilder;
addLocationAnalyzers(
...analyzers: Array<ScmLocationAnalyzer | Array<ScmLocationAnalyzer>>
...analyzers: Array<ScmLocationAnalyzer_2 | Array<ScmLocationAnalyzer_2>>
): CatalogBuilder;
addPermissionRules(
...permissionRules: Array<
@@ -468,13 +467,8 @@ export const processingResult: Readonly<{
readonly refresh: (key: string) => CatalogProcessorResult_2;
}>;
// @public (undocumented)
export type ScmLocationAnalyzer = {
supports(url: string): boolean;
analyze(options: AnalyzeOptions): Promise<{
existing: AnalyzeLocationExistingEntity[];
}>;
};
// @public @deprecated (undocumented)
export type ScmLocationAnalyzer = ScmLocationAnalyzer_2;
// @public (undocumented)
export class UrlReaderProcessor implements CatalogProcessor_2 {
+12
View File
@@ -33,6 +33,8 @@ import {
type EntityProvider as _EntityProvider,
type EntityProviderConnection as _EntityProviderConnection,
type EntityProviderMutation as _EntityProviderMutation,
type AnalyzeOptions as _AnalyzeOptions,
type ScmLocationAnalyzer as _ScmLocationAnalyzer,
} from '@backstage/plugin-catalog-node';
import { type LocationSpec as _LocationSpec } from '@backstage/plugin-catalog-common';
@@ -141,3 +143,13 @@ export type EntityProviderMutation = _EntityProviderMutation;
* @deprecated use the same type from `@backstage/plugin-catalog-common` instead
*/
export type LocationSpec = _LocationSpec;
/**
* @public
* @deprecated import from `@backstage/plugin-catalog-node` instead
*/
export type AnalyzeOptions = _AnalyzeOptions;
/**
* @public
* @deprecated import from `@backstage/plugin-catalog-node` instead
*/
export type ScmLocationAnalyzer = _ScmLocationAnalyzer;
@@ -18,11 +18,12 @@ import { Logger } from 'winston';
import parseGitUrl from 'git-url-parse';
import { Entity } from '@backstage/catalog-model';
import { ScmIntegrationRegistry } from '@backstage/integration';
import { LocationAnalyzer, ScmLocationAnalyzer } from './types';
import { LocationAnalyzer } from './types';
import {
AnalyzeLocationRequest,
AnalyzeLocationResponse,
} from '@backstage/plugin-catalog-common';
import { ScmLocationAnalyzer } from '@backstage/plugin-catalog-node';
export class RepoLocationAnalyzer implements LocationAnalyzer {
private readonly logger: Logger;
@@ -21,6 +21,4 @@ export type {
AnalyzeLocationRequest,
AnalyzeLocationResponse,
LocationAnalyzer,
ScmLocationAnalyzer,
AnalyzeOptions,
} from './types';
@@ -78,19 +78,3 @@ export type LocationAnalyzer = {
location: AnalyzeLocationRequest,
): Promise<AnalyzeLocationResponse>;
};
/** @public */
export type AnalyzeOptions = {
url: string;
catalogFilename?: string;
};
/** @public */
export type ScmLocationAnalyzer = {
/** The method that decides if this analyzer can work with the provided url */
supports(url: string): boolean;
/** This function can return an array of already existing entities */
analyze(options: AnalyzeOptions): Promise<{
/** Existing entities in the analyzed location */
existing: AnalyzeLocationExistingEntity[];
}>;
};
@@ -38,6 +38,7 @@ import {
CatalogProcessor,
CatalogProcessorParser,
EntityProvider,
ScmLocationAnalyzer,
} from '@backstage/plugin-catalog-node';
import {
AnnotateLocationEntityProcessor,
@@ -57,7 +58,7 @@ import {
yamlPlaceholderResolver,
} from '../modules/core/PlaceholderProcessor';
import { defaultEntityDataParser } from '../modules/util/parse';
import { LocationAnalyzer, ScmLocationAnalyzer } from '../ingestion/types';
import { LocationAnalyzer } from '../ingestion/types';
import { CatalogProcessingEngine } from '../processing';
import { DefaultProcessingDatabase } from '../database/DefaultProcessingDatabase';
import { applyDatabaseMigrations } from '../database/migrations';
@@ -19,17 +19,22 @@ import {
} from '@backstage/backend-plugin-api';
import { CatalogBuilder } from './CatalogBuilder';
import {
CatalogAnalysisExtensionPoint,
catalogAnalysisExtensionPoint,
CatalogProcessingExtensionPoint,
catalogProcessingExtensionPoint,
} from '@backstage/plugin-catalog-node/alpha';
import {
CatalogProcessor,
EntityProvider,
ScmLocationAnalyzer,
} from '@backstage/plugin-catalog-node';
import { loggerToWinstonLogger } from '@backstage/backend-common';
import { PlaceholderResolver } from '../modules';
class CatalogExtensionPointImpl implements CatalogProcessingExtensionPoint {
class CatalogProcessingExtensionPointImpl
implements CatalogProcessingExtensionPoint
{
#processors = new Array<CatalogProcessor>();
#entityProviders = new Array<EntityProvider>();
#placeholderResolvers: Record<string, PlaceholderResolver> = {};
@@ -67,6 +72,20 @@ class CatalogExtensionPointImpl implements CatalogProcessingExtensionPoint {
}
}
class CatalogAnalysisExtensionPointImpl
implements CatalogAnalysisExtensionPoint
{
#locationAnalyzers = new Array<ScmLocationAnalyzer>();
addLocationAnalyzer(analyzer: ScmLocationAnalyzer): void {
this.#locationAnalyzers.push(analyzer);
}
get locationAnalyzers() {
return this.#locationAnalyzers;
}
}
/**
* Catalog plugin
* @alpha
@@ -74,13 +93,19 @@ class CatalogExtensionPointImpl implements CatalogProcessingExtensionPoint {
export const catalogPlugin = createBackendPlugin({
pluginId: 'catalog',
register(env) {
const processingExtensions = new CatalogExtensionPointImpl();
const processingExtensions = new CatalogProcessingExtensionPointImpl();
// plugins depending on this API will be initialized before this plugins init method is executed.
env.registerExtensionPoint(
catalogProcessingExtensionPoint,
processingExtensions,
);
const analysisExtensions = new CatalogAnalysisExtensionPointImpl();
env.registerExtensionPoint(
catalogAnalysisExtensionPoint,
analysisExtensions,
);
env.registerInit({
deps: {
logger: coreServices.logger,
@@ -116,6 +141,7 @@ export const catalogPlugin = createBackendPlugin({
Object.entries(processingExtensions.placeholderResolvers).forEach(
([key, resolver]) => builder.setPlaceholderResolver(key, resolver),
);
builder.addLocationAnalyzers(...analysisExtensions.locationAnalyzers);
const { processingEngine, router } = await builder.build();
+10
View File
@@ -8,8 +8,18 @@ import { CatalogProcessor } from '@backstage/plugin-catalog-node';
import { EntityProvider } from '@backstage/plugin-catalog-node';
import { ExtensionPoint } from '@backstage/backend-plugin-api';
import { PlaceholderResolver } from '@backstage/plugin-catalog-node';
import { ScmLocationAnalyzer } from '@backstage/plugin-catalog-node';
import { ServiceRef } from '@backstage/backend-plugin-api';
// @alpha (undocumented)
export interface CatalogAnalysisExtensionPoint {
// (undocumented)
addLocationAnalyzer(analyzer: ScmLocationAnalyzer): void;
}
// @alpha (undocumented)
export const catalogAnalysisExtensionPoint: ExtensionPoint<CatalogAnalysisExtensionPoint>;
// @alpha (undocumented)
export interface CatalogProcessingExtensionPoint {
// (undocumented)
+15
View File
@@ -5,12 +5,19 @@
```ts
/// <reference types="node" />
import { AnalyzeLocationExistingEntity } from '@backstage/plugin-catalog-common';
import { CompoundEntityRef } from '@backstage/catalog-model';
import { Entity } from '@backstage/catalog-model';
import { JsonValue } from '@backstage/types';
import { LocationEntityV1alpha1 } from '@backstage/catalog-model';
import { LocationSpec as LocationSpec_2 } from '@backstage/plugin-catalog-common';
// @public (undocumented)
export type AnalyzeOptions = {
url: string;
catalogFilename?: string;
};
// @public (undocumented)
export type CatalogProcessor = {
getProcessorName(): string;
@@ -198,4 +205,12 @@ export const processingResult: Readonly<{
readonly relation: (spec: EntityRelationSpec) => CatalogProcessorResult;
readonly refresh: (key: string) => CatalogProcessorResult;
}>;
// @public (undocumented)
export type ScmLocationAnalyzer = {
supports(url: string): boolean;
analyze(options: AnalyzeOptions): Promise<{
existing: AnalyzeLocationExistingEntity[];
}>;
};
```
+2
View File
@@ -17,3 +17,5 @@
export { catalogServiceRef } from './catalogService';
export type { CatalogProcessingExtensionPoint } from './extensions';
export { catalogProcessingExtensionPoint } from './extensions';
export type { CatalogAnalysisExtensionPoint } from './extensions';
export { catalogAnalysisExtensionPoint } from './extensions';
+16
View File
@@ -18,6 +18,7 @@ import {
EntityProvider,
CatalogProcessor,
PlaceholderResolver,
ScmLocationAnalyzer,
} from '@backstage/plugin-catalog-node';
/**
@@ -40,3 +41,18 @@ export const catalogProcessingExtensionPoint =
createExtensionPoint<CatalogProcessingExtensionPoint>({
id: 'catalog.processing',
});
/**
* @alpha
*/
export interface CatalogAnalysisExtensionPoint {
addLocationAnalyzer(analyzer: ScmLocationAnalyzer): void;
}
/**
* @alpha
*/
export const catalogAnalysisExtensionPoint =
createExtensionPoint<CatalogAnalysisExtensionPoint>({
id: 'catalog.analysis',
});
@@ -15,9 +15,11 @@
*/
export type {
AnalyzeOptions,
DeferredEntity,
PlaceholderResolver,
PlaceholderResolverParams,
PlaceholderResolverRead,
PlaceholderResolverResolveUrl,
ScmLocationAnalyzer,
} from './types';
@@ -15,6 +15,7 @@
*/
import { Entity } from '@backstage/catalog-model';
import { AnalyzeLocationExistingEntity } from '@backstage/plugin-catalog-common';
import { JsonValue } from '@backstage/types';
import { CatalogProcessorEmit } from '../api';
@@ -50,3 +51,20 @@ export type PlaceholderResolverParams = {
export type PlaceholderResolver = (
params: PlaceholderResolverParams,
) => Promise<JsonValue>;
/** @public */
export type AnalyzeOptions = {
url: string;
catalogFilename?: string;
};
/** @public */
export type ScmLocationAnalyzer = {
/** The method that decides if this analyzer can work with the provided url */
supports(url: string): boolean;
/** This function can return an array of already existing entities */
analyze(options: AnalyzeOptions): Promise<{
/** Existing entities in the analyzed location */
existing: AnalyzeLocationExistingEntity[];
}>;
};