From a68ba8fc74cf84cbec6ae96948433521961c2320 Mon Sep 17 00:00:00 2001
From: Jamie Magee <jamie.magee@gmail.com>
Date: Sun, 27 Jun 2021 01:25:29 -0700
Subject: [PATCH] refactor(ruby-version): convert to class-based (#10508)

---
 lib/datasource/api.ts                     |  4 +-
 lib/datasource/ruby-version/index.spec.ts |  4 +-
 lib/datasource/ruby-version/index.ts      | 87 ++++++++++++-----------
 lib/manager/ruby-version/extract.ts       |  4 +-
 4 files changed, 53 insertions(+), 46 deletions(-)

diff --git a/lib/datasource/api.ts b/lib/datasource/api.ts
index 8cf8702425..cdcc24f13b 100644
--- a/lib/datasource/api.ts
+++ b/lib/datasource/api.ts
@@ -24,7 +24,7 @@ import * as packagist from './packagist';
 import * as pod from './pod';
 import * as pypi from './pypi';
 import * as repology from './repology';
-import * as rubyVersion from './ruby-version';
+import { RubyVersionDatasource } from './ruby-version';
 import * as rubygems from './rubygems';
 import * as sbtPackage from './sbt-package';
 import * as sbtPlugin from './sbt-plugin';
@@ -61,7 +61,7 @@ api.set('packagist', packagist);
 api.set('pod', pod);
 api.set('pypi', pypi);
 api.set('repology', repology);
-api.set('ruby-version', rubyVersion);
+api.set('ruby-version', new RubyVersionDatasource());
 api.set('rubygems', rubygems);
 api.set('sbt-package', sbtPackage);
 api.set('sbt-plugin', sbtPlugin);
diff --git a/lib/datasource/ruby-version/index.spec.ts b/lib/datasource/ruby-version/index.spec.ts
index 3efbd83d38..a4e94ce0b5 100644
--- a/lib/datasource/ruby-version/index.spec.ts
+++ b/lib/datasource/ruby-version/index.spec.ts
@@ -1,10 +1,12 @@
 import { getPkgReleases } from '..';
 import * as httpMock from '../../../test/http-mock';
 import { getName, loadFixture } from '../../../test/util';
-import { id as datasource } from '.';
+import { RubyVersionDatasource } from '.';
 
 const rubyReleasesHtml = loadFixture('releases.html');
 
+const datasource = RubyVersionDatasource.id;
+
 describe(getName(), () => {
   describe('getReleases', () => {
     it('parses real data', async () => {
diff --git a/lib/datasource/ruby-version/index.ts b/lib/datasource/ruby-version/index.ts
index f225b9fbca..9019d63c88 100644
--- a/lib/datasource/ruby-version/index.ts
+++ b/lib/datasource/ruby-version/index.ts
@@ -1,58 +1,63 @@
 import { ExternalHostError } from '../../types/errors/external-host-error';
-import * as packageCache from '../../util/cache/package';
+import { cache } from '../../util/cache/package/decorator';
 import { parse } from '../../util/html';
-import { Http } from '../../util/http';
+import { HttpError } from '../../util/http/types';
 import { isVersion, id as rubyVersioningId } from '../../versioning/ruby';
+import { Datasource } from '../datasource';
 import type { GetReleasesConfig, ReleaseResult } from '../types';
 
-export const id = 'ruby-version';
-export const defaultRegistryUrls = ['https://www.ruby-lang.org/'];
-export const customRegistrySupport = false;
-export const defaultVersioning = rubyVersioningId;
-
-const http = new Http(id);
-
-export async function getReleases({
-  registryUrl,
-}: GetReleasesConfig): Promise<ReleaseResult | null> {
-  // First check the persistent cache
-  const cacheNamespace = 'datasource-ruby-version';
-  const cachedResult = await packageCache.get<ReleaseResult>(
-    cacheNamespace,
-    'all'
-  );
-  // istanbul ignore if
-  if (cachedResult) {
-    return cachedResult;
+export class RubyVersionDatasource extends Datasource {
+  static readonly id = 'ruby-version';
+
+  constructor() {
+    super(RubyVersionDatasource.id);
   }
-  try {
+
+  readonly defaultRegistryUrls = ['https://www.ruby-lang.org/'];
+
+  readonly customRegistrySupport = false;
+
+  readonly defaultVersioning = rubyVersioningId;
+
+  @cache({ namespace: `datasource-${RubyVersionDatasource.id}`, key: 'all' })
+  async getReleases({
+    registryUrl,
+  }: GetReleasesConfig): Promise<ReleaseResult | null> {
     const res: ReleaseResult = {
       homepage: 'https://www.ruby-lang.org',
       sourceUrl: 'https://github.com/ruby/ruby',
       releases: [],
     };
     const rubyVersionsUrl = `${registryUrl}en/downloads/releases/`;
-    const response = await http.get(rubyVersionsUrl);
-    const root = parse(response.body);
-    const rows = root.querySelector('.release-list').querySelectorAll('tr');
-    rows.forEach((row) => {
-      const tds = row.querySelectorAll('td');
-      const columns: string[] = [];
-      tds.forEach((td) => columns.push(td.innerHTML));
-      if (columns.length) {
-        const version = columns[0].replace('Ruby ', '');
-        if (isVersion(version)) {
-          const releaseTimestamp = columns[1];
-          const changelogUrl = columns[2]
-            .replace('<a href="', 'https://www.ruby-lang.org')
-            .replace('">more...</a>', '');
-          res.releases.push({ version, releaseTimestamp, changelogUrl });
+    try {
+      const response = await this.http.get(rubyVersionsUrl);
+
+      const root = parse(response.body);
+      const rows = root.querySelector('.release-list').querySelectorAll('tr');
+      rows.forEach((row) => {
+        const tds = row.querySelectorAll('td');
+        const columns: string[] = [];
+        tds.forEach((td) => columns.push(td.innerHTML));
+        if (columns.length) {
+          const version = columns[0].replace('Ruby ', '');
+          if (isVersion(version)) {
+            const releaseTimestamp = columns[1];
+            const changelogUrl = columns[2]
+              .replace('<a href="', 'https://www.ruby-lang.org')
+              .replace('">more...</a>', '');
+            res.releases.push({ version, releaseTimestamp, changelogUrl });
+          }
         }
-      }
-    });
-    await packageCache.set(cacheNamespace, 'all', res, 15);
+      });
+    } catch (err) {
+      this.handleGenericErrors(err);
+    }
+
     return res;
-  } catch (err) {
+  }
+
+  // eslint-disable-next-line class-methods-use-this
+  override handleSpecificErrors(err: HttpError): never | void {
     throw new ExternalHostError(err);
   }
 }
diff --git a/lib/manager/ruby-version/extract.ts b/lib/manager/ruby-version/extract.ts
index 57621bce2f..b71b58660c 100644
--- a/lib/manager/ruby-version/extract.ts
+++ b/lib/manager/ruby-version/extract.ts
@@ -1,4 +1,4 @@
-import * as datasourceRubyVersion from '../../datasource/ruby-version';
+import { RubyVersionDatasource } from '../../datasource/ruby-version';
 import { logger } from '../../logger';
 import type { PackageDependency, PackageFile } from '../types';
 
@@ -7,7 +7,7 @@ export function extractPackageFile(content: string): PackageFile {
   const dep: PackageDependency = {
     depName: 'ruby',
     currentValue: content.trim(),
-    datasource: datasourceRubyVersion.id,
+    datasource: RubyVersionDatasource.id,
   };
   return { deps: [dep] };
 }
-- 
GitLab