diff --git a/lib/datasource/api.ts b/lib/datasource/api.ts index cdcc24f13bb13cdb7ed5a5604675600993767122..3dd5e93b2f3f566b69dee9d1d5d6c8746b0cf31e 100644 --- a/lib/datasource/api.ts +++ b/lib/datasource/api.ts @@ -14,7 +14,7 @@ import * as gitlabTags from './gitlab-tags'; import * as go from './go'; import { GradleVersionDatasource } from './gradle-version'; import { HelmDatasource } from './helm'; -import * as hex from './hex'; +import { HexDatasource } from './hex'; import * as jenkinsPlugins from './jenkins-plugins'; import * as maven from './maven'; import * as npm from './npm'; @@ -51,7 +51,7 @@ api.set('gitlab-tags', gitlabTags); api.set('go', go); api.set('gradle-version', new GradleVersionDatasource()); api.set('helm', new HelmDatasource()); -api.set('hex', hex); +api.set('hex', new HexDatasource()); api.set('jenkins-plugins', jenkinsPlugins); api.set('maven', maven); api.set('npm', npm); diff --git a/lib/datasource/hex/index.spec.ts b/lib/datasource/hex/index.spec.ts index d6f453018a816a11c511845b7bb85899d395b2f7..d5bd072d0d0ca53ea725dcc8aa19eb835dfeed84 100644 --- a/lib/datasource/hex/index.spec.ts +++ b/lib/datasource/hex/index.spec.ts @@ -3,7 +3,7 @@ import * as httpMock from '../../../test/http-mock'; import { getName, loadJsonFixture } from '../../../test/util'; import { EXTERNAL_HOST_ERROR } from '../../constants/error-messages'; import * as _hostRules from '../../util/host-rules'; -import { id as datasource } from '.'; +import { HexDatasource } from '.'; const hostRules: any = _hostRules; @@ -12,6 +12,7 @@ const res1 = loadJsonFixture('certifi.json'); jest.mock('../../util/host-rules'); const baseUrl = 'https://hex.pm/api/packages/'; +const datasource = HexDatasource.id; describe(getName(), () => { beforeEach(() => { diff --git a/lib/datasource/hex/index.ts b/lib/datasource/hex/index.ts index 9704251be5b19b4c365bd08434ac9d4a4b6cbe05..4a0fde477e44f54c379573bace3147a7cce79256 100644 --- a/lib/datasource/hex/index.ts +++ b/lib/datasource/hex/index.ts @@ -1,30 +1,46 @@ import { logger } from '../../logger'; -import { ExternalHostError } from '../../types/errors/external-host-error'; -import { Http } from '../../util/http'; +import { cache } from '../../util/cache/package/decorator'; +import type { HttpResponse } from '../../util/http'; import * as hexVersioning from '../../versioning/hex'; +import { Datasource } from '../datasource'; import type { GetReleasesConfig, ReleaseResult } from '../types'; import type { HexRelease } from './types'; -export const id = 'hex'; -export const defaultRegistryUrls = ['https://hex.pm/']; -export const customRegistrySupport = false; -export const defaultVersioning = hexVersioning.id; +export class HexDatasource extends Datasource { + static readonly id = 'hex'; -const http = new Http(id); + constructor() { + super(HexDatasource.id); + } + + override readonly defaultRegistryUrls = ['https://hex.pm/']; + + override readonly customRegistrySupport = false; + + override readonly defaultVersioning = hexVersioning.id; -export async function getReleases({ - lookupName, - registryUrl, -}: GetReleasesConfig): Promise<ReleaseResult | null> { - // Get dependency name from lookupName. - // If the dependency is private lookupName contains organization name as following: - // hexPackageName:organizationName - // hexPackageName is used to pass it in hex dep url - // organizationName is used for accessing to private deps - const hexPackageName = lookupName.split(':')[0]; - const hexUrl = `${registryUrl}api/packages/${hexPackageName}`; - try { - const response = await http.getJson<HexRelease>(hexUrl); + @cache({ + namespace: `datasource-${HexDatasource.id}`, + key: ({ lookupName }: GetReleasesConfig) => lookupName, + }) + async getReleases({ + lookupName, + registryUrl, + }: GetReleasesConfig): Promise<ReleaseResult | null> { + // Get dependency name from lookupName. + // If the dependency is private lookupName contains organization name as following: + // hexPackageName:organizationName + // hexPackageName is used to pass it in hex dep url + // organizationName is used for accessing to private deps + const hexPackageName = lookupName.split(':')[0]; + const hexUrl = `${registryUrl}api/packages/${hexPackageName}`; + + let response: HttpResponse<HexRelease>; + try { + response = await this.http.getJson<HexRelease>(hexUrl); + } catch (err) { + this.handleGenericErrors(err); + } const hexRelease: HexRelease = response.body; @@ -60,13 +76,5 @@ export async function getReleases({ } return result; - } catch (err) { - if ( - err.statusCode === 429 || - (err.statusCode >= 500 && err.statusCode < 600) - ) { - throw new ExternalHostError(err); - } - throw err; } } diff --git a/lib/manager/mix/extract.ts b/lib/manager/mix/extract.ts index b5b3cf33feabeeee17784786a8dfaf8336f49ac9..5eacc93ff065a725759651126edd3819dec0c725 100644 --- a/lib/manager/mix/extract.ts +++ b/lib/manager/mix/extract.ts @@ -1,4 +1,4 @@ -import * as datasourceHex from '../../datasource/hex'; +import { HexDatasource } from '../../datasource/hex'; import { logger } from '../../logger'; import { SkipReason } from '../../types'; import { getSiblingFileName, localPathExists } from '../../util/fs'; @@ -39,9 +39,9 @@ export async function extractPackageFile( managerData: {}, }; - dep.datasource = datasource || datasourceHex.id; + dep.datasource = datasource || HexDatasource.id; - if (dep.datasource === datasourceHex.id) { + if (dep.datasource === HexDatasource.id) { dep.currentValue = currentValue; dep.lookupName = depName; } @@ -50,7 +50,7 @@ export async function extractPackageFile( dep.lookupName += ':' + organization; } - if (dep.datasource !== datasourceHex.id) { + if (dep.datasource !== HexDatasource.id) { dep.skipReason = SkipReason.NonHexDeptypes; }