From 95ad0d02dc9b871ae389d6d100d642cb01d0defd Mon Sep 17 00:00:00 2001 From: Sebastian Poxhofer Date: Sat, 25 Nov 2023 07:37:05 +0100 Subject: [PATCH] refactor(datasource/custom): use class based fetcher to simplify code (#25958) --- lib/config/types.ts | 5 ++- .../datasource/custom/formats/index.ts | 14 +++++++ lib/modules/datasource/custom/formats/json.ts | 17 ++++---- .../datasource/custom/formats/plain.ts | 28 ++++++------- .../datasource/custom/formats/types.ts | 6 +++ lib/modules/datasource/custom/formats/yaml.ts | 17 ++++---- lib/modules/datasource/custom/index.ts | 41 +++++-------------- 7 files changed, 68 insertions(+), 60 deletions(-) create mode 100644 lib/modules/datasource/custom/formats/index.ts create mode 100644 lib/modules/datasource/custom/formats/types.ts diff --git a/lib/config/types.ts b/lib/config/types.ts index 04a02bc91b08c4..bb36d35e88a465 100644 --- a/lib/config/types.ts +++ b/lib/config/types.ts @@ -262,9 +262,12 @@ export interface RenovateConfig customizeDashboard?: Record; } +const CustomDatasourceFormats = ['json', 'plain', 'yaml'] as const; +export type CustomDatasourceFormats = (typeof CustomDatasourceFormats)[number]; + export interface CustomDatasourceConfig { defaultRegistryUrlTemplate?: string; - format?: 'json' | 'plain' | 'yaml'; + format?: CustomDatasourceFormats; transformTemplates?: string[]; } diff --git a/lib/modules/datasource/custom/formats/index.ts b/lib/modules/datasource/custom/formats/index.ts new file mode 100644 index 00000000000000..fc69533b3a0bfc --- /dev/null +++ b/lib/modules/datasource/custom/formats/index.ts @@ -0,0 +1,14 @@ +import type { CustomDatasourceFormats } from '../../../../config/types'; +import { JSONFetcher } from './json'; +import { PlainFetcher } from './plain'; +import type { CustomDatasourceFetcher } from './types'; +import { YamlFetcher } from './yaml'; + +export const fetchers: Record< + CustomDatasourceFormats, + CustomDatasourceFetcher +> = { + json: new JSONFetcher(), + plain: new PlainFetcher(), + yaml: new YamlFetcher(), +}; diff --git a/lib/modules/datasource/custom/formats/json.ts b/lib/modules/datasource/custom/formats/json.ts index b2b1e2e30e15b6..ead333419bbd91 100644 --- a/lib/modules/datasource/custom/formats/json.ts +++ b/lib/modules/datasource/custom/formats/json.ts @@ -1,13 +1,16 @@ import { readLocalFile } from '../../../../util/fs'; import type { Http } from '../../../../util/http'; +import type { CustomDatasourceFetcher } from './types'; -export async function fetch(http: Http, url: string): Promise { - const response = await http.getJson(url); - return response.body; -} +export class JSONFetcher implements CustomDatasourceFetcher { + async fetch(http: Http, registryURL: string): Promise { + const response = await http.getJson(registryURL); + return response.body; + } -export async function read(path: string): Promise { - const fileContent = await readLocalFile(path, 'utf8'); + async readFile(registryURL: string): Promise { + const fileContent = await readLocalFile(registryURL, 'utf8'); - return JSON.parse(fileContent!); + return JSON.parse(fileContent!); + } } diff --git a/lib/modules/datasource/custom/formats/plain.ts b/lib/modules/datasource/custom/formats/plain.ts index 8548752ea94187..4b492b4063b7bb 100644 --- a/lib/modules/datasource/custom/formats/plain.ts +++ b/lib/modules/datasource/custom/formats/plain.ts @@ -2,6 +2,7 @@ import { readLocalFile } from '../../../../util/fs'; import type { Http } from '../../../../util/http'; import { newlineRegex } from '../../../../util/regex'; import type { ReleaseResult } from '../../types'; +import type { CustomDatasourceFetcher } from './types'; function convertLinesToVersions(content: string): ReleaseResult { const lines = content.split(newlineRegex).map((line) => line.trim()); @@ -15,22 +16,21 @@ function convertLinesToVersions(content: string): ReleaseResult { }; } -export async function fetch( - http: Http, - url: string, -): Promise { - const response = await http.getPlain(url); +export class PlainFetcher implements CustomDatasourceFetcher { + async fetch(http: Http, registryURL: string): Promise { + const response = await http.getPlain(registryURL); - const contentType = response.headers['content-type']; - if (!contentType?.startsWith('text/')) { - return null; - } + const contentType = response.headers['content-type']; + if (!contentType?.startsWith('text/')) { + return null; + } - return convertLinesToVersions(response.body); -} + return convertLinesToVersions(response.body); + } -export async function read(path: string): Promise { - const fileContent = await readLocalFile(path, 'utf8'); + async readFile(registryURL: string): Promise { + const fileContent = await readLocalFile(registryURL, 'utf8'); - return fileContent ? convertLinesToVersions(fileContent) : null; + return fileContent ? convertLinesToVersions(fileContent) : null; + } } diff --git a/lib/modules/datasource/custom/formats/types.ts b/lib/modules/datasource/custom/formats/types.ts new file mode 100644 index 00000000000000..790bf9f9d9fe0f --- /dev/null +++ b/lib/modules/datasource/custom/formats/types.ts @@ -0,0 +1,6 @@ +import type { Http } from '../../../../util/http'; + +export interface CustomDatasourceFetcher { + fetch(http: Http, registryURL: string): Promise; + readFile(registryURL: string): Promise; +} diff --git a/lib/modules/datasource/custom/formats/yaml.ts b/lib/modules/datasource/custom/formats/yaml.ts index 38e9af354decbe..076ded0a7f9a5b 100644 --- a/lib/modules/datasource/custom/formats/yaml.ts +++ b/lib/modules/datasource/custom/formats/yaml.ts @@ -1,15 +1,18 @@ import yaml from 'js-yaml'; import { readLocalFile } from '../../../../util/fs'; import type { Http } from '../../../../util/http'; +import type { CustomDatasourceFetcher } from './types'; -export async function fetch(http: Http, url: string): Promise { - const response = await http.get(url); +export class YamlFetcher implements CustomDatasourceFetcher { + async fetch(http: Http, registryURL: string): Promise { + const response = await http.get(registryURL); - return yaml.load(response.body); -} + return yaml.load(response.body); + } -export async function read(path: string): Promise { - const fileContent = await readLocalFile(path, 'utf8'); + async readFile(registryURL: string): Promise { + const fileContent = await readLocalFile(registryURL, 'utf8'); - return yaml.load(fileContent!); + return yaml.load(fileContent!); + } } diff --git a/lib/modules/datasource/custom/index.ts b/lib/modules/datasource/custom/index.ts index 25518368c827e9..d54b7d0d2c9dc6 100644 --- a/lib/modules/datasource/custom/index.ts +++ b/lib/modules/datasource/custom/index.ts @@ -3,9 +3,7 @@ import jsonata from 'jsonata'; import { logger } from '../../../logger'; import { Datasource } from '../datasource'; import type { GetReleasesConfig, ReleaseResult } from '../types'; -import { fetch as jsonFetch, read as jsonRead } from './formats/json'; -import { fetch as plainFetch, read as plainRead } from './formats/plain'; -import { fetch as yamlFetch, read as yamlRead } from './formats/yaml'; +import { fetchers } from './formats'; import { ReleaseResultZodSchema } from './schema'; import { getCustomConfig } from './utils'; @@ -28,38 +26,19 @@ export class CustomDatasource extends Datasource { const { defaultRegistryUrlTemplate, transformTemplates, format } = config; + const fetcher = fetchers[format]; const isLocalRegistry = defaultRegistryUrlTemplate.startsWith('file://'); let data: unknown; - if (isLocalRegistry) { - switch (format) { - case 'plain': - data = await plainRead(defaultRegistryUrlTemplate); - break; - case 'yaml': - data = await yamlRead(defaultRegistryUrlTemplate); - break; - case 'json': - data = await jsonRead(defaultRegistryUrlTemplate); - break; - } - } else { - try { - switch (format) { - case 'plain': - data = await plainFetch(this.http, defaultRegistryUrlTemplate); - break; - case 'yaml': - data = await yamlFetch(this.http, defaultRegistryUrlTemplate); - break; - case 'json': - data = await jsonFetch(this.http, defaultRegistryUrlTemplate); - break; - } - } catch (e) { - this.handleHttpErrors(e); - return null; + try { + if (isLocalRegistry) { + data = await fetcher.readFile(defaultRegistryUrlTemplate); + } else { + data = await fetcher.fetch(this.http, defaultRegistryUrlTemplate); } + } catch (e) { + this.handleHttpErrors(e); + return null; } for (const transformTemplate of transformTemplates) {