Merge pull request #19270 from backstage/philipph/linguist-remove-backend-options

[Linguist] Remove new backend system plugin options
This commit is contained in:
Patrik Oldsberg
2023-08-15 11:21:21 +02:00
committed by GitHub
9 changed files with 178 additions and 125 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-linguist-backend': minor
---
**BREAKING**: Removed the alpha export plugin options from exported `linguistPlugin()` (used by the new backend system) in favour of static config.
+1 -15
View File
@@ -36,7 +36,6 @@ import { badgesPlugin } from '@backstage/plugin-badges-backend';
import { azureDevOpsPlugin } from '@backstage/plugin-azure-devops-backend';
import { linguistPlugin } from '@backstage/plugin-linguist-backend';
import { devtoolsPlugin } from '@backstage/plugin-devtools-backend';
import { TaskScheduleDefinition } from '@backstage/backend-tasks';
import { adrPlugin } from '@backstage/plugin-adr-backend';
import { lighthousePlugin } from '@backstage/plugin-lighthouse-backend';
import { proxyPlugin } from '@backstage/plugin-proxy-backend';
@@ -58,20 +57,7 @@ backend.add(devtoolsPlugin());
backend.add(entityFeedbackPlugin());
// Linguist
const linguistSchedule: TaskScheduleDefinition = {
frequency: { minutes: 2 },
timeout: { minutes: 15 },
initialDelay: { seconds: 15 },
};
backend.add(
linguistPlugin({
schedule: linguistSchedule,
age: { days: 30 },
batchSize: 2,
useSourceLocation: false,
}),
);
backend.add(linguistPlugin());
// Todo
backend.add(todoPlugin());
+22 -14
View File
@@ -70,24 +70,32 @@ In your `packages/backend/src/index.ts` make the following changes:
// ... other feature additions
+ const linguistSchedule: TaskScheduleDefinition = {
+ frequency: { minutes: 2 },
+ timeout: { minutes: 15 },
+ initialDelay: { seconds: 15 },
+ };
+ backend.add(
+ linguistPlugin({
+ schedule: linguistSchedule,
+ age: { days: 30 },
+ batchSize: 2,
+ useSourceLocation: false,
+ }),
+ );
+ backend.add(linguistPlugin());
backend.start();
```
The plugin options can be set through the `app-config.yaml`:
```yaml
// ...
linguist:
schedule:
frequency:
minutes: 2
timeout:
minutes: 2
initialDelay:
seconds: 15
age:
days: 30
batchSize: 2
useSourceLocation: false
// ...
```
## Plugin Option
The Linguist backend has various plugin options that you can provide to the `createRouter` function in your `packages/backend/src/plugins/linguist.ts` file that will allow you to configure various aspects of how it works. The following sections go into the details of these options
+8 -17
View File
@@ -27,6 +27,11 @@ export function createRouter(
routerOptions: RouterOptions,
): Promise<express.Router>;
// @public (undocumented)
export function createRouterFromConfig(
routerOptions: RouterOptions,
): Promise<express.Router>;
// @public (undocumented)
export interface LinguistBackendApi {
// (undocumented)
@@ -36,23 +41,7 @@ export interface LinguistBackendApi {
}
// @public
export const linguistPlugin: (options: LinguistPluginOptions) => BackendFeature;
// @public
export interface LinguistPluginOptions {
// (undocumented)
age?: HumanDuration;
// (undocumented)
batchSize?: number;
// (undocumented)
kind?: string[];
// (undocumented)
linguistJsOptions?: Record<string, unknown>;
// (undocumented)
schedule?: TaskScheduleDefinition;
// (undocumented)
useSourceLocation?: boolean;
}
export const linguistPlugin: () => BackendFeature;
// @public
export class LinguistTagsProcessor implements CatalogProcessor {
@@ -104,6 +93,8 @@ export interface PluginOptions {
// @public (undocumented)
export interface RouterOptions {
// (undocumented)
config?: Config;
// (undocumented)
database: PluginDatabaseManager;
// (undocumented)
+24
View File
@@ -14,11 +14,35 @@
* limitations under the License.
*/
import { TaskScheduleDefinition } from '@backstage/backend-tasks';
import { HumanDuration } from '@backstage/types';
import { Options as LinguistJsOptions } from 'linguist-js/dist/types';
export interface Config {
/** Configuration options for the linguist plugin */
linguist?: {
schedule?: TaskScheduleDefinition;
/**
* @default 20
*/
batchSize?: number;
/**
* @default false
*/
useSourceLocation?: boolean;
/**
* Refresh generated language breakdown
*/
age?: HumanDuration;
/**
* @default ['API', 'Component', 'Template']
*/
kind?: string[];
/**
* [linguist-js](https://www.npmjs.com/package/linguist-js) options
*/
linguistJsOptions?: LinguistJsOptions;
/** Options for the tags processor */
tagsProcessor?: {
/**
-1
View File
@@ -24,4 +24,3 @@ export * from './processor';
export * from './service/router';
export type { LinguistBackendApi } from './api';
export { linguistPlugin } from './plugin';
export type { LinguistPluginOptions } from './plugin';
+40 -59
View File
@@ -19,69 +19,50 @@ import {
coreServices,
createBackendPlugin,
} from '@backstage/backend-plugin-api';
import { createRouter } from './service/router';
import { TaskScheduleDefinition } from '@backstage/backend-tasks';
import { HumanDuration } from '@backstage/types';
/**
* Options for Linguist backend plugin
*
* @public
*/
export interface LinguistPluginOptions {
schedule?: TaskScheduleDefinition;
age?: HumanDuration;
batchSize?: number;
useSourceLocation?: boolean;
linguistJsOptions?: Record<string, unknown>;
kind?: string[];
}
import { createRouterFromConfig } from './service/router';
/**
* Linguist backend plugin
*
* @public
*/
export const linguistPlugin = createBackendPlugin(
(options: LinguistPluginOptions) => ({
pluginId: 'linguist',
register(env) {
env.registerInit({
deps: {
logger: coreServices.logger,
reader: coreServices.urlReader,
database: coreServices.database,
discovery: coreServices.discovery,
scheduler: coreServices.scheduler,
tokenManager: coreServices.tokenManager,
httpRouter: coreServices.httpRouter,
},
async init({
logger,
reader,
database,
discovery,
scheduler,
tokenManager,
httpRouter,
}) {
httpRouter.use(
await createRouter(
{
...options,
},
{
logger: loggerToWinstonLogger(logger),
reader,
database,
discovery,
scheduler,
tokenManager,
},
),
);
},
});
},
}),
);
export const linguistPlugin = createBackendPlugin({
pluginId: 'linguist',
register(env) {
env.registerInit({
deps: {
logger: coreServices.logger,
config: coreServices.rootConfig,
reader: coreServices.urlReader,
database: coreServices.database,
discovery: coreServices.discovery,
scheduler: coreServices.scheduler,
tokenManager: coreServices.tokenManager,
httpRouter: coreServices.httpRouter,
},
async init({
logger,
config,
reader,
database,
discovery,
scheduler,
tokenManager,
httpRouter,
}) {
httpRouter.use(
await createRouterFromConfig({
logger: loggerToWinstonLogger(logger),
config,
reader,
database,
discovery,
scheduler,
tokenManager,
}),
);
},
});
},
});
@@ -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<LinguistBackendApi>;
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');
+31 -3
View File
@@ -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<express.Router> {
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);
}