Skip to content

Commit e7f55d7

Browse files
refactor: extract applyHostRules and applyNpmrc to functions (renovatebot#41528)
* refactor: extract `applyHostRules` and `applyNpmrc` to functions * Reuse applyHostRules in inherited.ts * Restore original log message for npmrc * Simplify applyNpmrc log context handling * Remove redundant config word * Apply Jamie's suggestion * Restore log messages again * Revert "Restore log messages again" This reverts commit 7a67c5d. * chore: re-add log line --------- Co-authored-by: Jamie Tanna <jamie.tanna@mend.io>
1 parent e914a5f commit e7f55d7

File tree

3 files changed

+127
-53
lines changed

3 files changed

+127
-53
lines changed

lib/workers/repository/init/inherited.ts

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,8 @@ import {
1616
} from '../../../constants/error-messages.ts';
1717
import { logger } from '../../../logger/index.ts';
1818
import { platform } from '../../../modules/platform/index.ts';
19-
import * as hostRules from '../../../util/host-rules.ts';
20-
import * as queue from '../../../util/http/queue.ts';
21-
import * as throttle from '../../../util/http/throttle.ts';
2219
import * as template from '../../../util/template/index.ts';
20+
import { applyHostRules } from './merge.ts';
2321

2422
export async function mergeInheritedConfig(
2523
config: RenovateConfig,
@@ -127,7 +125,7 @@ export async function mergeInheritedConfig(
127125
secrets: config.secrets ?? {},
128126
variables: config.variables ?? {},
129127
});
130-
setInheritedHostRules(filteredConfig);
128+
applyHostRules(filteredConfig);
131129
filteredConfig = InheritConfig.set(filteredConfig);
132130
return mergeChildConfig(config, filteredConfig);
133131
}
@@ -172,28 +170,7 @@ export async function mergeInheritedConfig(
172170
secrets: config.secrets ?? {},
173171
variables: config.variables ?? {},
174172
});
175-
setInheritedHostRules(filteredConfig);
173+
applyHostRules(filteredConfig);
176174
filteredConfig = InheritConfig.set(filteredConfig);
177175
return mergeChildConfig(config, filteredConfig);
178176
}
179-
180-
function setInheritedHostRules(config: RenovateConfig): void {
181-
if (config.hostRules) {
182-
logger.debug('Setting hostRules from config');
183-
for (const rule of config.hostRules) {
184-
try {
185-
hostRules.add(rule);
186-
} catch (err) {
187-
// istanbul ignore next
188-
logger.warn(
189-
{ err, config: rule },
190-
'Error setting hostRule from config',
191-
);
192-
}
193-
}
194-
// host rules can change concurrency
195-
queue.clear();
196-
throttle.clear();
197-
delete config.hostRules;
198-
}
199-
}

lib/workers/repository/init/merge.spec.ts

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,20 @@ import { getConfig } from '../../../config/defaults.ts';
77
import * as _migrateAndValidate from '../../../config/migrate-validate.ts';
88
import * as _migrate from '../../../config/migration.ts';
99
import type { AllConfig } from '../../../config/types.ts';
10+
import * as npmApi from '../../../modules/datasource/npm/index.ts';
1011
import * as memCache from '../../../util/cache/memory/index.ts';
1112
import * as repoCache from '../../../util/cache/repository/index.ts';
1213
import { initRepoCache } from '../../../util/cache/repository/init.ts';
1314
import type { RepoCacheData } from '../../../util/cache/repository/types.ts';
1415
import { getUserEnv } from '../../../util/env.ts';
16+
import * as hostRules from '../../../util/host-rules.ts';
17+
import * as queue from '../../../util/http/queue.ts';
18+
import * as throttle from '../../../util/http/throttle.ts';
1519
import * as _onboardingCache from '../onboarding/branch/onboarding-branch-cache.ts';
1620
import { OnboardingState } from '../onboarding/common.ts';
1721
import {
22+
applyHostRules,
23+
applyNpmrc,
1824
checkForRepoConfigError,
1925
detectRepoFileConfig,
2026
mergeRenovateConfig,
@@ -503,6 +509,88 @@ describe('workers/repository/init/merge', () => {
503509
});
504510
});
505511

512+
describe('applyNpmrc', () => {
513+
it('does nothing if npmrc is missing after token migration', () => {
514+
const setNpmrcSpy = vi.spyOn(npmApi, 'setNpmrc');
515+
516+
applyNpmrc({});
517+
518+
expect(setNpmrcSpy).not.toHaveBeenCalled();
519+
});
520+
521+
it('migrates npmToken and sets npmrc', () => {
522+
const setNpmrcSpy = vi.spyOn(npmApi, 'setNpmrc');
523+
const config = {
524+
npmToken: 'token',
525+
npmrc: 'something_authToken=${NPM_TOKEN}',
526+
};
527+
528+
applyNpmrc(config);
529+
530+
expect(config.npmToken).toBeUndefined();
531+
expect(config.npmrc).toBe('something_authToken=token');
532+
expect(setNpmrcSpy).toHaveBeenCalledExactlyOnceWith(
533+
'something_authToken=token',
534+
);
535+
});
536+
});
537+
538+
describe('applyHostRules', () => {
539+
it('does nothing when hostRules is not configured', () => {
540+
const addSpy = vi.spyOn(hostRules, 'add');
541+
const clearQueueSpy = vi.spyOn(queue, 'clear');
542+
const clearThrottleSpy = vi.spyOn(throttle, 'clear');
543+
544+
applyHostRules({});
545+
546+
expect(addSpy).not.toHaveBeenCalled();
547+
expect(clearQueueSpy).not.toHaveBeenCalled();
548+
expect(clearThrottleSpy).not.toHaveBeenCalled();
549+
});
550+
551+
it('adds hostRules and clears queue and throttle', () => {
552+
const addSpy = vi
553+
.spyOn(hostRules, 'add')
554+
.mockImplementation(() => undefined);
555+
const clearQueueSpy = vi.spyOn(queue, 'clear');
556+
const clearThrottleSpy = vi.spyOn(throttle, 'clear');
557+
const config = {
558+
hostRules: [{ matchHost: 'registry.npmjs.org' }],
559+
};
560+
561+
applyHostRules(config);
562+
563+
expect(addSpy).toHaveBeenCalledExactlyOnceWith({
564+
matchHost: 'registry.npmjs.org',
565+
});
566+
expect(clearQueueSpy).toHaveBeenCalledOnce();
567+
expect(clearThrottleSpy).toHaveBeenCalledOnce();
568+
expect(config.hostRules).toBeUndefined();
569+
});
570+
571+
it('warns on invalid hostRule and continues applying others', () => {
572+
const addSpy = vi
573+
.spyOn(hostRules, 'add')
574+
.mockImplementationOnce(() => {
575+
throw new Error('invalid host rule');
576+
})
577+
.mockImplementation(() => undefined);
578+
const clearQueueSpy = vi.spyOn(queue, 'clear');
579+
const clearThrottleSpy = vi.spyOn(throttle, 'clear');
580+
const config = {
581+
hostRules: [{ matchHost: 'one.example' }, { matchHost: 'two.example' }],
582+
};
583+
584+
applyHostRules(config);
585+
586+
expect(addSpy).toHaveBeenCalledTimes(2);
587+
expect(logger.logger.warn).toHaveBeenCalledOnce();
588+
expect(clearQueueSpy).toHaveBeenCalledOnce();
589+
expect(clearThrottleSpy).toHaveBeenCalledOnce();
590+
expect(config.hostRules).toBeUndefined();
591+
});
592+
});
593+
506594
describe('static repository config', () => {
507595
const repoStaticConfigFileKey = 'RENOVATE_X_STATIC_REPO_CONFIG_FILE';
508596

lib/workers/repository/init/merge.ts

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -239,12 +239,7 @@ export async function mergeRenovateConfig(
239239
const repository = config.repository!;
240240
// Decrypt before resolving in case we need npm authentication for any presets
241241
const decryptedConfig = await decryptConfig(migratedConfig, repository);
242-
setNpmTokenInNpmrc(decryptedConfig);
243-
// istanbul ignore if
244-
if (isString(decryptedConfig.npmrc)) {
245-
logger.debug('Found npmrc in decrypted config - setting');
246-
npmApi.setNpmrc(decryptedConfig.npmrc);
247-
}
242+
applyNpmrc(decryptedConfig, 'decrypted');
248243
// Decrypt after resolving in case the preset contains npm authentication instead
249244
const { config: configToDecrypt } = await presets.resolveConfigPresets(
250245
decryptedConfig,
@@ -259,14 +254,12 @@ export async function mergeRenovateConfig(
259254
logger.trace({ config: resolvedConfig }, 'resolved config after migrating');
260255
resolvedConfig = migrationResult.migratedConfig;
261256
}
262-
setNpmTokenInNpmrc(resolvedConfig);
263-
// istanbul ignore if
264257
if (isString(resolvedConfig.npmrc)) {
265258
logger.debug(
266259
'Ignoring any .npmrc files in repository due to configured npmrc',
267260
);
268-
npmApi.setNpmrc(resolvedConfig.npmrc);
269261
}
262+
applyNpmrc(resolvedConfig, 'resolved');
270263
resolvedConfig = applySecretsAndVariablesToConfig({
271264
config: resolvedConfig,
272265
secrets: mergeChildConfig(
@@ -279,24 +272,7 @@ export async function mergeRenovateConfig(
279272
),
280273
});
281274

282-
// istanbul ignore if
283-
if (resolvedConfig.hostRules) {
284-
logger.debug('Setting hostRules from config');
285-
for (const rule of resolvedConfig.hostRules) {
286-
try {
287-
hostRules.add(rule);
288-
} catch (err) {
289-
logger.warn(
290-
{ err, config: rule },
291-
'Error setting hostRule from config',
292-
);
293-
}
294-
}
295-
// host rules can change concurrency
296-
queue.clear();
297-
throttle.clear();
298-
delete resolvedConfig.hostRules;
299-
}
275+
applyHostRules(resolvedConfig);
300276
returnConfig = mergeChildConfig(returnConfig, resolvedConfig);
301277
({ config: returnConfig } = await presets.resolveConfigPresets(
302278
returnConfig,
@@ -317,6 +293,39 @@ export async function mergeRenovateConfig(
317293
return returnConfig;
318294
}
319295

296+
export function applyNpmrc(
297+
config: RenovateConfig,
298+
configType?: 'resolved' | 'decrypted',
299+
): void {
300+
setNpmTokenInNpmrc(config);
301+
if (!isString(config.npmrc)) {
302+
return;
303+
}
304+
logger.debug(
305+
`Setting npmrc from ${configType ? `${configType} ` : ''}config`,
306+
);
307+
npmApi.setNpmrc(config.npmrc);
308+
}
309+
310+
export function applyHostRules(config: RenovateConfig): void {
311+
if (!config.hostRules) {
312+
return;
313+
}
314+
315+
logger.debug('Setting hostRules from config');
316+
for (const rule of config.hostRules) {
317+
try {
318+
hostRules.add(rule);
319+
} catch (err) {
320+
logger.warn({ err, config: rule }, 'Error setting hostRule from config');
321+
}
322+
}
323+
// host rules can change concurrency
324+
queue.clear();
325+
throttle.clear();
326+
delete config.hostRules;
327+
}
328+
320329
/** needed when using portal secrets for npmToken */
321330
export function setNpmTokenInNpmrc(config: RenovateConfig): void {
322331
if (!isString(config.npmToken)) {

0 commit comments

Comments
 (0)