renovate 43.59.2 → 43.59.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -105,7 +105,7 @@ var CrateDatasource = class CrateDatasource extends Datasource {
|
|
|
105
105
|
const registryConfig = await this.fetchRegistryConfig(info);
|
|
106
106
|
if (!registryConfig?.api) return null;
|
|
107
107
|
const crateUrl = `${joinUrlParts(registryConfig.api, "api/v1/")}crates/${packageName}?include=`;
|
|
108
|
-
logger.
|
|
108
|
+
logger.trace({
|
|
109
109
|
crateUrl,
|
|
110
110
|
packageName,
|
|
111
111
|
registryUrl: info.rawUrl
|
|
@@ -113,7 +113,7 @@ var CrateDatasource = class CrateDatasource extends Datasource {
|
|
|
113
113
|
try {
|
|
114
114
|
return (await this.http.getJsonUnchecked(crateUrl)).body.crate;
|
|
115
115
|
} catch (err) {
|
|
116
|
-
logger.
|
|
116
|
+
logger.debug({
|
|
117
117
|
err,
|
|
118
118
|
packageName,
|
|
119
119
|
registryUrl: info.rawUrl
|
|
@@ -133,6 +133,11 @@ var CrateDatasource = class CrateDatasource extends Datasource {
|
|
|
133
133
|
if (info.clonePath) return readCacheFile(upath.join(info.clonePath, ...CrateDatasource.getIndexSuffix(packageName)), "utf8");
|
|
134
134
|
const packageSuffix = CrateDatasource.getIndexSuffix(packageName.toLowerCase());
|
|
135
135
|
const crateUrl = joinUrlParts(info.rawUrl, ...packageSuffix);
|
|
136
|
+
logger.trace({
|
|
137
|
+
crateUrl,
|
|
138
|
+
packageName,
|
|
139
|
+
registryUrl: info.rawUrl
|
|
140
|
+
}, "fetching crate records from sparse index");
|
|
136
141
|
try {
|
|
137
142
|
return (await this.http.getText(crateUrl)).body;
|
|
138
143
|
} catch (err) {
|
|
@@ -297,6 +302,12 @@ var CrateDatasource = class CrateDatasource extends Datasource {
|
|
|
297
302
|
const config = get(cacheKey);
|
|
298
303
|
if (!config?.api) return release;
|
|
299
304
|
const url = `${joinUrlParts(config.api, "api/v1/")}crates/${packageName}/${release.versionOrig ?? release.version}`;
|
|
305
|
+
logger.trace({
|
|
306
|
+
url,
|
|
307
|
+
packageName,
|
|
308
|
+
version: release.version,
|
|
309
|
+
registryUrl
|
|
310
|
+
}, "fetching crate release timestamp");
|
|
300
311
|
const { body: releaseTimestamp } = await this.http.getJson(url, { cacheProvider: memCacheProvider }, ReleaseTimestamp);
|
|
301
312
|
release.releaseTimestamp = releaseTimestamp;
|
|
302
313
|
return release;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["cargoVersioning.id","memCache.get"],"sources":["../../../../lib/modules/datasource/crate/index.ts"],"sourcesContent":["import { simpleGit } from 'simple-git';\nimport upath from 'upath';\nimport { GlobalConfig } from '../../../config/global.ts';\nimport { logger } from '../../../logger/index.ts';\nimport * as memCache from '../../../util/cache/memory/index.ts';\nimport { withCache } from '../../../util/cache/package/with-cache.ts';\nimport { getChildEnv } from '../../../util/exec/utils.ts';\nimport { privateCacheDir, readCacheFile } from '../../../util/fs/index.ts';\nimport { simpleGitConfig } from '../../../util/git/config.ts';\nimport { toSha256 } from '../../../util/hash.ts';\nimport { memCacheProvider } from '../../../util/http/cache/memory-http-cache-provider.ts';\nimport { acquireLock } from '../../../util/mutex.ts';\nimport { newlineRegex, regEx } from '../../../util/regex.ts';\nimport { Json } from '../../../util/schema-utils/index.ts';\nimport { asTimestamp } from '../../../util/timestamp.ts';\nimport { joinUrlParts, parseUrl } from '../../../util/url.ts';\nimport * as cargoVersioning from '../../versioning/cargo/index.ts';\nimport { Datasource } from '../datasource.ts';\nimport type {\n GetReleasesConfig,\n PostprocessReleaseConfig,\n PostprocessReleaseResult,\n Release,\n ReleaseResult,\n} from '../types.ts';\nimport { RegistryConfigSchema, ReleaseTimestamp } from './schema.ts';\nimport type {\n CrateMetadata,\n CrateRecord,\n RegistryFlavor,\n RegistryInfo,\n} from './types.ts';\n\ntype CloneResult =\n | {\n err: Error;\n clonePath?: undefined;\n }\n | {\n clonePath: string;\n err?: undefined;\n };\n\nexport class CrateDatasource extends Datasource {\n static readonly id = 'crate';\n\n constructor() {\n super(CrateDatasource.id);\n }\n\n override defaultRegistryUrls = ['sparse+https://index.crates.io/'];\n\n override defaultVersioning = cargoVersioning.id;\n\n override readonly sourceUrlSupport = 'package';\n override readonly sourceUrlNote =\n 'The source URL is determined from the `repository` field in the results.';\n\n override readonly releaseTimestampSupport = true;\n override readonly releaseTimestampNote =\n 'The release timestamp is determined from `pubtime` field from crates.io index if available, or `version.created_at` field from crates.io API otherwise.';\n\n private async _getReleases({\n packageName,\n registryUrl,\n }: GetReleasesConfig): Promise<ReleaseResult | null> {\n /* v8 ignore if -- should never happen */\n if (!registryUrl) {\n logger.warn(\n 'crate datasource: No registryUrl specified, cannot perform getReleases',\n );\n return null;\n }\n\n const registryInfo = await CrateDatasource.fetchRegistryInfo({\n packageName,\n registryUrl,\n });\n if (!registryInfo) {\n logger.debug(`Could not fetch registry info from ${registryUrl}`);\n return null;\n }\n\n const dependencyUrl = CrateDatasource.getDependencyUrl(\n registryInfo,\n packageName,\n );\n\n const payload = await this.fetchCrateRecordsPayload(\n registryInfo,\n packageName,\n );\n const lines = payload\n .split(newlineRegex) // break into lines\n .map((line) => line.trim()) // remove whitespace\n .filter((line) => line.length !== 0) // remove empty lines\n .map((line) => JSON.parse(line) as CrateRecord); // parse\n\n const metadata = await this.getCrateMetadata(registryInfo, packageName);\n\n const result: ReleaseResult = {\n dependencyUrl,\n releases: [],\n };\n\n if (metadata?.homepage) {\n result.homepage = metadata.homepage;\n }\n\n if (metadata?.repository) {\n result.sourceUrl = metadata.repository;\n }\n\n result.releases = lines\n .map((line) => {\n const versionOrig = line.vers;\n const version = versionOrig.replace(/\\+.*$/, '');\n const release: Release = { version };\n\n if (versionOrig !== version) {\n release.versionOrig = versionOrig;\n }\n\n if (line.yanked) {\n release.isDeprecated = true;\n }\n\n if (line.rust_version) {\n release.constraints = { rust: [line.rust_version] };\n }\n\n if (line.pubtime) {\n release.releaseTimestamp = asTimestamp(line.pubtime);\n }\n\n return release;\n })\n .filter((release) => release.version);\n if (!result.releases.length) {\n return null;\n }\n\n return result;\n }\n\n getReleases(config: GetReleasesConfig): Promise<ReleaseResult | null> {\n return withCache(\n {\n namespace: `datasource-${CrateDatasource.id}`,\n // TODO: types (#22198)\n key: `${config.registryUrl}/${config.packageName}`,\n cacheable: CrateDatasource.isCratesIo(config.registryUrl),\n fallback: true,\n },\n () => this._getReleases(config),\n );\n }\n\n /**\n * Fetches the registry's config.json which provides the API base URL\n * and download URL template.\n * See: https://doc.rust-lang.org/cargo/reference/registry-index.html#index-configuration\n */\n private async fetchRegistryConfig(\n info: RegistryInfo,\n ): Promise<RegistryConfigSchema | null> {\n const cacheKey = `crate-datasource/registry-config/${info.rawUrl}`;\n const cached = memCache.get<RegistryConfigSchema>(cacheKey);\n if (cached) {\n return cached;\n }\n\n if (info.clonePath) {\n try {\n const configPath = upath.join(info.clonePath, 'config.json');\n const content = await readCacheFile(configPath, 'utf8');\n const parsed = Json.pipe(RegistryConfigSchema).parse(content);\n memCache.set(cacheKey, parsed);\n return parsed;\n } catch {\n logger.debug(\n { registryUrl: info.rawUrl },\n 'Could not read config.json from cloned registry',\n );\n }\n } else {\n try {\n const configUrl = joinUrlParts(info.rawUrl, 'config.json');\n const { body } = await this.http.getJson(\n configUrl,\n RegistryConfigSchema,\n );\n memCache.set(cacheKey, body);\n return body;\n } catch {\n logger.debug(\n { registryUrl: info.rawUrl },\n 'Could not fetch registry config.json',\n );\n }\n }\n\n return null;\n }\n\n private async _getCrateMetadata(\n info: RegistryInfo,\n packageName: string,\n ): Promise<CrateMetadata | null> {\n const registryConfig = await this.fetchRegistryConfig(info);\n if (!registryConfig?.api) {\n return null;\n }\n\n const apiBaseUrl = joinUrlParts(registryConfig.api, 'api/v1/');\n\n // The `?include=` suffix is required to avoid unnecessary database queries\n // on the crates.io server. This lets us work around the regular request\n // throttling of one request per second.\n const crateUrl = `${apiBaseUrl}crates/${packageName}?include=`;\n\n logger.debug(\n { crateUrl, packageName, registryUrl: info.rawUrl },\n 'downloading crate metadata',\n );\n\n try {\n interface Response {\n crate: CrateMetadata;\n }\n const response = await this.http.getJsonUnchecked<Response>(crateUrl);\n return response.body.crate;\n } catch (err) {\n logger.warn(\n { err, packageName, registryUrl: info.rawUrl },\n 'failed to download crate metadata',\n );\n }\n\n return null;\n }\n\n public getCrateMetadata(\n info: RegistryInfo,\n packageName: string,\n ): Promise<CrateMetadata | null> {\n return withCache(\n {\n namespace: `datasource-${CrateDatasource.id}-metadata`,\n key: `${info.rawUrl}/${packageName}`,\n cacheable: info.flavor === 'crates.io',\n ttlMinutes: 24 * 60, // 24 hours\n },\n () => this._getCrateMetadata(info, packageName),\n );\n }\n\n public async fetchCrateRecordsPayload(\n info: RegistryInfo,\n packageName: string,\n ): Promise<string> {\n if (info.clonePath) {\n const path = upath.join(\n info.clonePath,\n ...CrateDatasource.getIndexSuffix(packageName),\n );\n return readCacheFile(path, 'utf8');\n }\n\n // sparse index\n const packageSuffix = CrateDatasource.getIndexSuffix(\n packageName.toLowerCase(),\n );\n const crateUrl = joinUrlParts(info.rawUrl, ...packageSuffix);\n try {\n return (await this.http.getText(crateUrl)).body;\n } catch (err) {\n this.handleGenericErrors(err);\n }\n }\n\n /**\n * Computes the dependency URL for a crate, given\n * registry information\n */\n private static getDependencyUrl(\n info: RegistryInfo,\n packageName: string,\n ): string {\n switch (info.flavor) {\n case 'crates.io':\n return `https://crates.io/crates/${packageName}`;\n case 'cloudsmith': {\n // input: https://dl.cloudsmith.io/basic/$org/$repo/cargo/index.git\n const tokens = info.url.pathname.split('/');\n const org = tokens[2];\n const repo = tokens[3];\n return `https://cloudsmith.io/~${org}/repos/${repo}/packages/detail/cargo/${packageName}`;\n }\n default:\n return `${info.url}/${packageName}`;\n }\n }\n\n /**\n * Given a Git URL, computes a semi-human-readable name for a folder in which to\n * clone the repository.\n */\n private static cacheDirFromUrl(url: URL): string {\n const proto = url.protocol.replace(regEx(/:$/), '');\n const host = url.hostname;\n const hash = toSha256(url.pathname).substring(0, 7);\n\n return `crate-registry-${proto}-${host}-${hash}`;\n }\n\n private static isSparseRegistry(url: string): boolean {\n const parsed = parseUrl(url);\n if (!parsed) {\n return false;\n }\n return parsed.protocol.startsWith('sparse+');\n }\n\n /**\n * Fetches information about a registry, by url.\n * If no url is given, assumes crates.io.\n * If an url is given, assumes it's a valid Git repository\n * url and clones it to cache.\n */\n private static async fetchRegistryInfo({\n packageName,\n registryUrl,\n }: GetReleasesConfig): Promise<RegistryInfo | null> {\n /* v8 ignore next 3 -- should never happen */\n if (!registryUrl) {\n return null;\n }\n\n const isSparseRegistry = CrateDatasource.isSparseRegistry(registryUrl);\n const registryFetchUrl = isSparseRegistry\n ? registryUrl.replace(/^sparse\\+/, '')\n : registryUrl;\n\n const url = parseUrl(registryFetchUrl);\n if (!url) {\n logger.debug(`Could not parse registry URL ${registryFetchUrl}`);\n return null;\n }\n\n let flavor: RegistryFlavor;\n if (url.hostname === 'index.crates.io') {\n flavor = 'crates.io';\n } else if (url.hostname === 'dl.cloudsmith.io') {\n flavor = 'cloudsmith';\n } else {\n flavor = 'other';\n }\n\n const registry: RegistryInfo = {\n flavor,\n rawUrl: registryFetchUrl,\n url,\n };\n\n if (\n registry.flavor !== 'crates.io' &&\n !GlobalConfig.get('allowCustomCrateRegistries')\n ) {\n logger.warn(\n 'crate datasource: allowCustomCrateRegistries=true is required for registries other than crates.io, bailing out',\n );\n return null;\n }\n if (!isSparseRegistry) {\n const cacheKey = `crate-datasource/registry-clone-path/${registryFetchUrl}`;\n const lockKey = registryFetchUrl;\n\n const executionTimeout =\n GlobalConfig.get('executionTimeout', 15) * 60 * 1000;\n const gitTimeout = GlobalConfig.get('gitTimeout', executionTimeout);\n const releaseLock = await acquireLock(\n lockKey,\n 'crate-registry',\n gitTimeout,\n );\n try {\n const cached = memCache.get<CloneResult>(cacheKey);\n\n if (cached?.err) {\n logger.warn(\n { err: cached.err, packageName, registryFetchUrl },\n 'Previous git clone failed, bailing out.',\n );\n return null;\n }\n\n if (cached?.clonePath) {\n registry.clonePath = cached.clonePath;\n return registry;\n }\n\n const clonePath = upath.join(\n privateCacheDir(),\n CrateDatasource.cacheDirFromUrl(url),\n );\n\n const result = await CrateDatasource.clone(\n registryFetchUrl,\n clonePath,\n packageName,\n );\n\n memCache.set(cacheKey, result);\n\n if (result.err) {\n logger.warn(\n { err: result.err, packageName, registryFetchUrl },\n 'Git clone failed, bailing out.',\n );\n return null;\n }\n\n registry.clonePath = result.clonePath;\n } finally {\n releaseLock();\n }\n }\n\n return registry;\n }\n\n private static async clone(\n registryFetchUrl: string,\n clonePath: string,\n packageName: string,\n ): Promise<CloneResult> {\n logger.info(\n { clonePath, registryFetchUrl },\n `Cloning private cargo registry`,\n );\n\n const git = simpleGit({\n ...simpleGitConfig(),\n maxConcurrentProcesses: 1,\n }).env(getChildEnv());\n\n try {\n await git.clone(registryFetchUrl, clonePath, {\n '--depth': 1,\n });\n return { clonePath };\n } catch (err) {\n if (\n err.message.includes(\n 'fatal: dumb http transport does not support shallow capabilities',\n )\n ) {\n logger.info(\n { packageName, registryFetchUrl },\n 'failed to shallow clone git registry, doing full clone',\n );\n try {\n await git.clone(registryFetchUrl, clonePath);\n return { clonePath };\n } catch (err) {\n logger.warn(\n { err, packageName, registryFetchUrl },\n 'failed cloning git registry',\n );\n return { err };\n }\n } else {\n logger.warn(\n { err, packageName, registryFetchUrl },\n 'failed cloning git registry',\n );\n return { err };\n }\n }\n }\n\n private static isCratesIo(registryUrl: string | undefined): boolean {\n if (!registryUrl) {\n return false;\n }\n const normalized = registryUrl.replace(regEx(/^sparse\\+/), '');\n const parsed = parseUrl(normalized);\n return parsed?.hostname === 'index.crates.io';\n }\n\n public static getIndexSuffix(packageName: string): string[] {\n const len = packageName.length;\n\n if (len === 1) {\n return ['1', packageName];\n }\n if (len === 2) {\n return ['2', packageName];\n }\n if (len === 3) {\n return ['3', packageName[0], packageName];\n }\n\n return [packageName.slice(0, 2), packageName.slice(2, 4), packageName];\n }\n\n private async _postprocessRelease(\n { packageName, registryUrl }: PostprocessReleaseConfig,\n release: Release,\n ): Promise<PostprocessReleaseResult> {\n if (release.releaseTimestamp) {\n return release;\n }\n\n // Look up the registry config from cache (populated during getReleases)\n const rawUrl = registryUrl?.replace(/^sparse\\+/, '');\n if (!rawUrl) {\n return release;\n }\n const cacheKey = `crate-datasource/registry-config/${rawUrl}`;\n const config = memCache.get<{ dl: string; api?: string }>(cacheKey);\n if (!config?.api) {\n return release;\n }\n\n const apiBaseUrl = joinUrlParts(config.api, 'api/v1/');\n const url = `${apiBaseUrl}crates/${packageName}/${release.versionOrig ?? release.version}`;\n // Getting release timestamp could become unnecessary if the manual backfill of `pubtime` mentioned in\n // https://github.com/rust-lang/cargo/issues/15491 is done for all packages.\n const { body: releaseTimestamp } = await this.http.getJson(\n url,\n { cacheProvider: memCacheProvider },\n ReleaseTimestamp,\n );\n release.releaseTimestamp = releaseTimestamp;\n return release;\n }\n\n override postprocessRelease(\n config: PostprocessReleaseConfig,\n release: Release,\n ): Promise<PostprocessReleaseResult> {\n return withCache(\n {\n namespace: `datasource-crate`,\n key: `postprocessRelease:${config.registryUrl}:${config.packageName}:${release.version}`,\n ttlMinutes: 7 * 24 * 60,\n cacheable: CrateDatasource.isCratesIo(config.registryUrl ?? undefined),\n },\n () => this._postprocessRelease(config, release),\n );\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["cargoVersioning.id","memCache.get"],"sources":["../../../../lib/modules/datasource/crate/index.ts"],"sourcesContent":["import { simpleGit } from 'simple-git';\nimport upath from 'upath';\nimport { GlobalConfig } from '../../../config/global.ts';\nimport { logger } from '../../../logger/index.ts';\nimport * as memCache from '../../../util/cache/memory/index.ts';\nimport { withCache } from '../../../util/cache/package/with-cache.ts';\nimport { getChildEnv } from '../../../util/exec/utils.ts';\nimport { privateCacheDir, readCacheFile } from '../../../util/fs/index.ts';\nimport { simpleGitConfig } from '../../../util/git/config.ts';\nimport { toSha256 } from '../../../util/hash.ts';\nimport { memCacheProvider } from '../../../util/http/cache/memory-http-cache-provider.ts';\nimport { acquireLock } from '../../../util/mutex.ts';\nimport { newlineRegex, regEx } from '../../../util/regex.ts';\nimport { Json } from '../../../util/schema-utils/index.ts';\nimport { asTimestamp } from '../../../util/timestamp.ts';\nimport { joinUrlParts, parseUrl } from '../../../util/url.ts';\nimport * as cargoVersioning from '../../versioning/cargo/index.ts';\nimport { Datasource } from '../datasource.ts';\nimport type {\n GetReleasesConfig,\n PostprocessReleaseConfig,\n PostprocessReleaseResult,\n Release,\n ReleaseResult,\n} from '../types.ts';\nimport { RegistryConfigSchema, ReleaseTimestamp } from './schema.ts';\nimport type {\n CrateMetadata,\n CrateRecord,\n RegistryFlavor,\n RegistryInfo,\n} from './types.ts';\n\ntype CloneResult =\n | {\n err: Error;\n clonePath?: undefined;\n }\n | {\n clonePath: string;\n err?: undefined;\n };\n\nexport class CrateDatasource extends Datasource {\n static readonly id = 'crate';\n\n constructor() {\n super(CrateDatasource.id);\n }\n\n override defaultRegistryUrls = ['sparse+https://index.crates.io/'];\n\n override defaultVersioning = cargoVersioning.id;\n\n override readonly sourceUrlSupport = 'package';\n override readonly sourceUrlNote =\n 'The source URL is determined from the `repository` field in the results.';\n\n override readonly releaseTimestampSupport = true;\n override readonly releaseTimestampNote =\n 'The release timestamp is determined from `pubtime` field from crates.io index if available, or `version.created_at` field from crates.io API otherwise.';\n\n private async _getReleases({\n packageName,\n registryUrl,\n }: GetReleasesConfig): Promise<ReleaseResult | null> {\n /* v8 ignore if -- should never happen */\n if (!registryUrl) {\n logger.warn(\n 'crate datasource: No registryUrl specified, cannot perform getReleases',\n );\n return null;\n }\n\n const registryInfo = await CrateDatasource.fetchRegistryInfo({\n packageName,\n registryUrl,\n });\n if (!registryInfo) {\n logger.debug(`Could not fetch registry info from ${registryUrl}`);\n return null;\n }\n\n const dependencyUrl = CrateDatasource.getDependencyUrl(\n registryInfo,\n packageName,\n );\n\n const payload = await this.fetchCrateRecordsPayload(\n registryInfo,\n packageName,\n );\n const lines = payload\n .split(newlineRegex) // break into lines\n .map((line) => line.trim()) // remove whitespace\n .filter((line) => line.length !== 0) // remove empty lines\n .map((line) => JSON.parse(line) as CrateRecord); // parse\n\n const metadata = await this.getCrateMetadata(registryInfo, packageName);\n\n const result: ReleaseResult = {\n dependencyUrl,\n releases: [],\n };\n\n if (metadata?.homepage) {\n result.homepage = metadata.homepage;\n }\n\n if (metadata?.repository) {\n result.sourceUrl = metadata.repository;\n }\n\n result.releases = lines\n .map((line) => {\n const versionOrig = line.vers;\n const version = versionOrig.replace(/\\+.*$/, '');\n const release: Release = { version };\n\n if (versionOrig !== version) {\n release.versionOrig = versionOrig;\n }\n\n if (line.yanked) {\n release.isDeprecated = true;\n }\n\n if (line.rust_version) {\n release.constraints = { rust: [line.rust_version] };\n }\n\n if (line.pubtime) {\n release.releaseTimestamp = asTimestamp(line.pubtime);\n }\n\n return release;\n })\n .filter((release) => release.version);\n if (!result.releases.length) {\n return null;\n }\n\n return result;\n }\n\n getReleases(config: GetReleasesConfig): Promise<ReleaseResult | null> {\n return withCache(\n {\n namespace: `datasource-${CrateDatasource.id}`,\n // TODO: types (#22198)\n key: `${config.registryUrl}/${config.packageName}`,\n cacheable: CrateDatasource.isCratesIo(config.registryUrl),\n fallback: true,\n },\n () => this._getReleases(config),\n );\n }\n\n /**\n * Fetches the registry's config.json which provides the API base URL\n * and download URL template.\n * See: https://doc.rust-lang.org/cargo/reference/registry-index.html#index-configuration\n */\n private async fetchRegistryConfig(\n info: RegistryInfo,\n ): Promise<RegistryConfigSchema | null> {\n const cacheKey = `crate-datasource/registry-config/${info.rawUrl}`;\n const cached = memCache.get<RegistryConfigSchema>(cacheKey);\n if (cached) {\n return cached;\n }\n\n if (info.clonePath) {\n try {\n const configPath = upath.join(info.clonePath, 'config.json');\n const content = await readCacheFile(configPath, 'utf8');\n const parsed = Json.pipe(RegistryConfigSchema).parse(content);\n memCache.set(cacheKey, parsed);\n return parsed;\n } catch {\n logger.debug(\n { registryUrl: info.rawUrl },\n 'Could not read config.json from cloned registry',\n );\n }\n } else {\n try {\n const configUrl = joinUrlParts(info.rawUrl, 'config.json');\n const { body } = await this.http.getJson(\n configUrl,\n RegistryConfigSchema,\n );\n memCache.set(cacheKey, body);\n return body;\n } catch {\n logger.debug(\n { registryUrl: info.rawUrl },\n 'Could not fetch registry config.json',\n );\n }\n }\n\n return null;\n }\n\n private async _getCrateMetadata(\n info: RegistryInfo,\n packageName: string,\n ): Promise<CrateMetadata | null> {\n const registryConfig = await this.fetchRegistryConfig(info);\n if (!registryConfig?.api) {\n return null;\n }\n\n const apiBaseUrl = joinUrlParts(registryConfig.api, 'api/v1/');\n\n // The `?include=` suffix is required to avoid unnecessary database queries\n // on the crates.io server. This lets us work around the regular request\n // throttling of one request per second.\n const crateUrl = `${apiBaseUrl}crates/${packageName}?include=`;\n\n logger.trace(\n { crateUrl, packageName, registryUrl: info.rawUrl },\n 'downloading crate metadata',\n );\n\n try {\n interface Response {\n crate: CrateMetadata;\n }\n const response = await this.http.getJsonUnchecked<Response>(crateUrl);\n return response.body.crate;\n } catch (err) {\n logger.debug(\n { err, packageName, registryUrl: info.rawUrl },\n 'failed to download crate metadata',\n );\n }\n\n return null;\n }\n\n public getCrateMetadata(\n info: RegistryInfo,\n packageName: string,\n ): Promise<CrateMetadata | null> {\n return withCache(\n {\n namespace: `datasource-${CrateDatasource.id}-metadata`,\n key: `${info.rawUrl}/${packageName}`,\n cacheable: info.flavor === 'crates.io',\n ttlMinutes: 24 * 60, // 24 hours\n },\n () => this._getCrateMetadata(info, packageName),\n );\n }\n\n public async fetchCrateRecordsPayload(\n info: RegistryInfo,\n packageName: string,\n ): Promise<string> {\n if (info.clonePath) {\n const path = upath.join(\n info.clonePath,\n ...CrateDatasource.getIndexSuffix(packageName),\n );\n return readCacheFile(path, 'utf8');\n }\n\n // sparse index\n const packageSuffix = CrateDatasource.getIndexSuffix(\n packageName.toLowerCase(),\n );\n const crateUrl = joinUrlParts(info.rawUrl, ...packageSuffix);\n logger.trace(\n { crateUrl, packageName, registryUrl: info.rawUrl },\n 'fetching crate records from sparse index',\n );\n try {\n return (await this.http.getText(crateUrl)).body;\n } catch (err) {\n this.handleGenericErrors(err);\n }\n }\n\n /**\n * Computes the dependency URL for a crate, given\n * registry information\n */\n private static getDependencyUrl(\n info: RegistryInfo,\n packageName: string,\n ): string {\n switch (info.flavor) {\n case 'crates.io':\n return `https://crates.io/crates/${packageName}`;\n case 'cloudsmith': {\n // input: https://dl.cloudsmith.io/basic/$org/$repo/cargo/index.git\n const tokens = info.url.pathname.split('/');\n const org = tokens[2];\n const repo = tokens[3];\n return `https://cloudsmith.io/~${org}/repos/${repo}/packages/detail/cargo/${packageName}`;\n }\n default:\n return `${info.url}/${packageName}`;\n }\n }\n\n /**\n * Given a Git URL, computes a semi-human-readable name for a folder in which to\n * clone the repository.\n */\n private static cacheDirFromUrl(url: URL): string {\n const proto = url.protocol.replace(regEx(/:$/), '');\n const host = url.hostname;\n const hash = toSha256(url.pathname).substring(0, 7);\n\n return `crate-registry-${proto}-${host}-${hash}`;\n }\n\n private static isSparseRegistry(url: string): boolean {\n const parsed = parseUrl(url);\n if (!parsed) {\n return false;\n }\n return parsed.protocol.startsWith('sparse+');\n }\n\n /**\n * Fetches information about a registry, by url.\n * If no url is given, assumes crates.io.\n * If an url is given, assumes it's a valid Git repository\n * url and clones it to cache.\n */\n private static async fetchRegistryInfo({\n packageName,\n registryUrl,\n }: GetReleasesConfig): Promise<RegistryInfo | null> {\n /* v8 ignore next 3 -- should never happen */\n if (!registryUrl) {\n return null;\n }\n\n const isSparseRegistry = CrateDatasource.isSparseRegistry(registryUrl);\n const registryFetchUrl = isSparseRegistry\n ? registryUrl.replace(/^sparse\\+/, '')\n : registryUrl;\n\n const url = parseUrl(registryFetchUrl);\n if (!url) {\n logger.debug(`Could not parse registry URL ${registryFetchUrl}`);\n return null;\n }\n\n let flavor: RegistryFlavor;\n if (url.hostname === 'index.crates.io') {\n flavor = 'crates.io';\n } else if (url.hostname === 'dl.cloudsmith.io') {\n flavor = 'cloudsmith';\n } else {\n flavor = 'other';\n }\n\n const registry: RegistryInfo = {\n flavor,\n rawUrl: registryFetchUrl,\n url,\n };\n\n if (\n registry.flavor !== 'crates.io' &&\n !GlobalConfig.get('allowCustomCrateRegistries')\n ) {\n logger.warn(\n 'crate datasource: allowCustomCrateRegistries=true is required for registries other than crates.io, bailing out',\n );\n return null;\n }\n if (!isSparseRegistry) {\n const cacheKey = `crate-datasource/registry-clone-path/${registryFetchUrl}`;\n const lockKey = registryFetchUrl;\n\n const executionTimeout =\n GlobalConfig.get('executionTimeout', 15) * 60 * 1000;\n const gitTimeout = GlobalConfig.get('gitTimeout', executionTimeout);\n const releaseLock = await acquireLock(\n lockKey,\n 'crate-registry',\n gitTimeout,\n );\n try {\n const cached = memCache.get<CloneResult>(cacheKey);\n\n if (cached?.err) {\n logger.warn(\n { err: cached.err, packageName, registryFetchUrl },\n 'Previous git clone failed, bailing out.',\n );\n return null;\n }\n\n if (cached?.clonePath) {\n registry.clonePath = cached.clonePath;\n return registry;\n }\n\n const clonePath = upath.join(\n privateCacheDir(),\n CrateDatasource.cacheDirFromUrl(url),\n );\n\n const result = await CrateDatasource.clone(\n registryFetchUrl,\n clonePath,\n packageName,\n );\n\n memCache.set(cacheKey, result);\n\n if (result.err) {\n logger.warn(\n { err: result.err, packageName, registryFetchUrl },\n 'Git clone failed, bailing out.',\n );\n return null;\n }\n\n registry.clonePath = result.clonePath;\n } finally {\n releaseLock();\n }\n }\n\n return registry;\n }\n\n private static async clone(\n registryFetchUrl: string,\n clonePath: string,\n packageName: string,\n ): Promise<CloneResult> {\n logger.info(\n { clonePath, registryFetchUrl },\n `Cloning private cargo registry`,\n );\n\n const git = simpleGit({\n ...simpleGitConfig(),\n maxConcurrentProcesses: 1,\n }).env(getChildEnv());\n\n try {\n await git.clone(registryFetchUrl, clonePath, {\n '--depth': 1,\n });\n return { clonePath };\n } catch (err) {\n if (\n err.message.includes(\n 'fatal: dumb http transport does not support shallow capabilities',\n )\n ) {\n logger.info(\n { packageName, registryFetchUrl },\n 'failed to shallow clone git registry, doing full clone',\n );\n try {\n await git.clone(registryFetchUrl, clonePath);\n return { clonePath };\n } catch (err) {\n logger.warn(\n { err, packageName, registryFetchUrl },\n 'failed cloning git registry',\n );\n return { err };\n }\n } else {\n logger.warn(\n { err, packageName, registryFetchUrl },\n 'failed cloning git registry',\n );\n return { err };\n }\n }\n }\n\n private static isCratesIo(registryUrl: string | undefined): boolean {\n if (!registryUrl) {\n return false;\n }\n const normalized = registryUrl.replace(regEx(/^sparse\\+/), '');\n const parsed = parseUrl(normalized);\n return parsed?.hostname === 'index.crates.io';\n }\n\n public static getIndexSuffix(packageName: string): string[] {\n const len = packageName.length;\n\n if (len === 1) {\n return ['1', packageName];\n }\n if (len === 2) {\n return ['2', packageName];\n }\n if (len === 3) {\n return ['3', packageName[0], packageName];\n }\n\n return [packageName.slice(0, 2), packageName.slice(2, 4), packageName];\n }\n\n private async _postprocessRelease(\n { packageName, registryUrl }: PostprocessReleaseConfig,\n release: Release,\n ): Promise<PostprocessReleaseResult> {\n if (release.releaseTimestamp) {\n return release;\n }\n\n // Look up the registry config from cache (populated during getReleases)\n const rawUrl = registryUrl?.replace(/^sparse\\+/, '');\n if (!rawUrl) {\n return release;\n }\n const cacheKey = `crate-datasource/registry-config/${rawUrl}`;\n const config = memCache.get<{ dl: string; api?: string }>(cacheKey);\n if (!config?.api) {\n return release;\n }\n\n const apiBaseUrl = joinUrlParts(config.api, 'api/v1/');\n const url = `${apiBaseUrl}crates/${packageName}/${release.versionOrig ?? release.version}`;\n logger.trace(\n { url, packageName, version: release.version, registryUrl },\n 'fetching crate release timestamp',\n );\n // Getting release timestamp could become unnecessary if the manual backfill of `pubtime` mentioned in\n // https://github.com/rust-lang/cargo/issues/15491 is done for all packages.\n const { body: releaseTimestamp } = await this.http.getJson(\n url,\n { cacheProvider: memCacheProvider },\n ReleaseTimestamp,\n );\n release.releaseTimestamp = releaseTimestamp;\n return release;\n }\n\n override postprocessRelease(\n config: PostprocessReleaseConfig,\n release: Release,\n ): Promise<PostprocessReleaseResult> {\n return withCache(\n {\n namespace: `datasource-crate`,\n key: `postprocessRelease:${config.registryUrl}:${config.packageName}:${release.version}`,\n ttlMinutes: 7 * 24 * 60,\n cacheable: CrateDatasource.isCratesIo(config.registryUrl ?? undefined),\n },\n () => this._postprocessRelease(config, release),\n );\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "renovate",
|
|
3
3
|
"description": "Automated dependency updates. Flexible so you don't need to be.",
|
|
4
|
-
"version": "43.59.
|
|
4
|
+
"version": "43.59.4",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"renovate": "dist/renovate.js",
|
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
"dequal": "2.0.3",
|
|
147
147
|
"detect-indent": "7.0.2",
|
|
148
148
|
"diff": "8.0.3",
|
|
149
|
-
"editorconfig": "3.0.
|
|
149
|
+
"editorconfig": "3.0.2",
|
|
150
150
|
"email-addresses": "5.0.0",
|
|
151
151
|
"emoji-regex": "10.6.0",
|
|
152
152
|
"emojibase": "17.0.0",
|
|
@@ -192,7 +192,7 @@
|
|
|
192
192
|
"remark-gfm": "4.0.1",
|
|
193
193
|
"remark-github": "12.0.0",
|
|
194
194
|
"safe-stable-stringify": "2.5.0",
|
|
195
|
-
"sax": "1.
|
|
195
|
+
"sax": "1.5.0",
|
|
196
196
|
"semver": "7.7.4",
|
|
197
197
|
"semver-stable": "3.0.0",
|
|
198
198
|
"semver-utils": "1.1.4",
|
|
@@ -253,7 +253,7 @@
|
|
|
253
253
|
"@types/mdast": "4.0.4",
|
|
254
254
|
"@types/moo": "0.5.10",
|
|
255
255
|
"@types/ms": "2.1.0",
|
|
256
|
-
"@types/node": "24.
|
|
256
|
+
"@types/node": "24.11.0",
|
|
257
257
|
"@types/parse-link-header": "2.0.3",
|
|
258
258
|
"@types/punycode": "2.1.4",
|
|
259
259
|
"@types/sax": "1.2.7",
|
|
@@ -268,7 +268,7 @@
|
|
|
268
268
|
"aws-sdk-client-mock": "4.1.0",
|
|
269
269
|
"callsite": "1.0.0",
|
|
270
270
|
"common-tags": "1.8.2",
|
|
271
|
-
"conventional-changelog-conventionalcommits": "9.
|
|
271
|
+
"conventional-changelog-conventionalcommits": "9.2.0",
|
|
272
272
|
"emojibase-data": "17.0.0",
|
|
273
273
|
"esbuild": "0.27.3",
|
|
274
274
|
"eslint": "9.39.3",
|
|
@@ -279,11 +279,11 @@
|
|
|
279
279
|
"eslint-plugin-oxlint": "1.50.0",
|
|
280
280
|
"eslint-plugin-promise": "7.2.1",
|
|
281
281
|
"expect-more-jest": "5.5.0",
|
|
282
|
-
"globals": "17.
|
|
282
|
+
"globals": "17.4.0",
|
|
283
283
|
"graphql": "16.13.0",
|
|
284
284
|
"husky": "9.1.7",
|
|
285
285
|
"jest-extended": "7.0.0",
|
|
286
|
-
"lint-staged": "16.
|
|
286
|
+
"lint-staged": "16.3.1",
|
|
287
287
|
"markdownlint-cli2": "0.21.0",
|
|
288
288
|
"markdownlint-cli2-formatter-template": "0.0.4",
|
|
289
289
|
"memfs": "4.56.10",
|
package/renovate-schema.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"title": "JSON schema for Renovate 43.59.
|
|
2
|
+
"title": "JSON schema for Renovate 43.59.4 config files (https://renovatebot.com/)",
|
|
3
3
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
4
|
-
"x-renovate-version": "43.59.
|
|
4
|
+
"x-renovate-version": "43.59.4",
|
|
5
5
|
"allowComments": true,
|
|
6
6
|
"type": "object",
|
|
7
7
|
"properties": {
|