From f243e3cf2229f6107c241bfea43f72062f055d5c Mon Sep 17 00:00:00 2001
From: Michael Kriese <michael.kriese@visualon.de>
Date: Thu, 12 Sep 2019 08:43:08 +0200
Subject: [PATCH] fix(config): fix cyclic imports (#4477)

---
 lib/config/index.ts   | 42 ++----------------------------------------
 lib/config/presets.ts |  7 +++----
 lib/config/utils.ts   | 41 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 46 insertions(+), 44 deletions(-)
 create mode 100644 lib/config/utils.ts

diff --git a/lib/config/index.ts b/lib/config/index.ts
index 6f228424fe..dc0b6d0614 100644
--- a/lib/config/index.ts
+++ b/lib/config/index.ts
@@ -4,14 +4,13 @@ import * as defaultsParser from './defaults';
 import * as fileParser from './file';
 import * as cliParser from './cli';
 import * as envParser from './env';
-
-// eslint-disable-next-line import/no-cycle
 import { resolveConfigPresets } from './presets';
 import { get, getLanguageList, getManagerList } from '../manager';
 import { RenovateConfig, RenovateConfigStage } from './common';
-import { clone } from '../util/clone';
+import { mergeChildConfig } from './utils';
 
 export * from './common';
+export { mergeChildConfig };
 
 export interface ManagerConfig extends RenovateConfig {
   language: string;
@@ -100,43 +99,6 @@ export async function parseConfigs(
   return config;
 }
 
-export function mergeChildConfig<T extends RenovateConfig = RenovateConfig>(
-  parent: T,
-  child: RenovateConfig
-): T {
-  logger.trace({ parent, child }, `mergeChildConfig`);
-  if (!child) {
-    return parent;
-  }
-  const parentConfig = clone(parent);
-  const childConfig = clone(child);
-  const config: Record<string, any> = { ...parentConfig, ...childConfig };
-  for (const option of definitions.getOptions()) {
-    if (
-      option.mergeable &&
-      childConfig[option.name] &&
-      parentConfig[option.name]
-    ) {
-      logger.trace(`mergeable option: ${option.name}`);
-      if (option.type === 'array') {
-        config[option.name] = (parentConfig[option.name] || []).concat(
-          config[option.name] || []
-        );
-      } else {
-        config[option.name] = mergeChildConfig(
-          parentConfig[option.name],
-          childConfig[option.name]
-        );
-      }
-      logger.trace(
-        { result: config[option.name] },
-        `Merged config.${option.name}`
-      );
-    }
-  }
-  return Object.assign(config, config.force);
-}
-
 export function filterConfig(
   inputConfig: RenovateConfig,
   targetStage: RenovateConfigStage
diff --git a/lib/config/presets.ts b/lib/config/presets.ts
index 59cb1037a9..95933fa9d6 100644
--- a/lib/config/presets.ts
+++ b/lib/config/presets.ts
@@ -1,13 +1,12 @@
 import is from '@sindresorhus/is';
 import { logger } from '../logger';
-// eslint-disable-next-line import/no-cycle
-import * as configParser from './index';
 import * as massage from './massage';
 import * as migration from './migration';
 import * as github from '../datasource/github';
 import * as npm from '../datasource/npm';
 import * as gitlab from '../datasource/gitlab';
 import { RenovateConfig } from './common';
+import { mergeChildConfig } from './utils';
 
 const datasources = {
   github,
@@ -81,13 +80,13 @@ export async function resolveConfigPresets(
         ) {
           delete presetConfig.description;
         }
-        config = configParser.mergeChildConfig(config, presetConfig);
+        config = mergeChildConfig(config, presetConfig);
       }
     }
   }
   logger.trace({ config }, `Post-preset resolve config`);
   // Now assign "regular" config on top
-  config = configParser.mergeChildConfig(config, inputConfig);
+  config = mergeChildConfig(config, inputConfig);
   delete config.extends;
   delete config.ignorePresets;
   logger.trace({ config }, `Post-merge resolve config`);
diff --git a/lib/config/utils.ts b/lib/config/utils.ts
new file mode 100644
index 0000000000..659185a290
--- /dev/null
+++ b/lib/config/utils.ts
@@ -0,0 +1,41 @@
+import { RenovateConfig } from './common';
+import { logger } from '../logger';
+import { clone } from '../util/clone';
+import * as definitions from './definitions';
+
+export function mergeChildConfig<T extends RenovateConfig = RenovateConfig>(
+  parent: T,
+  child: RenovateConfig
+): T {
+  logger.trace({ parent, child }, `mergeChildConfig`);
+  if (!child) {
+    return parent;
+  }
+  const parentConfig = clone(parent);
+  const childConfig = clone(child);
+  const config: Record<string, any> = { ...parentConfig, ...childConfig };
+  for (const option of definitions.getOptions()) {
+    if (
+      option.mergeable &&
+      childConfig[option.name] &&
+      parentConfig[option.name]
+    ) {
+      logger.trace(`mergeable option: ${option.name}`);
+      if (option.type === 'array') {
+        config[option.name] = parentConfig[option.name].concat(
+          config[option.name]
+        );
+      } else {
+        config[option.name] = mergeChildConfig(
+          parentConfig[option.name],
+          childConfig[option.name]
+        );
+      }
+      logger.trace(
+        { result: config[option.name] },
+        `Merged config.${option.name}`
+      );
+    }
+  }
+  return Object.assign(config, config.force);
+}
-- 
GitLab