diff --git a/.changeset/sweet-feet-study.md b/.changeset/sweet-feet-study.md index ccec79678b..d27b05e848 100644 --- a/.changeset/sweet-feet-study.md +++ b/.changeset/sweet-feet-study.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-linguist-backend': minor +'@backstage/plugin-linguist-backend': patch --- -**BREAKING**: Removing options from exported `linguistPlugin()` in favour of static config +Breaking change for the alpha export plugin options from exported `linguistPlugin()` in favour of static config. diff --git a/plugins/linguist-backend/api-report.md b/plugins/linguist-backend/api-report.md index 5cee322a5b..4edd939058 100644 --- a/plugins/linguist-backend/api-report.md +++ b/plugins/linguist-backend/api-report.md @@ -27,6 +27,11 @@ export function createRouter( routerOptions: RouterOptions, ): Promise; +// @public (undocumented) +export function createRouterFromConfig( + routerOptions: RouterOptions, +): Promise; + // @public (undocumented) export interface LinguistBackendApi { // (undocumented) @@ -88,6 +93,8 @@ export interface PluginOptions { // @public (undocumented) export interface RouterOptions { + // (undocumented) + config?: Config; // (undocumented) database: PluginDatabaseManager; // (undocumented) diff --git a/plugins/linguist-backend/config.d.ts b/plugins/linguist-backend/config.d.ts index 5f5a3e2656..758210feb7 100644 --- a/plugins/linguist-backend/config.d.ts +++ b/plugins/linguist-backend/config.d.ts @@ -15,7 +15,8 @@ */ import { TaskScheduleDefinition } from '@backstage/backend-tasks'; -import { HumanDuration, JsonObject } from '@backstage/types'; +import { HumanDuration } from '@backstage/types'; +import { Options as LinguistJsOptions } from 'linguist-js/dist/types'; export interface Config { /** Configuration options for the linguist plugin */ @@ -40,7 +41,7 @@ export interface Config { /** * [linguist-js](https://www.npmjs.com/package/linguist-js) options */ - linguistJsOptions?: JsonObject; + linguistJsOptions?: LinguistJsOptions; /** Options for the tags processor */ tagsProcessor?: { diff --git a/plugins/linguist-backend/src/plugin.ts b/plugins/linguist-backend/src/plugin.ts index 0605ee3027..cbf18d9ebe 100644 --- a/plugins/linguist-backend/src/plugin.ts +++ b/plugins/linguist-backend/src/plugin.ts @@ -19,10 +19,8 @@ import { coreServices, createBackendPlugin, } from '@backstage/backend-plugin-api'; -import { readTaskScheduleDefinitionFromConfig } from '@backstage/backend-tasks'; -import { HumanDuration } from '@backstage/types'; -import { createRouter } from './service/router'; +import { createRouterFromConfig } from './service/router'; /** * Linguist backend plugin @@ -53,43 +51,16 @@ export const linguistPlugin = createBackendPlugin({ tokenManager, httpRouter, }) { - let schedule; - if (config.has('linguist.schedule')) { - schedule = readTaskScheduleDefinitionFromConfig( - config.getConfig('linguist.schedule'), - ); - } - const batchSize = config.getOptionalNumber('linguist.batchSize'); - const useSourceLocation = config.getBoolean( - 'linguist.useSourceLocation', - ); - const age = config.getOptionalConfig('linguist.age') as - | HumanDuration - | undefined; - const kind = config.getOptionalStringArray('linguist.kind'); - const linguistJsOptions = config.getOptionalConfig( - 'linguist.linguistJsOptions', - ); - httpRouter.use( - await createRouter( - { - schedule, - batchSize, - useSourceLocation, - age, - kind, - linguistJsOptions, - }, - { - logger: loggerToWinstonLogger(logger), - reader, - database, - discovery, - scheduler, - tokenManager, - }, - ), + await createRouterFromConfig({ + logger: loggerToWinstonLogger(logger), + config, + reader, + database, + discovery, + scheduler, + tokenManager, + }), ); }, }); diff --git a/plugins/linguist-backend/src/service/router.test.ts b/plugins/linguist-backend/src/service/router.test.ts index 7ab8f1c238..4048e1213b 100644 --- a/plugins/linguist-backend/src/service/router.test.ts +++ b/plugins/linguist-backend/src/service/router.test.ts @@ -25,7 +25,7 @@ import { import express from 'express'; import request from 'supertest'; import { ConfigReader } from '@backstage/config'; -import { createRouter } from './router'; +import { createRouter, createRouterFromConfig } from './router'; import { LinguistBackendApi } from '../api'; import { TaskScheduleDefinition } from '@backstage/backend-tasks'; @@ -69,26 +69,57 @@ describe('createRouter', () => { let linguistBackendApi: jest.Mocked; let app: express.Express; - beforeAll(async () => { - const router = await createRouter( - { schedule: schedule, age: { days: 30 }, useSourceLocation: false }, - { - linguistBackendApi: linguistBackendApi, - discovery: testDiscovery, - database: createDatabase(), - reader: mockUrlReader, - logger: getVoidLogger(), - tokenManager: mockedTokenManager, - }, - ); - app = express().use(router); - }); - beforeEach(() => { jest.resetAllMocks(); }); describe('GET /health', () => { + beforeAll(async () => { + const router = await createRouter( + { schedule: schedule, age: { days: 30 }, useSourceLocation: false }, + { + linguistBackendApi: linguistBackendApi, + discovery: testDiscovery, + database: createDatabase(), + reader: mockUrlReader, + logger: getVoidLogger(), + tokenManager: mockedTokenManager, + }, + ); + app = express().use(router); + }); + it('returns ok', async () => { + const response = await request(app).get('/health'); + + expect(response.status).toEqual(200); + expect(response.body).toEqual({ status: 'ok' }); + }); + }); + + describe('GET /health from config', () => { + beforeAll(async () => { + const config = new ConfigReader({ + linguist: { + schedule: { + frequency: { minutes: 2 }, + timeout: { minutes: 15 }, + initialDelay: { seconds: 15 }, + }, + age: { days: 30 }, + useSourceLocation: false, + }, + }); + const router = await createRouterFromConfig({ + linguistBackendApi: linguistBackendApi, + discovery: testDiscovery, + database: createDatabase(), + reader: mockUrlReader, + logger: getVoidLogger(), + config, + tokenManager: mockedTokenManager, + }); + app = express().use(router); + }); it('returns ok', async () => { const response = await request(app).get('/health'); diff --git a/plugins/linguist-backend/src/service/router.ts b/plugins/linguist-backend/src/service/router.ts index 9e45438ec8..02ff05f398 100644 --- a/plugins/linguist-backend/src/service/router.ts +++ b/plugins/linguist-backend/src/service/router.ts @@ -28,11 +28,13 @@ import { LinguistBackendApi } from '../api'; import { LinguistBackendDatabase } from '../db'; import { PluginTaskScheduler, + readTaskScheduleDefinitionFromConfig, TaskScheduleDefinition, } from '@backstage/backend-tasks'; import { HumanDuration } from '@backstage/types'; import { CatalogClient } from '@backstage/catalog-client'; import { LinguistBackendClient } from '../api/LinguistBackendClient'; +import { Config } from '@backstage/config'; /** @public */ export interface PluginOptions { @@ -53,6 +55,7 @@ export interface RouterOptions { database: PluginDatabaseManager; discovery: PluginEndpointDiscovery; scheduler?: PluginTaskScheduler; + config?: Config; } /** @public */ @@ -60,6 +63,9 @@ export async function createRouter( pluginOptions: PluginOptions, routerOptions: RouterOptions, ): Promise { + const { logger, reader, database, discovery, scheduler, tokenManager } = + routerOptions; + const { schedule, age, @@ -69,9 +75,6 @@ export async function createRouter( linguistJsOptions, } = pluginOptions; - const { logger, reader, database, discovery, scheduler, tokenManager } = - routerOptions; - const linguistBackendStore = await LinguistBackendDatabase.create( await database.getClient(), ); @@ -135,3 +138,28 @@ export async function createRouter( router.use(errorHandler()); return router; } + +/** @public */ +export async function createRouterFromConfig(routerOptions: RouterOptions) { + const { config } = routerOptions; + const pluginOptions: PluginOptions = {}; + if (config) { + if (config.has('linguist.schedule')) { + pluginOptions.schedule = readTaskScheduleDefinitionFromConfig( + config.getConfig('linguist.schedule'), + ); + } + pluginOptions.batchSize = config.getOptionalNumber('linguist.batchSize'); + pluginOptions.useSourceLocation = config.getBoolean( + 'linguist.useSourceLocation', + ); + pluginOptions.age = config.getOptionalConfig('linguist.age') as + | HumanDuration + | undefined; + pluginOptions.kind = config.getOptionalStringArray('linguist.kind'); + pluginOptions.linguistJsOptions = config.getOptionalConfig( + 'linguist.linguistJsOptions', + ); + } + return createRouter(pluginOptions, routerOptions); +}