mirror of
https://github.com/renovatebot/renovate.git
synced 2025-01-11 14:36:25 +00:00
refactor: move config/parse into global worker (#10282)
This commit is contained in:
parent
1af4d80a5a
commit
11694e9294
23 changed files with 272 additions and 246 deletions
|
@ -4,12 +4,12 @@ import { dequal } from 'dequal';
|
|||
import { readFileSync } from 'fs-extra';
|
||||
import JSON5 from 'json5';
|
||||
import { configFileNames } from './config/app-strings';
|
||||
import { getConfig as getFileConfig } from './config/file';
|
||||
import { massageConfig } from './config/massage';
|
||||
import { migrateConfig } from './config/migration';
|
||||
import type { RenovateConfig } from './config/types';
|
||||
import { validateConfig } from './config/validation';
|
||||
import { logger } from './logger';
|
||||
import { getConfig as getFileConfig } from './workers/global/config/parse/file';
|
||||
|
||||
/* eslint-disable no-console */
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import { setAdminConfig } from './admin';
|
|||
import { decryptConfig } from './decrypt';
|
||||
import type { RenovateConfig } from './types';
|
||||
|
||||
const privateKey = loadFixture('private.pem', 'keys');
|
||||
const privateKey = loadFixture('private.pem', '.');
|
||||
|
||||
describe(getName(), () => {
|
||||
describe('decryptConfig()', () => {
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
import upath from 'upath';
|
||||
import { getName } from '../../test/util';
|
||||
import { readFile } from '../util/fs';
|
||||
import getArgv from './config/__fixtures__/argv';
|
||||
import { getConfig } from './defaults';
|
||||
|
||||
jest.mock('../datasource/npm');
|
||||
|
@ -14,111 +11,6 @@ try {
|
|||
const defaultConfig = getConfig();
|
||||
|
||||
describe(getName(), () => {
|
||||
describe('.parseConfigs(env, defaultArgv)', () => {
|
||||
let configParser: typeof import('.');
|
||||
let defaultArgv: string[];
|
||||
let defaultEnv: NodeJS.ProcessEnv;
|
||||
beforeEach(async () => {
|
||||
jest.resetModules();
|
||||
configParser = await import('./index');
|
||||
defaultArgv = getArgv();
|
||||
defaultEnv = { RENOVATE_CONFIG_FILE: 'abc' };
|
||||
jest.mock('delay', () => Promise.resolve());
|
||||
});
|
||||
it('supports token in env', async () => {
|
||||
const env: NodeJS.ProcessEnv = { ...defaultEnv, RENOVATE_TOKEN: 'abc' };
|
||||
const parsedConfig = await configParser.parseConfigs(env, defaultArgv);
|
||||
expect(parsedConfig).toContainEntries([['token', 'abc']]);
|
||||
});
|
||||
|
||||
it('supports token in CLI options', async () => {
|
||||
defaultArgv = defaultArgv.concat([
|
||||
'--token=abc',
|
||||
'--pr-footer=custom',
|
||||
'--log-context=abc123',
|
||||
]);
|
||||
const parsedConfig = await configParser.parseConfigs(
|
||||
defaultEnv,
|
||||
defaultArgv
|
||||
);
|
||||
expect(parsedConfig).toContainEntries([
|
||||
['token', 'abc'],
|
||||
['prFooter', 'custom'],
|
||||
['logContext', 'abc123'],
|
||||
]);
|
||||
});
|
||||
|
||||
it('supports forceCli', async () => {
|
||||
defaultArgv = defaultArgv.concat(['--force-cli=false']);
|
||||
const env: NodeJS.ProcessEnv = {
|
||||
...defaultEnv,
|
||||
RENOVATE_TOKEN: 'abc',
|
||||
};
|
||||
const parsedConfig = await configParser.parseConfigs(env, defaultArgv);
|
||||
expect(parsedConfig).toContainEntries([
|
||||
['token', 'abc'],
|
||||
['force', null],
|
||||
]);
|
||||
expect(parsedConfig).not.toContainKey('configFile');
|
||||
});
|
||||
it('supports config.force', async () => {
|
||||
const configPath = upath.join(
|
||||
__dirname,
|
||||
'config/__fixtures__/with-force.js'
|
||||
);
|
||||
const env: NodeJS.ProcessEnv = {
|
||||
...defaultEnv,
|
||||
RENOVATE_CONFIG_FILE: configPath,
|
||||
};
|
||||
const parsedConfig = await configParser.parseConfigs(env, defaultArgv);
|
||||
expect(parsedConfig).toContainEntries([
|
||||
['token', 'abcdefg'],
|
||||
[
|
||||
'force',
|
||||
{
|
||||
schedule: null,
|
||||
},
|
||||
],
|
||||
]);
|
||||
});
|
||||
it('reads private key from file', async () => {
|
||||
const privateKeyPath = upath.join(
|
||||
__dirname,
|
||||
'keys/__fixtures__/private.pem'
|
||||
);
|
||||
const env: NodeJS.ProcessEnv = {
|
||||
...defaultEnv,
|
||||
RENOVATE_PRIVATE_KEY_PATH: privateKeyPath,
|
||||
};
|
||||
const expected = await readFile(privateKeyPath);
|
||||
const parsedConfig = await configParser.parseConfigs(env, defaultArgv);
|
||||
|
||||
expect(parsedConfig).toContainEntries([['privateKey', expected]]);
|
||||
});
|
||||
it('supports Bitbucket username/passwod', async () => {
|
||||
defaultArgv = defaultArgv.concat([
|
||||
'--platform=bitbucket',
|
||||
'--username=user',
|
||||
'--password=pass',
|
||||
]);
|
||||
const parsedConfig = await configParser.parseConfigs(
|
||||
defaultEnv,
|
||||
defaultArgv
|
||||
);
|
||||
expect(parsedConfig).toContainEntries([
|
||||
['platform', 'bitbucket'],
|
||||
['username', 'user'],
|
||||
['password', 'pass'],
|
||||
]);
|
||||
});
|
||||
it('massages trailing slash into endpoint', async () => {
|
||||
defaultArgv = defaultArgv.concat([
|
||||
'--endpoint=https://github.renovatebot.com/api/v3',
|
||||
]);
|
||||
const parsed = await configParser.parseConfigs(defaultEnv, defaultArgv);
|
||||
expect(parsed.endpoint).toEqual('https://github.renovatebot.com/api/v3/');
|
||||
});
|
||||
});
|
||||
describe('mergeChildConfig(parentConfig, childConfig)', () => {
|
||||
it('merges', async () => {
|
||||
const parentConfig = { ...defaultConfig };
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
import { addStream, logger, setContext } from '../logger';
|
||||
import { logger } from '../logger';
|
||||
import { get, getLanguageList, getManagerList } from '../manager';
|
||||
import { ensureDir, getSubDirectory, readFile } from '../util/fs';
|
||||
import { ensureTrailingSlash } from '../util/url';
|
||||
import * as cliParser from './cli';
|
||||
import * as defaultsParser from './defaults';
|
||||
import * as definitions from './definitions';
|
||||
import * as envParser from './env';
|
||||
import * as fileParser from './file';
|
||||
import type {
|
||||
AllConfig,
|
||||
ManagerConfig,
|
||||
|
@ -39,85 +33,6 @@ export function getManagerConfig(
|
|||
return managerConfig;
|
||||
}
|
||||
|
||||
export async function parseConfigs(
|
||||
env: NodeJS.ProcessEnv,
|
||||
argv: string[]
|
||||
): Promise<AllConfig> {
|
||||
logger.debug('Parsing configs');
|
||||
|
||||
// Get configs
|
||||
const defaultConfig = defaultsParser.getConfig();
|
||||
const fileConfig = fileParser.getConfig(env);
|
||||
const cliConfig = cliParser.getConfig(argv);
|
||||
const envConfig = envParser.getConfig(env);
|
||||
|
||||
let config: AllConfig = mergeChildConfig(fileConfig, envConfig);
|
||||
config = mergeChildConfig(config, cliConfig);
|
||||
|
||||
const combinedConfig = config;
|
||||
|
||||
config = mergeChildConfig(defaultConfig, config);
|
||||
|
||||
if (config.forceCli) {
|
||||
const forcedCli = { ...cliConfig };
|
||||
delete forcedCli.token;
|
||||
delete forcedCli.hostRules;
|
||||
if (config.force) {
|
||||
config.force = { ...config.force, ...forcedCli };
|
||||
} else {
|
||||
config.force = forcedCli;
|
||||
}
|
||||
}
|
||||
|
||||
if (!config.privateKey && config.privateKeyPath) {
|
||||
config.privateKey = await readFile(config.privateKeyPath);
|
||||
delete config.privateKeyPath;
|
||||
}
|
||||
|
||||
if (config.logContext) {
|
||||
// This only has an effect if logContext was defined via file or CLI, otherwise it would already have been detected in env
|
||||
setContext(config.logContext);
|
||||
}
|
||||
|
||||
// Add file logger
|
||||
// istanbul ignore if
|
||||
if (config.logFile) {
|
||||
logger.debug(
|
||||
`Enabling ${config.logFileLevel} logging to ${config.logFile}`
|
||||
);
|
||||
await ensureDir(getSubDirectory(config.logFile));
|
||||
addStream({
|
||||
name: 'logfile',
|
||||
path: config.logFile,
|
||||
level: config.logFileLevel,
|
||||
});
|
||||
}
|
||||
|
||||
logger.trace({ config: defaultConfig }, 'Default config');
|
||||
logger.debug({ config: fileConfig }, 'File config');
|
||||
logger.debug({ config: cliConfig }, 'CLI config');
|
||||
logger.debug({ config: envConfig }, 'Env config');
|
||||
logger.debug({ config: combinedConfig }, 'Combined config');
|
||||
|
||||
// Get global config
|
||||
logger.trace({ config }, 'Full config');
|
||||
|
||||
// Print config
|
||||
logger.trace({ config }, 'Global config');
|
||||
|
||||
// Massage endpoint to have a trailing slash
|
||||
if (config.endpoint) {
|
||||
logger.debug('Adding trailing slash to endpoint');
|
||||
config.endpoint = ensureTrailingSlash(config.endpoint);
|
||||
}
|
||||
|
||||
// Remove log file entries
|
||||
delete config.logFile;
|
||||
delete config.logFileLevel;
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
export function filterConfig(
|
||||
inputConfig: AllConfig,
|
||||
targetStage: RenovateConfigStage
|
||||
|
|
|
@ -370,10 +370,6 @@ export interface ManagerConfig extends RenovateConfig {
|
|||
manager: string;
|
||||
}
|
||||
|
||||
export interface RenovateCliConfig extends Record<string, any> {
|
||||
repositories?: string[];
|
||||
}
|
||||
|
||||
export interface MigratedConfig {
|
||||
isMigrated: boolean;
|
||||
migratedConfig: RenovateConfig;
|
||||
|
|
27
lib/workers/global/config/parse/__fixtures__/private.pem
Normal file
27
lib/workers/global/config/parse/__fixtures__/private.pem
Normal file
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpQIBAAKCAQEAzVLc1KmhWxcLnoPTPpQwxVHySFx4vY+0Sk+2AdnlJvrTFlNR
|
||||
8XgBPdgU9SDwHFFTYyXRQ/msm0YMOBRoIdz4/psz6IzRV80aOtDIkUPAU+cdqnje
|
||||
3rusrPnqCykDuIHGoBZ8zlt57t/8OVNOduUflrQRqMFors8iLWcNjuGJfZAusI5B
|
||||
M8KYYDPL2oUo/8AV0bWN8MdNnxDSwGtan4bbzrtG6dpNzyntsG5DkL1h8OZRki4S
|
||||
kHf+71ZzJFz1KcyrzBVJ9DBxdiJdmLLkv9caLLc2QS0VFmtfLnlrga3Sahy6YNwc
|
||||
rN33aaNOXwFPSErsKWIgIf16eOaSUQCFusXY9QIDAQABAoIBAQCkltMM6nm9Ikkf
|
||||
JX9V/8bkth7o4K+tDSAyHZnB/CBUUeaaU+oxDci5AZkzMtcnbA3TQcJxohg6VDmB
|
||||
TuJ2msNCnblLpm492t023pyYzd3DpFXEjKXjmEAAXUm+7n7cDbPiKoSbivrAgO6Y
|
||||
KW6RonPjA6/QPlIjJ0m3aY+VxLfJXTYVfFBk+0HGEAvmrSSSEezXej8Qzs9CRKtz
|
||||
cQkR5Bs749SS509MHxaslP7n366EvJBJkqrjUxA6kbxOxUkuuOWF9jfduDAG+NYc
|
||||
pe4IXFOYMpK/w29wqvkNulKYs+FHXr1sGjkztGjyNnjP0NnX+r0EYU07xLJ26krD
|
||||
KMWQG8sBAoGBAO93iFrPnEBnnKojI8b+u3YowVCz0HVuHHIStHd9uUgfsn/Bxfls
|
||||
HRIlg8l1MJd69TT0knOhkJxBCP+b/qBvid7YLbTxIVELCAfLAzsmGgY+DEN/TTUb
|
||||
FDvHGa/drCnkSR/O/RbtHvMQISzTja1siYrdwwY+wpwzR2tB7ZH/9iO1AoGBANt/
|
||||
3Srpv4BbP7JZ+cNte4JfI2gZq41mo+DF5ryuFZzsP3R5SZ1BOapQGyLEATQaoxsJ
|
||||
QZsI73KPBzab0/+E75qJuXckIGmFftHXgoQpClGvPaEDF9M21QW5Y3vKVa/45qhy
|
||||
3wpb8gEYqrt1x0rmzyumCtCD8J470Er64gE1eKhBAoGBALW6ScFYwqRhvROkvTb8
|
||||
A7mE7kfXXgBwAqhTJ59yytRAMc8gd6R0do9Z5uxQwgKDLmj0ndugpcTe2fxZHuAU
|
||||
JVX3SqCBSZ5eN8bqOtZ9cMyB8/6ZMjd2CGHhE85R9KCJ/TBlfc4TPySIfhStq1wL
|
||||
/UlkR+eKY1f01mNAUhE1ZU7tAoGBAKwS/B51KsSERFYcRToYbRfSX55vaVarnVNL
|
||||
scw+qQDhEAnOP5CBHqTOscc6YzsmmrFKO10/zv8+80ezN6n73B6JU5T8BFDU74uv
|
||||
6EiVJ9rLh4PfOeFB/hPDtyLHhw8yEBkEHKgxVnHXlZjqBzdH5Cdyvs2icZKKj4sI
|
||||
TP7nnVRBAoGAPZBjjTn9HgB9et5Kdovp+7nr842WboxwklVyTpbNGAjIxNXIXex+
|
||||
TST21UbquTIpIrpYRk1WMIu9T5PndAagDWVEsmUYQZeuhmuY64K+iviRsfdGthws
|
||||
nbbR8sMEkn4XEtPZfrEBq27g01RNmIIMW5Es2O5N2AjLlyeBOh099Fw=
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1,6 +1,6 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`config/env .getConfig(env) supports Azure DevOps 1`] = `
|
||||
exports[`workers/global/config/parse/env .getConfig(env) supports Azure DevOps 1`] = `
|
||||
Object {
|
||||
"endpoint": "an Azure DevOps endpoint",
|
||||
"hostRules": Array [],
|
||||
|
@ -9,7 +9,7 @@ Object {
|
|||
}
|
||||
`;
|
||||
|
||||
exports[`config/env .getConfig(env) supports Bitbucket token 1`] = `
|
||||
exports[`workers/global/config/parse/env .getConfig(env) supports Bitbucket token 1`] = `
|
||||
Object {
|
||||
"endpoint": "a bitbucket endpoint",
|
||||
"hostRules": Array [],
|
||||
|
@ -19,7 +19,7 @@ Object {
|
|||
}
|
||||
`;
|
||||
|
||||
exports[`config/env .getConfig(env) supports Bitbucket username/password 1`] = `
|
||||
exports[`workers/global/config/parse/env .getConfig(env) supports Bitbucket username/password 1`] = `
|
||||
Object {
|
||||
"endpoint": "a bitbucket endpoint",
|
||||
"hostRules": Array [],
|
||||
|
@ -29,14 +29,14 @@ Object {
|
|||
}
|
||||
`;
|
||||
|
||||
exports[`config/env .getConfig(env) supports GitHub custom endpoint 1`] = `
|
||||
exports[`workers/global/config/parse/env .getConfig(env) supports GitHub custom endpoint 1`] = `
|
||||
Object {
|
||||
"endpoint": "a ghe endpoint",
|
||||
"hostRules": Array [],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`config/env .getConfig(env) supports GitHub custom endpoint and github.com 1`] = `
|
||||
exports[`workers/global/config/parse/env .getConfig(env) supports GitHub custom endpoint and github.com 1`] = `
|
||||
Object {
|
||||
"endpoint": "a ghe endpoint",
|
||||
"hostRules": Array [
|
||||
|
@ -50,7 +50,7 @@ Object {
|
|||
}
|
||||
`;
|
||||
|
||||
exports[`config/env .getConfig(env) supports GitHub custom endpoint and gitlab.com 1`] = `
|
||||
exports[`workers/global/config/parse/env .getConfig(env) supports GitHub custom endpoint and gitlab.com 1`] = `
|
||||
Object {
|
||||
"endpoint": "a ghe endpoint",
|
||||
"hostRules": Array [],
|
||||
|
@ -58,14 +58,14 @@ Object {
|
|||
}
|
||||
`;
|
||||
|
||||
exports[`config/env .getConfig(env) supports GitHub token 1`] = `
|
||||
exports[`workers/global/config/parse/env .getConfig(env) supports GitHub token 1`] = `
|
||||
Object {
|
||||
"hostRules": Array [],
|
||||
"token": "github.com token",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`config/env .getConfig(env) supports GitLab custom endpoint 1`] = `
|
||||
exports[`workers/global/config/parse/env .getConfig(env) supports GitLab custom endpoint 1`] = `
|
||||
Object {
|
||||
"endpoint": "a gitlab endpoint",
|
||||
"hostRules": Array [],
|
||||
|
@ -74,7 +74,7 @@ Object {
|
|||
}
|
||||
`;
|
||||
|
||||
exports[`config/env .getConfig(env) supports GitLab token 1`] = `
|
||||
exports[`workers/global/config/parse/env .getConfig(env) supports GitLab token 1`] = `
|
||||
Object {
|
||||
"hostRules": Array [],
|
||||
"platform": "gitlab",
|
||||
|
@ -82,7 +82,7 @@ Object {
|
|||
}
|
||||
`;
|
||||
|
||||
exports[`config/env .getConfig(env) supports datasource env token 1`] = `
|
||||
exports[`workers/global/config/parse/env .getConfig(env) supports datasource env token 1`] = `
|
||||
Object {
|
||||
"hostRules": Array [
|
||||
Object {
|
||||
|
@ -93,7 +93,7 @@ Object {
|
|||
}
|
||||
`;
|
||||
|
||||
exports[`config/env .getConfig(env) supports docker username/password 1`] = `
|
||||
exports[`workers/global/config/parse/env .getConfig(env) supports docker username/password 1`] = `
|
||||
Object {
|
||||
"hostRules": Array [
|
||||
Object {
|
||||
|
@ -105,7 +105,7 @@ Object {
|
|||
}
|
||||
`;
|
||||
|
||||
exports[`config/env .getConfig(env) supports domain and host names with case insensitivity 1`] = `
|
||||
exports[`workers/global/config/parse/env .getConfig(env) supports domain and host names with case insensitivity 1`] = `
|
||||
Object {
|
||||
"hostRules": Array [
|
||||
Object {
|
||||
|
@ -122,7 +122,7 @@ Object {
|
|||
}
|
||||
`;
|
||||
|
||||
exports[`config/env .getConfig(env) supports password-only 1`] = `
|
||||
exports[`workers/global/config/parse/env .getConfig(env) supports password-only 1`] = `
|
||||
Object {
|
||||
"hostRules": Array [
|
||||
Object {
|
|
@ -1,6 +1,6 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`config/file .getConfig() migrates 1`] = `
|
||||
exports[`workers/global/config/parse/file .getConfig() migrates 1`] = `
|
||||
Object {
|
||||
"rangeStrategy": "bump",
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
import { getName } from '../../test/util';
|
||||
import * as datasourceDocker from '../datasource/docker';
|
||||
import { getName } from '../../../../../test/util';
|
||||
import type { RenovateOptions } from '../../../../config/types';
|
||||
import * as datasourceDocker from '../../../../datasource/docker';
|
||||
import getArgv from './__fixtures__/argv';
|
||||
import * as cli from './cli';
|
||||
import getArgv from './config/__fixtures__/argv';
|
||||
import type { RenovateOptions } from './types';
|
||||
|
||||
describe(getName(), () => {
|
||||
let argv: string[];
|
|
@ -1,7 +1,7 @@
|
|||
import { Command } from 'commander';
|
||||
import { version } from '../../package.json';
|
||||
import { getOptions } from './definitions';
|
||||
import type { AllConfig, RenovateCliConfig, RenovateOptions } from './types';
|
||||
import { version } from '../../../../../package.json';
|
||||
import { getOptions } from '../../../../config/definitions';
|
||||
import type { AllConfig, RenovateOptions } from '../../../../config/types';
|
||||
|
||||
export function getCliName(option: Partial<RenovateOptions>): string {
|
||||
if (option.cli === false) {
|
||||
|
@ -27,7 +27,7 @@ export function getConfig(input: string[]): AllConfig {
|
|||
.filter((a) => !a.startsWith('--git-fs'));
|
||||
const options = getOptions();
|
||||
|
||||
const config: RenovateCliConfig = {};
|
||||
const config: Record<string, any> = {};
|
||||
|
||||
const coersions: Record<string, (arg: string) => unknown> = {
|
||||
boolean: (val: string): boolean => {
|
|
@ -1,10 +1,10 @@
|
|||
import { getName } from '../../test/util';
|
||||
import { getName } from '../../../../../test/util';
|
||||
import type { RenovateOptions } from '../../../../config/types';
|
||||
import {
|
||||
PLATFORM_TYPE_BITBUCKET,
|
||||
PLATFORM_TYPE_GITLAB,
|
||||
} from '../constants/platforms';
|
||||
} from '../../../../constants/platforms';
|
||||
import * as env from './env';
|
||||
import type { RenovateOptions } from './types';
|
||||
|
||||
describe(getName(), () => {
|
||||
describe('.getConfig(env)', () => {
|
|
@ -1,11 +1,11 @@
|
|||
import is from '@sindresorhus/is';
|
||||
|
||||
import { PLATFORM_TYPE_GITHUB } from '../constants/platforms';
|
||||
import { getDatasourceList } from '../datasource';
|
||||
import { logger } from '../logger';
|
||||
import type { HostRule } from '../types';
|
||||
import { getOptions } from './definitions';
|
||||
import type { AllConfig, RenovateOptions } from './types';
|
||||
import { getOptions } from '../../../../config/definitions';
|
||||
import type { AllConfig, RenovateOptions } from '../../../../config/types';
|
||||
import { PLATFORM_TYPE_GITHUB } from '../../../../constants/platforms';
|
||||
import { getDatasourceList } from '../../../../datasource';
|
||||
import { logger } from '../../../../logger';
|
||||
import type { HostRule } from '../../../../types';
|
||||
|
||||
// istanbul ignore if
|
||||
if (process.env.ENV_PREFIX) {
|
|
@ -1,8 +1,8 @@
|
|||
import fs from 'fs';
|
||||
import { DirectoryResult, dir } from 'tmp-promise';
|
||||
import upath from 'upath';
|
||||
import { getName } from '../../test/util';
|
||||
import customConfig from './config/__fixtures__/file';
|
||||
import { getName } from '../../../../../test/util';
|
||||
import customConfig from './__fixtures__/file';
|
||||
import * as file from './file';
|
||||
|
||||
describe(getName(), () => {
|
||||
|
@ -23,19 +23,13 @@ describe(getName(), () => {
|
|||
);
|
||||
});
|
||||
it('parses custom config file', () => {
|
||||
const configFile = upath.resolve(
|
||||
__dirname,
|
||||
'./config/__fixtures__/file.js'
|
||||
);
|
||||
const configFile = upath.resolve(__dirname, './__fixtures__/file.js');
|
||||
expect(file.getConfig({ RENOVATE_CONFIG_FILE: configFile })).toEqual(
|
||||
customConfig
|
||||
);
|
||||
});
|
||||
it('migrates', () => {
|
||||
const configFile = upath.resolve(
|
||||
__dirname,
|
||||
'./config/__fixtures__/file2.js'
|
||||
);
|
||||
const configFile = upath.resolve(__dirname, './__fixtures__/file2.js');
|
||||
const res = file.getConfig({ RENOVATE_CONFIG_FILE: configFile });
|
||||
expect(res).toMatchSnapshot();
|
||||
expect(res.rangeStrategy).toEqual('bump');
|
|
@ -1,7 +1,7 @@
|
|||
import upath from 'upath';
|
||||
import { logger } from '../logger';
|
||||
import { migrateConfig } from './migration';
|
||||
import type { AllConfig } from './types';
|
||||
import { migrateConfig } from '../../../../config/migration';
|
||||
import type { AllConfig } from '../../../../config/types';
|
||||
import { logger } from '../../../../logger';
|
||||
|
||||
export function getConfig(env: NodeJS.ProcessEnv): AllConfig {
|
||||
let configFile = env.RENOVATE_CONFIG_FILE || 'config';
|
113
lib/workers/global/config/parse/index.spec.ts
Normal file
113
lib/workers/global/config/parse/index.spec.ts
Normal file
|
@ -0,0 +1,113 @@
|
|||
import upath from 'upath';
|
||||
import { getName } from '../../../../../test/util';
|
||||
import { readFile } from '../../../../util/fs';
|
||||
import getArgv from './__fixtures__/argv';
|
||||
|
||||
jest.mock('../../../../datasource/npm');
|
||||
try {
|
||||
jest.mock('../../config.js');
|
||||
} catch (err) {
|
||||
// file does not exist
|
||||
}
|
||||
|
||||
describe(getName(), () => {
|
||||
describe('.parseConfigs(env, defaultArgv)', () => {
|
||||
let configParser: typeof import('.');
|
||||
let defaultArgv: string[];
|
||||
let defaultEnv: NodeJS.ProcessEnv;
|
||||
beforeEach(async () => {
|
||||
jest.resetModules();
|
||||
configParser = await import('./index');
|
||||
defaultArgv = getArgv();
|
||||
defaultEnv = { RENOVATE_CONFIG_FILE: 'abc' };
|
||||
jest.mock('delay', () => Promise.resolve());
|
||||
});
|
||||
it('supports token in env', async () => {
|
||||
const env: NodeJS.ProcessEnv = { ...defaultEnv, RENOVATE_TOKEN: 'abc' };
|
||||
const parsedConfig = await configParser.parseConfigs(env, defaultArgv);
|
||||
expect(parsedConfig).toContainEntries([['token', 'abc']]);
|
||||
});
|
||||
|
||||
it('supports token in CLI options', async () => {
|
||||
defaultArgv = defaultArgv.concat([
|
||||
'--token=abc',
|
||||
'--pr-footer=custom',
|
||||
'--log-context=abc123',
|
||||
]);
|
||||
const parsedConfig = await configParser.parseConfigs(
|
||||
defaultEnv,
|
||||
defaultArgv
|
||||
);
|
||||
expect(parsedConfig).toContainEntries([
|
||||
['token', 'abc'],
|
||||
['prFooter', 'custom'],
|
||||
['logContext', 'abc123'],
|
||||
]);
|
||||
});
|
||||
|
||||
it('supports forceCli', async () => {
|
||||
defaultArgv = defaultArgv.concat(['--force-cli=false']);
|
||||
const env: NodeJS.ProcessEnv = {
|
||||
...defaultEnv,
|
||||
RENOVATE_TOKEN: 'abc',
|
||||
};
|
||||
const parsedConfig = await configParser.parseConfigs(env, defaultArgv);
|
||||
expect(parsedConfig).toContainEntries([
|
||||
['token', 'abc'],
|
||||
['force', null],
|
||||
]);
|
||||
expect(parsedConfig).not.toContainKey('configFile');
|
||||
});
|
||||
it('supports config.force', async () => {
|
||||
const configPath = upath.join(__dirname, '__fixtures__/with-force.js');
|
||||
const env: NodeJS.ProcessEnv = {
|
||||
...defaultEnv,
|
||||
RENOVATE_CONFIG_FILE: configPath,
|
||||
};
|
||||
const parsedConfig = await configParser.parseConfigs(env, defaultArgv);
|
||||
expect(parsedConfig).toContainEntries([
|
||||
['token', 'abcdefg'],
|
||||
[
|
||||
'force',
|
||||
{
|
||||
schedule: null,
|
||||
},
|
||||
],
|
||||
]);
|
||||
});
|
||||
it('reads private key from file', async () => {
|
||||
const privateKeyPath = upath.join(__dirname, '__fixtures__/private.pem');
|
||||
const env: NodeJS.ProcessEnv = {
|
||||
...defaultEnv,
|
||||
RENOVATE_PRIVATE_KEY_PATH: privateKeyPath,
|
||||
};
|
||||
const expected = await readFile(privateKeyPath);
|
||||
const parsedConfig = await configParser.parseConfigs(env, defaultArgv);
|
||||
|
||||
expect(parsedConfig).toContainEntries([['privateKey', expected]]);
|
||||
});
|
||||
it('supports Bitbucket username/passwod', async () => {
|
||||
defaultArgv = defaultArgv.concat([
|
||||
'--platform=bitbucket',
|
||||
'--username=user',
|
||||
'--password=pass',
|
||||
]);
|
||||
const parsedConfig = await configParser.parseConfigs(
|
||||
defaultEnv,
|
||||
defaultArgv
|
||||
);
|
||||
expect(parsedConfig).toContainEntries([
|
||||
['platform', 'bitbucket'],
|
||||
['username', 'user'],
|
||||
['password', 'pass'],
|
||||
]);
|
||||
});
|
||||
it('massages trailing slash into endpoint', async () => {
|
||||
defaultArgv = defaultArgv.concat([
|
||||
'--endpoint=https://github.renovatebot.com/api/v3',
|
||||
]);
|
||||
const parsed = await configParser.parseConfigs(defaultEnv, defaultArgv);
|
||||
expect(parsed.endpoint).toEqual('https://github.renovatebot.com/api/v3/');
|
||||
});
|
||||
});
|
||||
});
|
88
lib/workers/global/config/parse/index.ts
Normal file
88
lib/workers/global/config/parse/index.ts
Normal file
|
@ -0,0 +1,88 @@
|
|||
import * as defaultsParser from '../../../../config/defaults';
|
||||
import { AllConfig } from '../../../../config/types';
|
||||
import { mergeChildConfig } from '../../../../config/utils';
|
||||
import { addStream, logger, setContext } from '../../../../logger';
|
||||
import { ensureDir, getSubDirectory, readFile } from '../../../../util/fs';
|
||||
import { ensureTrailingSlash } from '../../../../util/url';
|
||||
import * as cliParser from './cli';
|
||||
import * as envParser from './env';
|
||||
import * as fileParser from './file';
|
||||
|
||||
export async function parseConfigs(
|
||||
env: NodeJS.ProcessEnv,
|
||||
argv: string[]
|
||||
): Promise<AllConfig> {
|
||||
logger.debug('Parsing configs');
|
||||
|
||||
// Get configs
|
||||
const defaultConfig = defaultsParser.getConfig();
|
||||
const fileConfig = fileParser.getConfig(env);
|
||||
const cliConfig = cliParser.getConfig(argv);
|
||||
const envConfig = envParser.getConfig(env);
|
||||
|
||||
let config: AllConfig = mergeChildConfig(fileConfig, envConfig);
|
||||
config = mergeChildConfig(config, cliConfig);
|
||||
|
||||
const combinedConfig = config;
|
||||
|
||||
config = mergeChildConfig(defaultConfig, config);
|
||||
|
||||
if (config.forceCli) {
|
||||
const forcedCli = { ...cliConfig };
|
||||
delete forcedCli.token;
|
||||
delete forcedCli.hostRules;
|
||||
if (config.force) {
|
||||
config.force = { ...config.force, ...forcedCli };
|
||||
} else {
|
||||
config.force = forcedCli;
|
||||
}
|
||||
}
|
||||
|
||||
if (!config.privateKey && config.privateKeyPath) {
|
||||
config.privateKey = await readFile(config.privateKeyPath);
|
||||
delete config.privateKeyPath;
|
||||
}
|
||||
|
||||
if (config.logContext) {
|
||||
// This only has an effect if logContext was defined via file or CLI, otherwise it would already have been detected in env
|
||||
setContext(config.logContext);
|
||||
}
|
||||
|
||||
// Add file logger
|
||||
// istanbul ignore if
|
||||
if (config.logFile) {
|
||||
logger.debug(
|
||||
`Enabling ${config.logFileLevel} logging to ${config.logFile}`
|
||||
);
|
||||
await ensureDir(getSubDirectory(config.logFile));
|
||||
addStream({
|
||||
name: 'logfile',
|
||||
path: config.logFile,
|
||||
level: config.logFileLevel,
|
||||
});
|
||||
}
|
||||
|
||||
logger.trace({ config: defaultConfig }, 'Default config');
|
||||
logger.debug({ config: fileConfig }, 'File config');
|
||||
logger.debug({ config: cliConfig }, 'CLI config');
|
||||
logger.debug({ config: envConfig }, 'Env config');
|
||||
logger.debug({ config: combinedConfig }, 'Combined config');
|
||||
|
||||
// Get global config
|
||||
logger.trace({ config }, 'Full config');
|
||||
|
||||
// Print config
|
||||
logger.trace({ config }, 'Global config');
|
||||
|
||||
// Massage endpoint to have a trailing slash
|
||||
if (config.endpoint) {
|
||||
logger.debug('Adding trailing slash to endpoint');
|
||||
config.endpoint = ensureTrailingSlash(config.endpoint);
|
||||
}
|
||||
|
||||
// Remove log file entries
|
||||
delete config.logFile;
|
||||
delete config.logFileLevel;
|
||||
|
||||
return config;
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
import { ERROR, WARN } from 'bunyan';
|
||||
import { getName, logger } from '../../../test/util';
|
||||
import * as _configParser from '../../config';
|
||||
import {
|
||||
PLATFORM_TYPE_GITHUB,
|
||||
PLATFORM_TYPE_GITLAB,
|
||||
|
@ -8,6 +7,7 @@ import {
|
|||
import * as datasourceDocker from '../../datasource/docker';
|
||||
import * as _platform from '../../platform';
|
||||
import * as _repositoryWorker from '../repository';
|
||||
import * as _configParser from './config/parse';
|
||||
import * as _limits from './limits';
|
||||
import * as globalWorker from '.';
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import { getProblems, logger, setMeta } from '../../logger';
|
|||
import * as hostRules from '../../util/host-rules';
|
||||
import * as repositoryWorker from '../repository';
|
||||
import { autodiscoverRepositories } from './autodiscover';
|
||||
import { parseConfigs } from './config/parse';
|
||||
import { globalFinalize, globalInitialize } from './initialize';
|
||||
import { Limit, isLimitReached } from './limits';
|
||||
|
||||
|
@ -38,7 +39,7 @@ export async function getRepositoryConfig(
|
|||
}
|
||||
|
||||
function getGlobalConfig(): Promise<RenovateConfig> {
|
||||
return configParser.parseConfigs(process.env, process.argv);
|
||||
return parseConfigs(process.env, process.argv);
|
||||
}
|
||||
|
||||
function haveReachedLimits(): boolean {
|
||||
|
|
Loading…
Reference in a new issue