diff --git a/lib/.eslintrc.js b/lib/.eslintrc.js index 32892a5a2dacddc45a48162d78eaaf202a51ffa0..a860325aae1515989373538a8d5832450d1ec35f 100644 --- a/lib/.eslintrc.js +++ b/lib/.eslintrc.js @@ -2,5 +2,6 @@ module.exports = { globals: { logger: true, platform: true, + renovateCache: true, }, }; diff --git a/lib/datasource/github.js b/lib/datasource/github.js index 287109edac3001cf143c9fb89f6af3ee845d0222..3344ed68e6454a79d7d99c3c6bdafbc8d636b3e7 100644 --- a/lib/datasource/github.js +++ b/lib/datasource/github.js @@ -1,55 +1,11 @@ -const cacache = require('cacache/en'); -const os = require('os'); -const { DateTime } = require('luxon'); - const ghGot = require('../platform/github/gh-got-wrapper'); const versioning = require('../versioning'); module.exports = { getPreset, getPkgReleases, - rmAllCache, }; -const datasourceCache = - (process.env.RENOVATE_TMPDIR || os.tmpdir()) + - '/renovate-gh-datasource-cache-v1'; - -async function getCachedResult(repo, type) { - try { - const cacheVal = await cacache.get(datasourceCache, `${repo}-${type}`); - const cachedResult = JSON.parse(cacheVal.data.toString()); - if (cachedResult) { - if (DateTime.local() < DateTime.fromISO(cachedResult.expiry)) { - logger.debug( - { repo, type }, - 'Returning cached github datasource result' - ); - delete cachedResult.expiry; - return cachedResult; - } - // istanbul ignore next - logger.debug('Cache expiry'); - } - } catch (err) { - logger.debug('Cache miss'); - } - return null; -} - -async function setCachedResult(repo, type, res) { - logger.debug({ repo, type }, 'Saving cached github datasource'); - await cacache.put( - datasourceCache, - `${repo}-${type}`, - JSON.stringify({ ...res, expiry: DateTime.local().plus({ minutes: 10 }) }) - ); -} - -async function rmAllCache() { - await cacache.rm.all(datasourceCache); -} - const map = new Map(); async function getPreset(pkgName, presetName = 'default') { @@ -75,11 +31,20 @@ async function getPreset(pkgName, presetName = 'default') { } } +const cacheNamespace = 'datasource-github'; +function getCacheKey(repo, type) { + return `${repo}:${type}`; +} + async function getPkgReleases(purl, config) { const { versionScheme } = config || {}; const { fullname: repo, qualifiers: options } = purl; + options.ref = options.ref || 'tags'; let versions; - const cachedResult = await getCachedResult(repo, options.ref); + const cachedResult = await renovateCache.get( + cacheNamespace, + getCacheKey(repo, options.ref) + ); if (cachedResult) { return cachedResult; } @@ -117,6 +82,12 @@ async function getPkgReleases(purl, config) { version: options.sanitize === 'true' ? isVersion(version) : version, gitRef: version, })); - setCachedResult(repo, options.ref, dependency); + const cacheMinutes = 10; + await renovateCache.set( + cacheNamespace, + getCacheKey(repo, options.ref), + dependency, + cacheMinutes + ); return dependency; } diff --git a/lib/workers/global/cache.js b/lib/workers/global/cache.js new file mode 100644 index 0000000000000000000000000000000000000000..ed85a3b92d0048718377893ef4eaf3324fbd1cda --- /dev/null +++ b/lib/workers/global/cache.js @@ -0,0 +1,58 @@ +const cacache = require('cacache/en'); +const os = require('os'); +const { DateTime } = require('luxon'); + +module.exports = { + init, +}; + +function getKey(namespace, key) { + return `${namespace}-${key}`; +} + +const renovateCache = + (process.env.RENOVATE_TMPDIR || os.tmpdir()) + '/renovate-cache-v1'; + +async function get(namespace, key) { + try { + const res = await cacache.get(renovateCache, getKey(namespace, key)); + const cachedValue = JSON.parse(res.data.toString()); + if (cachedValue) { + if (DateTime.local() < DateTime.fromISO(cachedValue.expiry)) { + logger.debug({ namespace, key }, 'Returning cached value'); + return cachedValue.value; + } + // istanbul ignore next + await rm(namespace, key); + } + } catch (err) { + logger.debug({ namespace, key }, 'Cache miss'); + } + return null; +} + +async function set(namespace, key, value, ttlMinutes) { + logger.debug({ namespace, key }, 'Saving cached value'); + await cacache.put( + renovateCache, + getKey(namespace, key), + JSON.stringify({ + value, + expiry: DateTime.local().plus({ minutes: ttlMinutes }), + }) + ); +} + +// istanbul ignore next +async function rm(namespace, key) { + logger.debug({ namespace, key }, 'Removing cache entry'); + await cacache.rm.entry(renovateCache, getKey(namespace, key)); +} + +async function rmAll() { + await cacache.rm.all(renovateCache); +} + +function init() { + global.renovateCache = global.renovateCache || { get, set, rm, rmAll }; +} diff --git a/lib/workers/global/index.js b/lib/workers/global/index.js index 668377fc128a6cbb738d6858551a35cc78af94a6..84e3e7710cde37a21e54406740ff8a5f626e03f8 100644 --- a/lib/workers/global/index.js +++ b/lib/workers/global/index.js @@ -2,6 +2,7 @@ const is = require('@sindresorhus/is'); const { initLogger } = require('../../logger'); const configParser = require('../../config'); const repositoryWorker = require('../repository'); +const cache = require('./cache'); module.exports = { start, @@ -10,6 +11,7 @@ module.exports = { async function start() { initLogger(); + cache.init(); try { const config = await configParser.parseConfigs(process.env, process.argv); delete process.env.GITHUB_TOKEN; diff --git a/lib/workers/pr/changelog/index.js b/lib/workers/pr/changelog/index.js index 11a6953ef6a5263e7cd5563a81464f2ae2bb4c0f..7e706505c346cbc0fca8ed30c8c4806f27274edc 100644 --- a/lib/workers/pr/changelog/index.js +++ b/lib/workers/pr/changelog/index.js @@ -1,13 +1,25 @@ const versioning = require('../../../versioning'); const { addReleaseNotes } = require('../release-notes'); -const sourceCache = require('./source-cache'); const sourceGithub = require('./source-github'); module.exports = { getChangeLogJSON, }; +const cacheNamespace = 'changelog'; +function getCacheKey({ + versionScheme, + fromVersion, + toVersion, + repositoryUrl, + releases, +}) { + return `${repositoryUrl}-${versionScheme}-${fromVersion}-${toVersion}-${ + releases ? releases.map(release => release.version).join('-') : '' + }`; +} + async function getChangeLogJSON(args) { const { repositoryUrl, versionScheme, fromVersion, toVersion } = args; if (!repositoryUrl) { @@ -20,16 +32,24 @@ async function getChangeLogJSON(args) { if (!fromVersion || equals(fromVersion, toVersion)) { return null; } - const cachedResult = await sourceCache.getChangeLogJSON(args); + const cachedResult = await renovateCache.get( + cacheNamespace, + getCacheKey(args) + ); if (cachedResult) { - logger.debug('Returning cached changelog'); return cachedResult; } try { const res = await sourceGithub.getChangeLogJSON({ ...args }); const output = await addReleaseNotes(res); - await sourceCache.setChangeLogJSON(args, output); + const cacheMinutes = 60; + await renovateCache.set( + cacheNamespace, + getCacheKey(args), + output, + cacheMinutes + ); return output; } catch (err) /* istanbul ignore next */ { logger.error( diff --git a/lib/workers/pr/changelog/source-cache.js b/lib/workers/pr/changelog/source-cache.js deleted file mode 100644 index 3c6502dc72faca38ea5471388ef240a1352a2206..0000000000000000000000000000000000000000 --- a/lib/workers/pr/changelog/source-cache.js +++ /dev/null @@ -1,53 +0,0 @@ -const os = require('os'); -const cacache = require('cacache/en'); -const { DateTime } = require('luxon'); - -module.exports = { - getChangeLogJSON, - setChangeLogJSON, - rmAllCache, -}; - -function getCache({ manager, depName, fromVersion, toVersion, releases }) { - const tmpdir = process.env.RENOVATE_TMPDIR || os.tmpdir(); - const cachePath = tmpdir + '/renovate-cache-changelog-v3'; - const cacheKey = `${manager}-${depName}-${fromVersion}-${toVersion}-${ - releases ? releases.map(release => release.version).join('-') : '' - }`; - return [cachePath, cacheKey]; -} - -async function getChangeLogJSON(args) { - const cache = getCache(args); - const { depName } = args; - try { - const cacheVal = await cacache.get(...cache); - logger.trace(`Returning cached version of ${depName}`); - const cachedResult = JSON.parse(cacheVal.data.toString()); - if (cachedResult) { - if (DateTime.local() < DateTime.fromISO(cachedResult.expiry)) { - logger.debug('Cache hit'); - delete cachedResult.expiry; - return cachedResult; - } - // istanbul ignore next - logger.debug('Cache expiry'); - } - } catch (err) { - logger.debug('Cache miss'); - } - return null; -} - -async function setChangeLogJSON(args, res) { - const cache = getCache(args); - await cacache.put( - ...cache, - JSON.stringify({ ...res, expiry: DateTime.local().plus({ hours: 1 }) }) - ); -} - -async function rmAllCache() { - const cache = getCache({}); - await cacache.rm.all(cache[0]); -} diff --git a/test/datasource/github.spec.js b/test/datasource/github.spec.js index 597d26bd4ee84736f81f095d34db9c347d8c62c6..5342f5f8ae9c24b63f8176148e402e8d35b5cc2e 100644 --- a/test/datasource/github.spec.js +++ b/test/datasource/github.spec.js @@ -39,7 +39,7 @@ describe('datasource/github', () => { }); }); describe('getPkgReleases', () => { - beforeAll(() => github.rmAllCache()); + beforeAll(() => global.renovateCache.rmAll()); it('returns cleaned tags', async () => { const body = [ { name: 'a' }, diff --git a/test/globals.js b/test/globals.js index 083c640aa5076864c53c78fa2c991656addf8940..eba1f177d6df7af0b8260357c600007594282527 100644 --- a/test/globals.js +++ b/test/globals.js @@ -1,5 +1,9 @@ jest.mock('gh-got'); jest.mock('gl-got'); +const cache = require('../lib/workers/global/cache'); + global.platform = jest.genMockFromModule('../lib/platform/github'); global.logger = require('./_fixtures/logger'); + +cache.init(); diff --git a/test/workers/pr/changelog.spec.js b/test/workers/pr/changelog.spec.js index 257181a37961c14583aeab33f51e698dd516db7e..4df4f1f32eb029cf1d1c18fcaa21f1739a867ef9 100644 --- a/test/workers/pr/changelog.spec.js +++ b/test/workers/pr/changelog.spec.js @@ -6,9 +6,6 @@ const endpoints = require('../../../lib/util/endpoints'); const ghGot = require('../../../lib/platform/github/gh-got-wrapper'); const { getChangeLogJSON } = require('../../../lib/workers/pr/changelog'); -const { - rmAllCache, -} = require('../../../lib/workers/pr/changelog/source-cache'); const upgrade = { depName: 'renovate', @@ -39,7 +36,7 @@ describe('workers/pr/changelog', () => { platform: 'github', endpoint: 'https://api.github.com/', }); - await rmAllCache(); + await global.renovateCache.rmAll(); }); it('returns null if no fromVersion', async () => { expect(