From e631cae60126ea70ef78ccb3a12cd2d235610e76 Mon Sep 17 00:00:00 2001 From: Sebastian Poxhofer <secustor@users.noreply.github.com> Date: Thu, 29 Jul 2021 10:10:45 +0200 Subject: [PATCH] refactor(bitbucket-tags): move datasource to class (#10957) Co-authored-by: Jamie Magee <jamie.magee@gmail.com> Co-authored-by: Michael Kriese <michael.kriese@visualon.de> --- lib/datasource/api.ts | 4 +- lib/datasource/bitbucket-tags/index.spec.ts | 4 +- lib/datasource/bitbucket-tags/index.ts | 209 +++++++++--------- .../go/__snapshots__/index.spec.ts.snap | 1 + lib/datasource/go/index.ts | 3 +- 5 files changed, 111 insertions(+), 110 deletions(-) diff --git a/lib/datasource/api.ts b/lib/datasource/api.ts index 3dd5e93b2f..5dde26a33a 100644 --- a/lib/datasource/api.ts +++ b/lib/datasource/api.ts @@ -1,4 +1,4 @@ -import * as bitbucketTags from './bitbucket-tags'; +import { BitBucketTagsDatasource } from './bitbucket-tags'; import { CdnJsDatasource } from './cdnjs'; import { ClojureDatasource } from './clojure'; import * as crate from './crate'; @@ -35,7 +35,7 @@ import type { DatasourceApi } from './types'; const api = new Map<string, DatasourceApi>(); export default api; -api.set('bitbucket-tags', bitbucketTags); +api.set('bitbucket-tags', new BitBucketTagsDatasource()); api.set('cdnjs', new CdnJsDatasource()); api.set('clojure', new ClojureDatasource()); api.set('crate', crate); diff --git a/lib/datasource/bitbucket-tags/index.spec.ts b/lib/datasource/bitbucket-tags/index.spec.ts index 83290ddd9b..89487dd107 100644 --- a/lib/datasource/bitbucket-tags/index.spec.ts +++ b/lib/datasource/bitbucket-tags/index.spec.ts @@ -1,7 +1,9 @@ import { getDigest, getPkgReleases } from '..'; import * as httpMock from '../../../test/http-mock'; import { getName } from '../../../test/util'; -import { id as datasource } from '.'; +import { BitBucketTagsDatasource } from '.'; + +const datasource = BitBucketTagsDatasource.id; describe(getName(), () => { describe('getReleases', () => { diff --git a/lib/datasource/bitbucket-tags/index.ts b/lib/datasource/bitbucket-tags/index.ts index 3e06f3b4f0..33be94ef77 100644 --- a/lib/datasource/bitbucket-tags/index.ts +++ b/lib/datasource/bitbucket-tags/index.ts @@ -1,133 +1,130 @@ import * as utils from '../../platform/bitbucket/utils'; -import * as packageCache from '../../util/cache/package'; +import { cache } from '../../util/cache/package/decorator'; import { BitbucketHttp } from '../../util/http/bitbucket'; import { ensureTrailingSlash } from '../../util/url'; +import { Datasource } from '../datasource'; import type { DigestConfig, GetReleasesConfig, ReleaseResult } from '../types'; import { BitbucketCommit, BitbucketTag } from './types'; -const bitbucketHttp = new BitbucketHttp(); +export class BitBucketTagsDatasource extends Datasource { + bitbucketHttp = new BitbucketHttp(); -export const id = 'bitbucket-tags'; -export const customRegistrySupport = true; -export const registryStrategy = 'first'; -export const defaultRegistryUrls = ['https://bitbucket.org']; + static readonly id = 'bitbucket-tags'; -function getRegistryURL(registryUrl: string): string { - // fallback to default API endpoint if custom not provided - return registryUrl ?? defaultRegistryUrls[0]; -} - -const cacheNamespace = 'datasource-bitbucket'; + static readonly customRegistrySupport = true; -function getCacheKey(registryUrl: string, repo: string, type: string): string { - return `${getRegistryURL(registryUrl)}:${repo}:${type}`; -} + static readonly registryStrategy = 'first'; -// getReleases fetches list of tags for the repository -export async function getReleases({ - registryUrl, - lookupName: repo, -}: GetReleasesConfig): Promise<ReleaseResult | null> { - const cacheKey = getCacheKey(registryUrl, repo, 'tags'); - const cachedResult = await packageCache.get<ReleaseResult>( - cacheNamespace, - cacheKey - ); - // istanbul ignore if - if (cachedResult) { - return cachedResult; - } + static readonly defaultRegistryUrls = ['https://bitbucket.org']; - const url = `/2.0/repositories/${repo}/refs/tags`; - - const bitbucketTags = ( - await bitbucketHttp.getJson<utils.PagedResult<BitbucketTag>>(url) - ).body; - - const dependency: ReleaseResult = { - sourceUrl: `${ensureTrailingSlash(getRegistryURL(registryUrl))}${repo}`, - releases: null, - }; - dependency.releases = bitbucketTags.values.map(({ name, target }) => ({ - version: name, - gitRef: name, - releaseTimestamp: target?.date, - })); - - const cacheMinutes = 10; - await packageCache.set(cacheNamespace, cacheKey, dependency, cacheMinutes); - return dependency; -} + static readonly cacheNamespace = `datasource-${BitBucketTagsDatasource.id}`; -// getTagCommit fetched the commit has for specified tag -async function getTagCommit( - registryUrl: string, - repo: string, - tag: string -): Promise<string | null> { - const cacheKey = getCacheKey(registryUrl, repo, `tag-${tag}`); - const cachedResult = await packageCache.get<string>(cacheNamespace, cacheKey); - // istanbul ignore if - if (cachedResult) { - return cachedResult; + constructor() { + super(BitBucketTagsDatasource.id); } - const url = `/2.0/repositories/${repo}/refs/tags/${tag}`; - - const bitbucketTag = (await bitbucketHttp.getJson<BitbucketTag>(url)).body; - - const hash = bitbucketTag.target.hash; - - const cacheMinutes = 10; - await packageCache.set(cacheNamespace, cacheKey, hash, cacheMinutes); + static getRegistryURL(registryUrl: string): string { + // fallback to default API endpoint if custom not provided + return registryUrl ?? this.defaultRegistryUrls[0]; + } - return hash; -} + static getCacheKey(registryUrl: string, repo: string, type: string): string { + return `${BitBucketTagsDatasource.getRegistryURL( + registryUrl + )}:${repo}:${type}`; + } -// getDigest fetched the latest commit for repository main branch -// however, if newValue is provided, then getTagCommit is called -export async function getDigest( - { lookupName: repo, registryUrl }: DigestConfig, - newValue?: string -): Promise<string | null> { - if (newValue?.length) { - return getTagCommit(registryUrl, repo, newValue); + // getReleases fetches list of tags for the repository + @cache({ + namespace: BitBucketTagsDatasource.cacheNamespace, + key: ({ registryUrl, lookupName }: GetReleasesConfig) => + BitBucketTagsDatasource.getCacheKey(registryUrl, lookupName, 'tags'), + }) + async getReleases({ + registryUrl, + lookupName: repo, + }: GetReleasesConfig): Promise<ReleaseResult | null> { + const url = `/2.0/repositories/${repo}/refs/tags`; + + const bitbucketTags = ( + await this.bitbucketHttp.getJson<utils.PagedResult<BitbucketTag>>(url) + ).body; + + const dependency: ReleaseResult = { + sourceUrl: `${ensureTrailingSlash( + BitBucketTagsDatasource.getRegistryURL(registryUrl) + )}${repo}`, + registryUrl: BitBucketTagsDatasource.getRegistryURL(registryUrl), + releases: null, + }; + dependency.releases = bitbucketTags.values.map(({ name, target }) => ({ + version: name, + gitRef: name, + releaseTimestamp: target?.date, + })); + + return dependency; } - const cacheKey = getCacheKey(registryUrl, repo, 'digest'); - const cachedResult = await packageCache.get<string>(cacheNamespace, cacheKey); - // istanbul ignore if - if (cachedResult) { - return cachedResult; + // getTagCommit fetched the commit has for specified tag + @cache({ + namespace: BitBucketTagsDatasource.cacheNamespace, + key: (registryUrl, repo, tag: string) => + BitBucketTagsDatasource.getCacheKey(registryUrl, repo, `tag-${tag}`), + }) + async getTagCommit( + registryUrl: string, + repo: string, + tag: string + ): Promise<string | null> { + const url = `/2.0/repositories/${repo}/refs/tags/${tag}`; + + const bitbucketTag = (await this.bitbucketHttp.getJson<BitbucketTag>(url)) + .body; + + return bitbucketTag.target.hash; } - const branchCacheKey = getCacheKey(registryUrl, repo, 'mainbranch'); - let mainBranch = await packageCache.get<string>( - cacheNamespace, - branchCacheKey - ); - if (!mainBranch) { - mainBranch = ( - await bitbucketHttp.getJson<utils.RepoInfoBody>( + @cache({ + namespace: BitBucketTagsDatasource.cacheNamespace, + key: (registryUrl: string, repo: string) => + BitBucketTagsDatasource.getCacheKey(registryUrl, repo, 'mainbranch'), + ttlMinutes: 60, + }) + async getMainBranch(repo: string): Promise<string> { + return ( + await this.bitbucketHttp.getJson<utils.RepoInfoBody>( `/2.0/repositories/${repo}` ) ).body.mainbranch.name; - await packageCache.set(cacheNamespace, branchCacheKey, mainBranch, 60); } - const url = `/2.0/repositories/${repo}/commits/${mainBranch}`; - const bitbucketCommits = ( - await bitbucketHttp.getJson<utils.PagedResult<BitbucketCommit>>(url) - ).body; - - if (bitbucketCommits.values.length === 0) { - return null; + // getDigest fetched the latest commit for repository main branch + // however, if newValue is provided, then getTagCommit is called + @cache({ + namespace: BitBucketTagsDatasource.cacheNamespace, + key: ({ registryUrl, lookupName }: DigestConfig) => + BitBucketTagsDatasource.getCacheKey(registryUrl, lookupName, 'digest'), + }) + async getDigest( + { lookupName: repo, registryUrl }: DigestConfig, + newValue?: string + ): Promise<string | null> { + if (newValue?.length) { + return this.getTagCommit(registryUrl, repo, newValue); + } + + const mainBranch = await this.getMainBranch(repo); + + const url = `/2.0/repositories/${repo}/commits/${mainBranch}`; + const bitbucketCommits = ( + await this.bitbucketHttp.getJson<utils.PagedResult<BitbucketCommit>>(url) + ).body; + + if (bitbucketCommits.values.length === 0) { + return null; + } + + return bitbucketCommits.values[0].hash; } - - const latestCommit = bitbucketCommits.values[0].hash; - - const cacheMinutes = 10; - await packageCache.set(cacheNamespace, cacheKey, latestCommit, cacheMinutes); - - return latestCommit; } diff --git a/lib/datasource/go/__snapshots__/index.spec.ts.snap b/lib/datasource/go/__snapshots__/index.spec.ts.snap index 9d40fee4c3..6ea4039550 100644 --- a/lib/datasource/go/__snapshots__/index.spec.ts.snap +++ b/lib/datasource/go/__snapshots__/index.spec.ts.snap @@ -329,6 +329,7 @@ Array [ exports[`datasource/go/index getReleases support bitbucket tags 1`] = ` Object { + "registryUrl": "https://bitbucket.org", "releases": Array [ Object { "gitRef": "v1.0.0", diff --git a/lib/datasource/go/index.ts b/lib/datasource/go/index.ts index 781bd3db45..527473d89c 100644 --- a/lib/datasource/go/index.ts +++ b/lib/datasource/go/index.ts @@ -5,7 +5,7 @@ import * as hostRules from '../../util/host-rules'; import { Http } from '../../util/http'; import { regEx } from '../../util/regex'; import { trimTrailingSlash } from '../../util/url'; -import * as bitbucket from '../bitbucket-tags'; +import { BitBucketTagsDatasource } from '../bitbucket-tags'; import * as github from '../github-tags'; import * as gitlab from '../gitlab-tags'; import type { DigestConfig, GetReleasesConfig, ReleaseResult } from '../types'; @@ -16,6 +16,7 @@ export const customRegistrySupport = false; const http = new Http(id); const gitlabRegExp = /^(https:\/\/[^/]*gitlab.[^/]*)\/(.*)$/; +const bitbucket = new BitBucketTagsDatasource(); async function getDatasource(goModule: string): Promise<DataSource | null> { if (goModule.startsWith('gopkg.in/')) { -- GitLab