updated to config as func

Signed-off-by: kim5566 <28945404+kim5566@users.noreply.github.com>
This commit is contained in:
kim5566
2022-02-18 07:02:46 +11:00
parent 107dc001c3
commit dda3f42ddd
4 changed files with 85 additions and 36 deletions
+21 -1
View File
@@ -2,4 +2,24 @@
'@backstage/plugin-todo-backend': patch
---
Add support to exclude vendor folder in `todo` plugin.
Add support to exclude certain folders in `todo` plugin.
You can add function by configuring your own exclusion logic, for example:
```ts
import {
TodoScmReader,
createTodoParser,
} from '@backstage/plugin-todo-backend';
// ...
const todoReader = TodoScmReader.fromConfig(config, {
logger,
reader,
filePathFilter: (filePath: string): boolean => {
...
YOUR LOGIC HERE
},
});
```
+1
View File
@@ -131,6 +131,7 @@ export type TodoScmReaderOptions = {
reader: UrlReader;
integrations: ScmIntegrations;
parser?: TodoParser;
filePathFilter?: (path: string) => boolean;
};
// @public (undocumented)
@@ -190,23 +190,18 @@ describe('TodoScmReader', () => {
);
});
it('should filter out exclude folders', async () => {
it('should not filter out exclude folders', async () => {
const reader = mockReader();
const filePathFilter = jest.fn(() => true);
const todoReader = new TodoScmReader({
logger: getVoidLogger(),
reader,
integrations: ScmIntegrations.fromConfig(new ConfigReader({})),
filePathFilter,
});
reader.readTree.mockResolvedValueOnce({
files: async () => [
{
content: async () => Buffer.from('// TODO: my-todo', 'utf8'),
path: 'vendor/another-file.go',
},
{
content: async () => Buffer.from('// TODO: my-todo', 'utf8'),
path: 'test/vendor/another-file.go',
},
{
content: async () => Buffer.from('// TODO: my-todo', 'utf8'),
path: 'my-folder/my-file.js',
@@ -219,22 +214,6 @@ describe('TodoScmReader', () => {
}),
).resolves.toEqual({
items: [
{
text: 'my-todo',
tag: 'TODO',
lineNumber: 1,
repoFilePath: 'vendor/another-file.go',
viewUrl:
'https://github.com/backstage/backstage/vendor/another-file.go#L1',
},
{
text: 'my-todo',
tag: 'TODO',
lineNumber: 1,
repoFilePath: 'test/vendor/another-file.go',
viewUrl:
'https://github.com/backstage/backstage/test/vendor/another-file.go#L1',
},
{
text: 'my-todo',
tag: 'TODO',
@@ -255,10 +234,55 @@ describe('TodoScmReader', () => {
);
// Filter function should filter out exclude folders
const filterFunc = reader.readTree.mock.calls[0][1]!.filter!;
expect(filterFunc('another-file.go')).toBe(true);
expect(filterFunc('vendor/another-file.go')).toBe(false);
expect(filterFunc('test/vendor/another-file.go')).toBe(false);
expect(filterFunc('my-file.js')).toBe(true);
expect(filterFunc('my-folder/my-file.js')).toBe(true);
});
it('should filter out exclude folders', async () => {
const reader = mockReader();
const filePathFilter = jest.fn(() => false);
const todoReader = new TodoScmReader({
logger: getVoidLogger(),
reader,
integrations: ScmIntegrations.fromConfig(new ConfigReader({})),
filePathFilter,
});
reader.readTree.mockResolvedValueOnce({
files: async () => [
{
content: async () => Buffer.from('// TODO: my-todo', 'utf8'),
path: 'my-folder/my-file.js',
},
],
} as ReadTreeResponse);
await expect(
todoReader.readTodos({
url: 'https://github.com/backstage/backstage/catalog-info.yaml',
}),
).resolves.toEqual({
items: [
{
text: 'my-todo',
tag: 'TODO',
lineNumber: 1,
repoFilePath: 'my-folder/my-file.js',
viewUrl:
'https://github.com/backstage/backstage/my-folder/my-file.js#L1',
},
],
});
expect(reader.readTree).toHaveBeenCalledTimes(1);
expect(reader.readTree).toHaveBeenCalledWith(
'https://github.com/backstage/backstage/catalog-info.yaml',
{
etag: undefined,
filter: expect.any(Function),
},
);
// Filter function should filter out exclude folders
const filterFunc = reader.readTree.mock.calls[0][1]!.filter!;
expect(filterFunc('my-file.js')).toBe(false);
expect(filterFunc('my-folder/my-file.js')).toBe(false);
});
});
@@ -41,14 +41,13 @@ const excludedExtensions = [
];
const MAX_FILE_SIZE = 200000;
const excludeFolders = ['vendor'];
/** @public */
export type TodoScmReaderOptions = {
logger: Logger;
reader: UrlReader;
integrations: ScmIntegrations;
parser?: TodoParser;
filePathFilter?: (filePath: string) => boolean;
};
type CacheItem = {
@@ -62,6 +61,7 @@ export class TodoScmReader implements TodoReader {
private readonly reader: UrlReader;
private readonly parser: TodoParser;
private readonly integrations: ScmIntegrations;
private readonly filePathFilter: (filePath: string) => boolean;
private readonly cache = new Map<string, CacheItem>();
private readonly inFlightReads = new Map<string, Promise<CacheItem>>();
@@ -81,6 +81,7 @@ export class TodoScmReader implements TodoReader {
this.reader = options.reader;
this.parser = options.parser ?? createTodoParser();
this.integrations = options.integrations;
this.filePathFilter = options.filePathFilter ?? (() => true);
}
async readTodos(options: ReadTodosOptions): Promise<ReadTodosResult> {
@@ -91,7 +92,12 @@ export class TodoScmReader implements TodoReader {
}
const cacheItem = this.cache.get(url);
const newRead = this.doReadTodos({ url }, cacheItem?.etag).catch(error => {
const filePathFilter = this.filePathFilter;
const newRead = this.doReadTodos(
{ url },
filePathFilter,
cacheItem?.etag,
).catch(error => {
if (cacheItem && error.name === 'NotModifiedError') {
return cacheItem;
}
@@ -110,13 +116,11 @@ export class TodoScmReader implements TodoReader {
private async doReadTodos(
options: ReadTodosOptions,
filePathFilter: (filePath: string) => boolean,
etag?: string,
): Promise<CacheItem> {
const { url } = options;
const filePathFilter = (filePath: string): boolean => {
const splitPath = filePath.split('/');
return !excludeFolders.some(r => splitPath.includes(r));
};
const tree = await this.reader.readTree(url, {
etag,
filter(filePath, info) {