From d10dcff495c7de06f324e0d26e6add6ee08747d6 Mon Sep 17 00:00:00 2001 From: Sebastian Poxhofer <secustor@users.noreply.github.com> Date: Wed, 8 Nov 2023 07:05:22 +0100 Subject: [PATCH] refactor(custom/datasource): prepare for additional format types (#25640) --- .../datasource/custom/formats/plain.ts | 23 ++++++++ lib/modules/datasource/custom/index.ts | 52 ++++--------------- lib/modules/datasource/custom/utils.ts | 18 +++++++ lib/modules/platform/gitlab/index.ts | 3 +- lib/util/http/index.ts | 10 ++++ 5 files changed, 61 insertions(+), 45 deletions(-) create mode 100644 lib/modules/datasource/custom/formats/plain.ts diff --git a/lib/modules/datasource/custom/formats/plain.ts b/lib/modules/datasource/custom/formats/plain.ts new file mode 100644 index 0000000000..ac1ef928e8 --- /dev/null +++ b/lib/modules/datasource/custom/formats/plain.ts @@ -0,0 +1,23 @@ +import type { Http } from '../../../../util/http'; +import { newlineRegex } from '../../../../util/regex'; +import type { ReleaseResult } from '../../types'; + +export async function fetch( + http: Http, + url: string, +): Promise<ReleaseResult | null> { + const response = await http.getPlain(url); + const contentType = response.headers['content-type']; + if (!contentType?.startsWith('text/')) { + return null; + } + const lines = response.body.split(newlineRegex).map((line) => line.trim()); + + const versions = lines.map((value) => { + return { version: value }; + }); + + return { + releases: versions, + }; +} diff --git a/lib/modules/datasource/custom/index.ts b/lib/modules/datasource/custom/index.ts index 33438f9220..166e7958fe 100644 --- a/lib/modules/datasource/custom/index.ts +++ b/lib/modules/datasource/custom/index.ts @@ -1,11 +1,11 @@ import is from '@sindresorhus/is'; import jsonata from 'jsonata'; import { logger } from '../../../logger'; -import { newlineRegex } from '../../../util/regex'; import { Datasource } from '../datasource'; import type { GetReleasesConfig, ReleaseResult } from '../types'; +import { fetch as plainFetch } from './formats/plain'; import { ReleaseResultZodSchema } from './schema'; -import { massageCustomDatasourceConfig } from './utils'; +import { getCustomConfig } from './utils'; export class CustomDatasource extends Datasource { static readonly id = 'custom'; @@ -19,34 +19,20 @@ export class CustomDatasource extends Datasource { async getReleases( getReleasesConfig: GetReleasesConfig, ): Promise<ReleaseResult | null> { - const customDatasourceName = getReleasesConfig.datasource?.replace( - 'custom.', - '', - ); - - if (!is.nonEmptyString(customDatasourceName)) { - logger.debug( - `No datasource has been supplied while looking up ${getReleasesConfig.packageName}`, - ); - return null; - } - - const config = massageCustomDatasourceConfig( - customDatasourceName, - getReleasesConfig, - ); + const config = getCustomConfig(getReleasesConfig); if (is.nullOrUndefined(config)) { return null; } const { defaultRegistryUrlTemplate, transformTemplates, format } = config; - // TODO add here other format options than JSON and "plain" let response: unknown; try { - if (format === 'plain') { - response = await this.fetchPlainFormat(defaultRegistryUrlTemplate); - } else { - response = (await this.http.getJson(defaultRegistryUrlTemplate)).body; + switch (format) { + case 'plain': + response = await plainFetch(this.http, defaultRegistryUrlTemplate); + break; + case 'json': + response = (await this.http.getJson(defaultRegistryUrlTemplate)).body; } } catch (e) { this.handleHttpErrors(e); @@ -69,24 +55,4 @@ export class CustomDatasource extends Datasource { return null; } } - - private async fetchPlainFormat(url: string): Promise<unknown> { - const response = await this.http.get(url, { - headers: { - Accept: 'text/plain', - }, - }); - const contentType = response.headers['content-type']; - if (!contentType?.startsWith('text/')) { - return null; - } - const versions = response.body.split(newlineRegex).map((version) => { - return { - version: version.trim(), - }; - }); - return { - releases: versions, - }; - } } diff --git a/lib/modules/datasource/custom/utils.ts b/lib/modules/datasource/custom/utils.ts index 15d95a0216..d011ca22b6 100644 --- a/lib/modules/datasource/custom/utils.ts +++ b/lib/modules/datasource/custom/utils.ts @@ -44,3 +44,21 @@ export function massageCustomDatasourceConfig( transformTemplates: transform, }; } + +export function getCustomConfig( + getReleasesConfig: GetReleasesConfig, +): Required<CustomDatasourceConfig> | null { + const customDatasourceName = getReleasesConfig.datasource?.replace( + 'custom.', + '', + ); + + if (!is.nonEmptyString(customDatasourceName)) { + logger.debug( + `No datasource has been supplied while looking up ${getReleasesConfig.packageName}`, + ); + return null; + } + + return massageCustomDatasourceConfig(customDatasourceName, getReleasesConfig); +} diff --git a/lib/modules/platform/gitlab/index.ts b/lib/modules/platform/gitlab/index.ts index 70db40a1c1..d85b4026f6 100644 --- a/lib/modules/platform/gitlab/index.ts +++ b/lib/modules/platform/gitlab/index.ts @@ -18,8 +18,7 @@ import { import { logger } from '../../../logger'; import type { BranchStatus } from '../../../types'; import { coerceArray } from '../../../util/array'; -import { noLeadingAtSymbol } from '../../../util/common'; -import { parseJson } from '../../../util/common'; +import { noLeadingAtSymbol, parseJson } from '../../../util/common'; import * as git from '../../../util/git'; import * as hostRules from '../../../util/host-rules'; import { setBaseUrl } from '../../../util/http/gitlab'; diff --git a/lib/util/http/index.ts b/lib/util/http/index.ts index 98db134c62..f0dfd338a6 100644 --- a/lib/util/http/index.ts +++ b/lib/util/http/index.ts @@ -332,6 +332,16 @@ export class Http<Opts extends HttpOptions = HttpOptions> { return res; } + async getPlain(url: string, options?: Opts): Promise<HttpResponse> { + const opt = options ?? {}; + return await this.get(url, { + headers: { + Accept: 'text/plain', + }, + ...opt, + }); + } + getJson<ResT>( url: string, options?: Opts & HttpRequestOptions<ResT>, -- GitLab