From bc8e06e1d074ae6d51761e510343277fa2b91a93 Mon Sep 17 00:00:00 2001 From: Sergei Zharinov <zharinov@users.noreply.github.com> Date: Fri, 16 Jun 2023 22:05:18 +0300 Subject: [PATCH] refactor(rubygems): Decouple metadata fetching from versions fetching (#22808) Co-authored-by: lluiscab <lluiscab@gmail.com> Co-authored-by: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com> Co-authored-by: Michael Kriese <michael.kriese@visualon.de> Co-authored-by: Rhys Arkins <rhys@arkins.net> Co-authored-by: t-kulmburg <89128736+t-kulmburg@users.noreply.github.com> Co-authored-by: Victor Engmark <victor@engmark.name> --- lib/modules/datasource/rubygems/index.ts | 92 +++++++++++++---------- lib/modules/datasource/rubygems/schema.ts | 6 +- 2 files changed, 54 insertions(+), 44 deletions(-) diff --git a/lib/modules/datasource/rubygems/index.ts b/lib/modules/datasource/rubygems/index.ts index 2e343608c0..fa39a49e91 100644 --- a/lib/modules/datasource/rubygems/index.ts +++ b/lib/modules/datasource/rubygems/index.ts @@ -6,7 +6,7 @@ import { getQueryString, joinUrlParts, parseUrl } from '../../../util/url'; import * as rubyVersioning from '../../versioning/ruby'; import { Datasource } from '../datasource'; import type { GetReleasesConfig, Release, ReleaseResult } from '../types'; -import { GemVersions, GemsInfo, MarshalledVersionInfo } from './schema'; +import { GemMetadata, GemVersions, MarshalledVersionInfo } from './schema'; import { VersionsEndpointCache } from './versions-endpoint-cache'; export class RubyGemsDatasource extends Datasource { @@ -57,39 +57,42 @@ export class RubyGemsDatasource extends Datasource { cachedVersions.type === 'not-supported' && registryHostname !== 'rubygems.org' ) { - const hostname = registryHostname; - return hostname === 'rubygems.pkg.github.com' || - hostname === 'gitlab.com' - ? await this.getDependencyFallback(registryUrl, packageName) - : await this.getDependency(registryUrl, packageName); + if ( + registryHostname === 'rubygems.pkg.github.com' || + registryHostname === 'gitlab.com' + ) { + return await this.getReleasesViaFallbackAPI(registryUrl, packageName); + } + + const gemMetadata = await this.fetchGemMetadata( + registryUrl, + packageName + ); + if (!gemMetadata) { + return await this.getReleasesViaFallbackAPI(registryUrl, packageName); + } + + return await this.getReleasesViaAPI( + registryUrl, + packageName, + gemMetadata + ); } + + return null; } catch (error) { this.handleGenericErrors(error); } - - return null; } - async getDependencyFallback( + async fetchGemMetadata( registryUrl: string, packageName: string - ): Promise<ReleaseResult | null> { - const path = joinUrlParts(registryUrl, `/api/v1/dependencies`); - const query = getQueryString({ gems: packageName }); - const url = `${path}?${query}`; - const { body: buffer } = await this.http.getBuffer(url); - const data = Marshal.parse(buffer); - return MarshalledVersionInfo.parse(data); - } - - async fetchGemsInfo( - registryUrl: string, - packageName: string - ): Promise<GemsInfo | null> { + ): Promise<GemMetadata | null> { try { const { body } = await this.http.getJson( joinUrlParts(registryUrl, '/api/v1/gems', `${packageName}.json`), - GemsInfo + GemMetadata ); return body; } catch (err) { @@ -124,41 +127,48 @@ export class RubyGemsDatasource extends Datasource { } } - async getDependency( + async getReleasesViaAPI( registryUrl: string, - packageName: string + packageName: string, + gemMetadata: GemMetadata ): Promise<ReleaseResult | null> { - const info = await this.fetchGemsInfo(registryUrl, packageName); - if (!info) { - return await this.getDependencyFallback(registryUrl, packageName); - } + const gemVersions = await this.fetchGemVersions(registryUrl, packageName); let releases: Release[] | null = null; - const gemVersions = await this.fetchGemVersions(registryUrl, packageName); if (gemVersions?.length) { releases = gemVersions; - } else if (info.version) { - releases = [{ version: info.version }]; - } - - if (!releases) { + } else if (gemMetadata.latestVersion) { + releases = [{ version: gemMetadata.latestVersion }]; + } else { return null; } const result: ReleaseResult = { releases }; - if (info.changelogUrl) { - result.changelogUrl = info.changelogUrl; + if (gemMetadata.changelogUrl) { + result.changelogUrl = gemMetadata.changelogUrl; } - if (info.homepage) { - result.homepage = info.homepage; + if (gemMetadata.homepage) { + result.homepage = gemMetadata.homepage; } - if (info.sourceUrl) { - result.sourceUrl = info.sourceUrl; + if (gemMetadata.sourceUrl) { + result.sourceUrl = gemMetadata.sourceUrl; } return result; } + + async getReleasesViaFallbackAPI( + registryUrl: string, + packageName: string + ): Promise<ReleaseResult | null> { + const path = joinUrlParts(registryUrl, `/api/v1/dependencies`); + const query = getQueryString({ gems: packageName }); + const url = `${path}?${query}`; + const { body: buffer } = await this.http.getBuffer(url); + const data = Marshal.parse(buffer); + return MarshalledVersionInfo.parse(data); + } } diff --git a/lib/modules/datasource/rubygems/schema.ts b/lib/modules/datasource/rubygems/schema.ts index 3931a40c0c..e0109f885c 100644 --- a/lib/modules/datasource/rubygems/schema.ts +++ b/lib/modules/datasource/rubygems/schema.ts @@ -14,7 +14,7 @@ export const MarshalledVersionInfo = LooseArray( .nullable() .catch(null); -export const GemsInfo = z +export const GemMetadata = z .object({ name: z.string().transform((x) => x.toLowerCase()), version: z.string().nullish().catch(null), @@ -31,13 +31,13 @@ export const GemsInfo = z source_code_uri: sourceUrl, }) => ({ packageName, - version, + latestVersion: version, changelogUrl, homepage, sourceUrl, }) ); -export type GemsInfo = z.infer<typeof GemsInfo>; +export type GemMetadata = z.infer<typeof GemMetadata>; export const GemVersions = LooseArray( z -- GitLab