From 893df627e4fbec4f832885a25dcb7ed3a11449b3 Mon Sep 17 00:00:00 2001 From: Rhys Arkins <rhys@arkins.net> Date: Mon, 12 Apr 2021 06:11:25 +0200 Subject: [PATCH] feat(validation): language/manager top-level check (#9498) --- .../__snapshots__/validation.spec.ts.snap | 13 ++++++++++ lib/config/validation.spec.ts | 26 +++++++++++++++++++ lib/config/validation.ts | 10 ++++++- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/lib/config/__snapshots__/validation.spec.ts.snap b/lib/config/__snapshots__/validation.spec.ts.snap index 21366d0738..e969c62fcb 100644 --- a/lib/config/__snapshots__/validation.spec.ts.snap +++ b/lib/config/__snapshots__/validation.spec.ts.snap @@ -137,6 +137,19 @@ Array [ ] `; +exports[`config/validation validateConfig(config) errors if language or manager objects are nested 1`] = ` +Array [ + Object { + "message": "The \\"docker\\" object can only be configured at the top level of a config but was found inside \\"major.minor\\"", + "topic": "Configuration Error", + }, + Object { + "message": "The \\"gradle\\" object can only be configured at the top level of a config but was found inside \\"java\\"", + "topic": "Configuration Error", + }, +] +`; + exports[`config/validation validateConfig(config) errors if regexManager fields are missing 1`] = ` Array [ Object { diff --git a/lib/config/validation.spec.ts b/lib/config/validation.spec.ts index 452283349e..b7a3aa8ae7 100644 --- a/lib/config/validation.spec.ts +++ b/lib/config/validation.spec.ts @@ -484,6 +484,32 @@ describe('config/validation', () => { expect(warnings).toMatchSnapshot(); }); + it('errors if language or manager objects are nested', async () => { + const config = { + python: { + enabled: false, + }, + java: { + gradle: { + enabled: false, + }, + }, + major: { + minor: { + docker: { + automerge: true, + }, + }, + }, + } as never; + const { warnings, errors } = await configValidation.validateConfig( + config + ); + expect(errors).toHaveLength(2); + expect(warnings).toHaveLength(0); + expect(errors).toMatchSnapshot(); + }); + it('warns if hostType has the wrong parent', async () => { const config = { hostType: 'npm', diff --git a/lib/config/validation.ts b/lib/config/validation.ts index 100003ec52..633ce2c231 100644 --- a/lib/config/validation.ts +++ b/lib/config/validation.ts @@ -1,5 +1,5 @@ import is from '@sindresorhus/is'; -import { getManagerList } from '../manager'; +import { getLanguageList, getManagerList } from '../manager'; import { configRegexPredicate, isConfigRegex, regEx } from '../util/regex'; import * as template from '../util/template'; import { hasValidSchedule, hasValidTimezone } from '../workers/branch/schedule'; @@ -41,6 +41,8 @@ export function getParentName(parentPath: string): string { : '.'; } +const topLevelObjects = getLanguageList().concat(getManagerList()); + export async function validateConfig( config: RenovateConfig, isPreset?: boolean, @@ -115,6 +117,12 @@ export async function validateConfig( }); continue; // eslint-disable-line } + if (parentPath && topLevelObjects.includes(key)) { + errors.push({ + topic: 'Configuration Error', + message: `The "${key}" object can only be configured at the top level of a config but was found inside "${parentPath}"`, + }); + } if (key === 'fileMatch') { if (parentPath === undefined) { errors.push({ -- GitLab