diff --git a/lib/modules/datasource/custom/formats/plain.ts b/lib/modules/datasource/custom/formats/plain.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ac1ef928e8d21f76170902fa6f2386110824a054
--- /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 33438f922055ce0188684e2e0446e3795846afaf..166e7958fe3dfbb75af22817eae7c40747d256b2 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 15d95a021687d935b24c00348f398b09c6b189a7..d011ca22b637db0245a2019dc786949d095cb326 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 70db40a1c139832f1bf741ac8f28642721246f18..d85b4026f6efae1115b1474dd5937b39868b63d2 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 98db134c62ddc619a85606708b8a2561a474047c..f0dfd338a6f66ba32e08e0b008c6fc2621e4042a 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>,