From fd4547221311fa2db5cc0e9fb37b513f4f8d69fe Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 11 Mar 2021 21:23:17 +0100 Subject: [PATCH] todo-backend: add support for configuring the default parser Signed-off-by: Patrik Oldsberg --- .github/styles/vocab.txt | 1 + plugins/todo-backend/README.md | 21 +++++++++ .../src/lib/TodoReader/TodoScmReader.ts | 28 ++---------- .../src/lib/TodoReader/createTodoParser.ts | 44 +++++++++++++++++++ .../todo-backend/src/lib/TodoReader/index.ts | 1 + .../todo-backend/src/lib/TodoReader/types.ts | 13 ++++++ 6 files changed, 84 insertions(+), 24 deletions(-) create mode 100644 plugins/todo-backend/src/lib/TodoReader/createTodoParser.ts diff --git a/.github/styles/vocab.txt b/.github/styles/vocab.txt index 489727ca4d..dc3ef0f036 100644 --- a/.github/styles/vocab.txt +++ b/.github/styles/vocab.txt @@ -42,6 +42,7 @@ JavaScript Kaewkasi Knex Kumar +Leasot Lerna Lundberg Luxon diff --git a/plugins/todo-backend/README.md b/plugins/todo-backend/README.md index 4f79bab7a8..0e455977f9 100644 --- a/plugins/todo-backend/README.md +++ b/plugins/todo-backend/README.md @@ -35,3 +35,24 @@ export default async function createPlugin({ return await createRouter({ todoService }); } ``` + +## Parser Configuration + +The `TodoScmReader` accepts a `TodoParser` option, which can be used to configure your own parser. The default one is based on [Leasot](https://github.com/pgilad/leasot) and supports a wide range of languages. You can change the list of supported tags by configuring your own version of the built-in parser, for example: + +```ts +import { + TodoScmReader, + createTodoParser, +} from '@backstage/plugin-todo-backend'; + +// ... + +const todoReader = TodoScmReader.fromConfig(config, { + logger, + reader, + parser: createTodoParser({ + tags: ['TODO', 'FIXME', 'NOTE', 'XXX'], + }), +}); +``` diff --git a/plugins/todo-backend/src/lib/TodoReader/TodoScmReader.ts b/plugins/todo-backend/src/lib/TodoReader/TodoScmReader.ts index 2a191d2cb4..302c5985d6 100644 --- a/plugins/todo-backend/src/lib/TodoReader/TodoScmReader.ts +++ b/plugins/todo-backend/src/lib/TodoReader/TodoScmReader.ts @@ -14,23 +14,19 @@ * limitations under the License. */ -import { extname } from 'path'; import { UrlReader } from '@backstage/backend-common'; import { ScmIntegrations } from '@backstage/integration'; import { Logger } from 'winston'; -import { parse } from 'leasot'; + import { ReadTodosOptions, ReadTodosResult, TodoItem, + TodoParser, TodoReader, } from './types'; import { Config } from '@backstage/config'; - -type TodoParser = (ctx: { - content: string; - path: string; -}) => { text: string; author?: string; lineNumber: number }[]; +import { createTodoParser } from './createTodoParser'; type Options = { logger: Logger; @@ -43,22 +39,6 @@ type CacheItem = { result: ReadTodosResult; }; -const defaultTodoParser: TodoParser = ({ content, path }) => { - try { - const comments = parse(content, { - extension: extname(path), - }); - - return comments.map(comment => ({ - text: comment.text, - author: comment.ref, - lineNumber: comment.line, - })); - } catch /* ignore unsupported extensions */ { - return []; - } -}; - export class TodoScmReader implements TodoReader { private readonly logger: Logger; private readonly reader: UrlReader; @@ -74,7 +54,7 @@ export class TodoScmReader implements TodoReader { private constructor(options: Options, integrations: ScmIntegrations) { this.logger = options.logger; this.reader = options.reader; - this.parser = options.parser ?? defaultTodoParser; + this.parser = options.parser ?? createTodoParser(); this.integrations = integrations; } diff --git a/plugins/todo-backend/src/lib/TodoReader/createTodoParser.ts b/plugins/todo-backend/src/lib/TodoReader/createTodoParser.ts new file mode 100644 index 0000000000..deb0ed8800 --- /dev/null +++ b/plugins/todo-backend/src/lib/TodoReader/createTodoParser.ts @@ -0,0 +1,44 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { extname } from 'path'; +import { parse } from 'leasot'; +import { TodoParser } from './types'; + +export type TodoParserOptions = { + tags?: string[]; +}; + +export function createTodoParser(options: TodoParserOptions = {}): TodoParser { + const { tags = ['TODO', 'FIXME'] } = options; + + return ({ content, path }) => { + try { + const comments = parse(content, { + customTags: tags, + extension: extname(path), + }); + + return comments.map(comment => ({ + text: comment.text, + author: comment.ref, + lineNumber: comment.line, + })); + } catch /* ignore unsupported extensions */ { + return []; + } + }; +} diff --git a/plugins/todo-backend/src/lib/TodoReader/index.ts b/plugins/todo-backend/src/lib/TodoReader/index.ts index 22c47ebef2..58982385c8 100644 --- a/plugins/todo-backend/src/lib/TodoReader/index.ts +++ b/plugins/todo-backend/src/lib/TodoReader/index.ts @@ -15,6 +15,7 @@ */ export { TodoScmReader } from './TodoScmReader'; +export { createTodoParser } from './createTodoParser'; export type { TodoItem, TodoReader, diff --git a/plugins/todo-backend/src/lib/TodoReader/types.ts b/plugins/todo-backend/src/lib/TodoReader/types.ts index 499d3ac843..78859841d7 100644 --- a/plugins/todo-backend/src/lib/TodoReader/types.ts +++ b/plugins/todo-backend/src/lib/TodoReader/types.ts @@ -51,3 +51,16 @@ export interface TodoReader { */ readTodos(options: ReadTodosOptions): Promise; } + +type TodoParserContext = { + content: string; + path: string; +}; + +type TodoParserResult = { + text: string; + author?: string; + lineNumber: number; +}; + +export type TodoParser = (ctx: TodoParserContext) => TodoParserResult[];