diff --git a/lib/util/git/index.ts b/lib/util/git/index.ts index 6122d20755ff0a175373cc203a443c4ab6ad1dc7..b8104496f1a5a5ca33d3526c370204ac43b5aba8 100644 --- a/lib/util/git/index.ts +++ b/lib/util/git/index.ts @@ -17,7 +17,7 @@ import { import { logger } from '../../logger'; import { ExternalHostError } from '../../types/errors/external-host-error'; import { GitOptions, GitProtocol } from '../../types/git'; -import * as limits from '../../workers/global/limits'; +import { Limit, incLimitedValue } from '../../workers/global/limits'; import { writePrivateKey } from './private-key'; export * from './private-key'; @@ -455,7 +455,7 @@ export async function mergeBranch(branchName: string): Promise<void> { await git.checkout(config.currentBranch); await git.merge(['--ff-only', branchName]); await git.push('origin', config.currentBranch); - limits.incrementLimit('prCommitsPerRunLimit'); + incLimitedValue(Limit.Commits); } export async function getBranchLastCommitTime( @@ -604,7 +604,7 @@ export async function commitFiles({ await git.fetch(['origin', ref, '--depth=2', '--force']); config.branchCommits[branchName] = commit; config.branchIsModified[branchName] = false; - limits.incrementLimit('prCommitsPerRunLimit'); + incLimitedValue(Limit.Commits); return commit; } catch (err) /* istanbul ignore next */ { checkForPlatformFailure(err); diff --git a/lib/workers/global/index.spec.ts b/lib/workers/global/index.spec.ts index f58c0a58fdcbfe5d37de0b792fadd67c01ecd393..b79eef90536cccf64c73cd307a2164d7f7da7322 100644 --- a/lib/workers/global/index.spec.ts +++ b/lib/workers/global/index.spec.ts @@ -59,7 +59,7 @@ describe('lib/workers/global', () => { }); it('processes repositories break', async () => { - limits.getLimitRemaining = jest.fn(() => 0); + limits.isLimitReached = jest.fn(() => true); configParser.parseConfigs.mockResolvedValueOnce({ gitAuthor: 'a@b.com', enabled: true, diff --git a/lib/workers/global/index.ts b/lib/workers/global/index.ts index 2629360c9025e53933ce1c41cc77d1f700afc15e..6e353acf06fd8a89914b3ccc9c6ab87ec7790bcd 100644 --- a/lib/workers/global/index.ts +++ b/lib/workers/global/index.ts @@ -8,7 +8,7 @@ import * as hostRules from '../../util/host-rules'; import * as repositoryWorker from '../repository'; import { autodiscoverRepositories } from './autodiscover'; import { globalFinalize, globalInitialize } from './initialize'; -import * as limits from './limits'; +import { Limit, isLimitReached } from './limits'; type RenovateConfig = configParser.RenovateConfig; type RenovateRepository = configParser.RenovateRepository; @@ -35,7 +35,7 @@ function getGlobalConfig(): Promise<RenovateConfig> { } function haveReachedLimits(): boolean { - if (limits.getLimitRemaining('prCommitsPerRunLimit') <= 0) { + if (isLimitReached(Limit.Commits)) { logger.info('Max commits created for this run.'); return true; } diff --git a/lib/workers/global/initialize.ts b/lib/workers/global/initialize.ts index f575084b75e4464ad6c7ad7dc955af9106966bc9..dc2e34d39bfcece645ed7b11421e5cc522c8bda3 100644 --- a/lib/workers/global/initialize.ts +++ b/lib/workers/global/initialize.ts @@ -6,7 +6,7 @@ import { logger } from '../../logger'; import { initPlatform } from '../../platform'; import * as packageCache from '../../util/cache/package'; import { setEmojiConfig } from '../../util/emoji'; -import * as limits from './limits'; +import { Limit, setMaxLimit } from './limits'; async function setDirectories(input: RenovateConfig): Promise<RenovateConfig> { const config: RenovateConfig = { ...input }; @@ -35,7 +35,7 @@ export async function globalInitialize( config = await initPlatform(config); config = await setDirectories(config); packageCache.init(config); - limits.init(config); + setMaxLimit(Limit.Commits, config.prCommitsPerRunLimit); setEmojiConfig(config); return config; } diff --git a/lib/workers/global/limits.spec.ts b/lib/workers/global/limits.spec.ts index 6e89bc7a69351d5132efac9f22480cdac6aa4957..d2a4ad8b6b2ae5e2ee77a4675d8daa6da8c59ccd 100644 --- a/lib/workers/global/limits.spec.ts +++ b/lib/workers/global/limits.spec.ts @@ -1,21 +1,43 @@ -import { getLimitRemaining, incrementLimit, init } from './limits'; +import { + Limit, + incLimitedValue, + isLimitReached, + resetAllLimits, + setMaxLimit, +} from './limits'; describe('lib/workers/global/limits', () => { - describe('init()', () => { - it('check defined variables have a value set to zero', () => { - const config = { prCommitsPerRunLimit: 3 }; - init(config); - const result = getLimitRemaining('prCommitsPerRunLimit'); - expect(result).toEqual(3); - }); + beforeEach(() => { + resetAllLimits(); }); - describe('incrementLimit()', () => { - it('check increment works as expected', () => { - const config = { prCommitsPerRunLimit: 3 }; - init(config); - incrementLimit('prCommitsPerRunLimit', 2); - const result = getLimitRemaining('prCommitsPerRunLimit'); - expect(result).toEqual(1); - }); + + beforeEach(() => { + resetAllLimits(); + }); + + it('increments limited value', () => { + setMaxLimit(Limit.Commits, 3); + + expect(isLimitReached(Limit.Commits)).toBe(false); + + incLimitedValue(Limit.Commits, 2); + expect(isLimitReached(Limit.Commits)).toBe(false); + + incLimitedValue(Limit.Commits); + expect(isLimitReached(Limit.Commits)).toBe(true); + + incLimitedValue(Limit.Commits); + expect(isLimitReached(Limit.Commits)).toBe(true); + }); + + it('defaults to unlimited', () => { + expect(isLimitReached(Limit.Commits)).toBe(false); + }); + + it('increments undefined', () => { + incLimitedValue(Limit.Commits); + expect(isLimitReached(Limit.Commits)).toBe(false); + setMaxLimit(Limit.Commits, 1); + expect(isLimitReached(Limit.Commits)).toBe(true); }); }); diff --git a/lib/workers/global/limits.ts b/lib/workers/global/limits.ts index 0cf7d3052da9f32f16f4ebb19a66032b510d02db..5bb983bb09aa823e0845972a501a11ed81fc47c9 100644 --- a/lib/workers/global/limits.ts +++ b/lib/workers/global/limits.ts @@ -1,41 +1,44 @@ import { logger } from '../../logger'; -const limitsToInit = ['prCommitsPerRunLimit']; -const l: Record<string, number> = {}; -const v: Record<string, number> = {}; +export enum Limit { + Commits = 'Commits', +} -export function setLimit(name: string, value: number): void { - logger.debug(`Limits.setLimit l[${name}] = ${value}`); - l[name] = value; +interface LimitValue { + max: number | null; + current: number; } -export function init(config: Record<string, any>): void { - logger.debug(`Limits.init enter method`); - for (const limit of limitsToInit) { - logger.debug(`Limits.init ${limit} processing`); - if (config[limit]) { - setLimit(limit, config[limit]); - v[limit] = 0; - } else { - logger.debug( - `Limits.init ${limit} variable is not set. Ignoring ${limit}` - ); - } - } +const limits = new Map<Limit, LimitValue>(); + +export function resetAllLimits(): void { + limits.clear(); } -export function getLimitRemaining(name: string): number { - let result; - if (typeof v[name] !== 'undefined') { - result = l[name] - v[name]; - } else { - result = undefined; - } - return result; +export function setMaxLimit(key: Limit, max: unknown): void { + const maxVal = typeof max === 'number' && max > 0 ? max : null; + logger.debug(`${key} limit = ${maxVal}`); + const limit = limits.get(key); + limits.set(key, { + current: 0, + ...limit, + max: maxVal, + }); +} + +export function incLimitedValue(key: Limit, incBy = 1): void { + const limit = limits.get(key) || { max: null, current: 0 }; + limits.set(key, { + ...limit, + current: limit.current + incBy, + }); } -export function incrementLimit(name: string, value = 1): void { - if (typeof v[name] !== 'undefined') { - v[name] += value; +export function isLimitReached(key: Limit): boolean { + const limit = limits.get(key); + if (!limit || limit.max === null) { + return false; } + const { max, current } = limit; + return max - current <= 0; } diff --git a/lib/workers/repository/process/write.ts b/lib/workers/repository/process/write.ts index e127fa10ca21b97da9e93a7f408b25f4248ac409..424653d380c66df5063b0a08b91ff7ceaedd0bd4 100644 --- a/lib/workers/repository/process/write.ts +++ b/lib/workers/repository/process/write.ts @@ -2,7 +2,7 @@ import { RenovateConfig } from '../../../config'; import { addMeta, logger, removeMeta } from '../../../logger'; import { processBranch } from '../../branch'; import { BranchConfig, ProcessBranchResult } from '../../common'; -import { getLimitRemaining } from '../../global/limits'; +import { Limit, isLimitReached } from '../../global/limits'; import { getPrsRemaining } from './limits'; export type WriteUpdateResult = 'done' | 'automerged'; @@ -32,7 +32,7 @@ export async function writeUpdates( for (const branch of branches) { addMeta({ branch: branch.branchName }); const prLimitReached = prsRemaining <= 0; - const commitLimitReached = getLimitRemaining('prCommitsPerRunLimit') <= 0; + const commitLimitReached = isLimitReached(Limit.Commits); const res = await processBranch(branch, prLimitReached, commitLimitReached); branch.res = res; if (