From 11c05fc8373bee596ee36ec1fac6e257b57d9d56 Mon Sep 17 00:00:00 2001
From: Sergei Zharinov <zharinov@users.noreply.github.com>
Date: Sun, 25 Jun 2023 22:34:42 +0300
Subject: [PATCH] refactor: Default values for `GlobalConfig.get` (#22967)

---
 lib/config/decrypt.ts                                |  3 ++-
 lib/config/global.ts                                 | 11 ++++++++---
 lib/config/migrations/custom/extends-migration.ts    |  2 +-
 lib/config/presets/local/index.ts                    |  3 ++-
 lib/modules/datasource/npm/get.ts                    |  2 +-
 lib/modules/datasource/npm/npmrc.ts                  |  2 +-
 lib/modules/manager/azure-pipelines/extract.ts       |  3 ++-
 lib/modules/manager/git-submodules/extract.ts        |  2 +-
 lib/modules/manager/git-submodules/update.ts         |  2 +-
 lib/modules/manager/gitlabci-include/extract.ts      |  3 ++-
 lib/modules/manager/helmfile/extract.spec.ts         |  2 +-
 lib/modules/manager/npm/extract/pnpm.ts              |  2 +-
 lib/util/cache/package/decorator.ts                  |  2 +-
 lib/util/exec/containerbase.ts                       |  3 +--
 lib/util/exec/docker/index.ts                        |  7 ++++---
 lib/util/exec/hermit.ts                              |  5 ++---
 lib/util/exec/index.ts                               |  6 ++----
 lib/util/fs/index.ts                                 |  2 +-
 lib/util/git/index.ts                                |  5 ++---
 lib/util/json-writer/editor-config.ts                |  2 +-
 .../update/branch/execute-post-upgrade-commands.ts   | 12 +++++++-----
 21 files changed, 44 insertions(+), 37 deletions(-)

diff --git a/lib/config/decrypt.ts b/lib/config/decrypt.ts
index 5b48e76d64..80fb62b524 100644
--- a/lib/config/decrypt.ts
+++ b/lib/config/decrypt.ts
@@ -177,7 +177,8 @@ export async function decryptConfig(
 ): Promise<RenovateConfig> {
   logger.trace({ config }, 'decryptConfig()');
   const decryptedConfig = { ...config };
-  const { privateKey, privateKeyOld } = GlobalConfig.get();
+  const privateKey = GlobalConfig.get('privateKey');
+  const privateKeyOld = GlobalConfig.get('privateKeyOld');
   for (const [key, val] of Object.entries(config)) {
     if (key === 'encrypted' && is.object(val)) {
       logger.debug({ config: val }, 'Found encrypted config');
diff --git a/lib/config/global.ts b/lib/config/global.ts
index 666645f448..fca0001909 100644
--- a/lib/config/global.ts
+++ b/lib/config/global.ts
@@ -34,12 +34,17 @@ export class GlobalConfig {
 
   static get(): RepoGlobalConfig;
   static get<Key extends keyof RepoGlobalConfig>(
-    key?: Key
+    key: Key
   ): RepoGlobalConfig[Key];
   static get<Key extends keyof RepoGlobalConfig>(
-    key?: Key
+    key: Key,
+    defaultValue: Required<RepoGlobalConfig>[Key]
+  ): Required<RepoGlobalConfig>[Key];
+  static get<Key extends keyof RepoGlobalConfig>(
+    key?: Key,
+    defaultValue?: RepoGlobalConfig[Key]
   ): RepoGlobalConfig | RepoGlobalConfig[Key] {
-    return key ? GlobalConfig.config[key] : GlobalConfig.config;
+    return key ? GlobalConfig.config[key] ?? defaultValue : GlobalConfig.config;
   }
 
   static set(config: RenovateConfig | RepoGlobalConfig): RenovateConfig {
diff --git a/lib/config/migrations/custom/extends-migration.ts b/lib/config/migrations/custom/extends-migration.ts
index 64a444b917..92d3bc8d06 100644
--- a/lib/config/migrations/custom/extends-migration.ts
+++ b/lib/config/migrations/custom/extends-migration.ts
@@ -29,7 +29,7 @@ export class ExtendsMigration extends AbstractMigration {
   }
 
   private normalizePreset(preset: string): string | null {
-    const { migratePresets } = GlobalConfig.get();
+    const migratePresets = GlobalConfig.get('migratePresets');
 
     if (removedPresets[preset] !== undefined) {
       return removedPresets[preset];
diff --git a/lib/config/presets/local/index.ts b/lib/config/presets/local/index.ts
index 6f99390a6c..3ff13e03a7 100644
--- a/lib/config/presets/local/index.ts
+++ b/lib/config/presets/local/index.ts
@@ -33,7 +33,7 @@ export function getPreset({
   presetPath,
   tag,
 }: PresetConfig): Promise<Preset | undefined> {
-  const { platform, endpoint } = GlobalConfig.get();
+  const platform = GlobalConfig.get('platform');
   if (!platform) {
     throw new Error(`Missing platform config for local preset.`);
   }
@@ -43,6 +43,7 @@ export function getPreset({
       `The platform you're using ($platform) does not support local presets.`
     );
   }
+  const endpoint = GlobalConfig.get('endpoint');
   return resolver.getPresetFromEndpoint(
     repo,
     presetName,
diff --git a/lib/modules/datasource/npm/get.ts b/lib/modules/datasource/npm/get.ts
index 94109fcb1d..1ff4276dc0 100644
--- a/lib/modules/datasource/npm/get.ts
+++ b/lib/modules/datasource/npm/get.ts
@@ -104,7 +104,7 @@ export async function getDependency(
   const softExpireAt = DateTime.local()
     .plus({ minutes: cacheMinutes })
     .toISO()!;
-  let { cacheHardTtlMinutes } = GlobalConfig.get();
+  let cacheHardTtlMinutes = GlobalConfig.get('cacheHardTtlMinutes');
   if (!(is.number(cacheHardTtlMinutes) && cacheHardTtlMinutes > cacheMinutes)) {
     cacheHardTtlMinutes = cacheMinutes;
   }
diff --git a/lib/modules/datasource/npm/npmrc.ts b/lib/modules/datasource/npm/npmrc.ts
index 6b26a33827..fe1ea34446 100644
--- a/lib/modules/datasource/npm/npmrc.ts
+++ b/lib/modules/datasource/npm/npmrc.ts
@@ -131,7 +131,7 @@ export function setNpmrc(input?: string): void {
     npmrcRaw = input;
     logger.debug('Setting npmrc');
     npmrc = ini.parse(input.replace(regEx(/\\n/g), '\n'));
-    const { exposeAllEnv } = GlobalConfig.get();
+    const exposeAllEnv = GlobalConfig.get('exposeAllEnv');
     for (const [key, val] of Object.entries(npmrc)) {
       if (
         !exposeAllEnv &&
diff --git a/lib/modules/manager/azure-pipelines/extract.ts b/lib/modules/manager/azure-pipelines/extract.ts
index d05fb57437..4125141ee8 100644
--- a/lib/modules/manager/azure-pipelines/extract.ts
+++ b/lib/modules/manager/azure-pipelines/extract.ts
@@ -27,7 +27,8 @@ export function extractRepository(
     // same project, which is not currently accessible here. It could be deduced later by exposing
     // the repository URL to managers.
     // https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema/resources-repositories-repository?view=azure-pipelines#types
-    const { platform, endpoint } = GlobalConfig.get();
+    const platform = GlobalConfig.get('platform');
+    const endpoint = GlobalConfig.get('endpoint');
     if (platform === 'azure' && endpoint) {
       if (repository.name.includes('/')) {
         const [projectName, repoName] = repository.name.split('/');
diff --git a/lib/modules/manager/git-submodules/extract.ts b/lib/modules/manager/git-submodules/extract.ts
index 140f269702..468a89a747 100644
--- a/lib/modules/manager/git-submodules/extract.ts
+++ b/lib/modules/manager/git-submodules/extract.ts
@@ -95,7 +95,7 @@ export default async function extractPackageFile(
   packageFile: string,
   _config: ExtractConfig
 ): Promise<PackageFileContent | null> {
-  const { localDir } = GlobalConfig.get();
+  const localDir = GlobalConfig.get('localDir');
   const git = Git(localDir, simpleGitConfig());
   const gitModulesPath = upath.join(localDir, packageFile);
 
diff --git a/lib/modules/manager/git-submodules/update.ts b/lib/modules/manager/git-submodules/update.ts
index 613cc6c118..54df033376 100644
--- a/lib/modules/manager/git-submodules/update.ts
+++ b/lib/modules/manager/git-submodules/update.ts
@@ -8,7 +8,7 @@ export default async function updateDependency({
   fileContent,
   upgrade,
 }: UpdateDependencyConfig): Promise<string | null> {
-  const { localDir } = GlobalConfig.get();
+  const localDir = GlobalConfig.get('localDir');
   const git = Git(localDir);
   const submoduleGit = Git(upath.join(localDir, upgrade.depName));
 
diff --git a/lib/modules/manager/gitlabci-include/extract.ts b/lib/modules/manager/gitlabci-include/extract.ts
index 5e3bb02b2b..7d2011fca0 100644
--- a/lib/modules/manager/gitlabci-include/extract.ts
+++ b/lib/modules/manager/gitlabci-include/extract.ts
@@ -68,7 +68,8 @@ export function extractPackageFile(
   packageFile?: string
 ): PackageFileContent | null {
   const deps: PackageDependency[] = [];
-  const { platform, endpoint } = GlobalConfig.get();
+  const platform = GlobalConfig.get('platform');
+  const endpoint = GlobalConfig.get('endpoint');
   try {
     const doc = load(replaceReferenceTags(content), {
       json: true,
diff --git a/lib/modules/manager/helmfile/extract.spec.ts b/lib/modules/manager/helmfile/extract.spec.ts
index 479fad453f..10f9281a33 100644
--- a/lib/modules/manager/helmfile/extract.spec.ts
+++ b/lib/modules/manager/helmfile/extract.spec.ts
@@ -391,7 +391,7 @@ describe('modules/manager/helmfile/extract', () => {
 
     it('detects kustomize and respects relative paths', async () => {
       fs.localPathExists.mockImplementationOnce((path) => {
-        if (!path.startsWith(GlobalConfig.get('localDir') ?? '')) {
+        if (!path.startsWith(GlobalConfig.get('localDir', ''))) {
           throw new Error(FILE_ACCESS_VIOLATION_ERROR);
         }
         return Promise.resolve(true);
diff --git a/lib/modules/manager/npm/extract/pnpm.ts b/lib/modules/manager/npm/extract/pnpm.ts
index 2221ce8a03..fe0f0903b5 100644
--- a/lib/modules/manager/npm/extract/pnpm.ts
+++ b/lib/modules/manager/npm/extract/pnpm.ts
@@ -109,7 +109,7 @@ export async function detectPnpmWorkspaces(
     // check if package matches workspace filter
     if (!packagePathCache.has(workspaceYamlPath)) {
       const filters = await extractPnpmFilters(workspaceYamlPath);
-      const { localDir } = GlobalConfig.get();
+      const localDir = GlobalConfig.get('localDir');
       const packages = await findPackages(
         upath.dirname(upath.join(localDir, workspaceYamlPath)),
         {
diff --git a/lib/util/cache/package/decorator.ts b/lib/util/cache/package/decorator.ts
index e1bcd50bbb..560e44cb36 100644
--- a/lib/util/cache/package/decorator.ts
+++ b/lib/util/cache/package/decorator.ts
@@ -78,7 +78,7 @@ export function cache<T>({
 
     const softTtl = ttlMinutes;
 
-    const cacheHardTtlMinutes = GlobalConfig.get().cacheHardTtlMinutes ?? 0;
+    const cacheHardTtlMinutes = GlobalConfig.get('cacheHardTtlMinutes', 0);
     let hardTtl = softTtl;
     if (methodName === 'getReleases' || methodName === 'getDigest') {
       hardTtl = Math.max(softTtl, cacheHardTtlMinutes);
diff --git a/lib/util/exec/containerbase.ts b/lib/util/exec/containerbase.ts
index 165d362288..60ef028828 100644
--- a/lib/util/exec/containerbase.ts
+++ b/lib/util/exec/containerbase.ts
@@ -208,8 +208,7 @@ export function isContainerbase(): boolean {
 export function isDynamicInstall(
   toolConstraints?: Opt<ToolConstraint[]>
 ): boolean {
-  const { binarySource } = GlobalConfig.get();
-  if (binarySource !== 'install') {
+  if (GlobalConfig.get('binarySource') !== 'install') {
     return false;
   }
   if (!isContainerbase()) {
diff --git a/lib/util/exec/docker/index.ts b/lib/util/exec/docker/index.ts
index a2106a302b..4090231cde 100644
--- a/lib/util/exec/docker/index.ts
+++ b/lib/util/exec/docker/index.ts
@@ -164,13 +164,14 @@ export async function removeDockerContainer(
 }
 
 export async function removeDanglingContainers(): Promise<void> {
-  const { binarySource, dockerChildPrefix } = GlobalConfig.get();
-  if (binarySource !== 'docker') {
+  if (GlobalConfig.get('binarySource') !== 'docker') {
     return;
   }
 
   try {
-    const containerLabel = getContainerLabel(dockerChildPrefix);
+    const containerLabel = getContainerLabel(
+      GlobalConfig.get('dockerChildPrefix')
+    );
     const res = await rawExec(
       `docker ps --filter label=${containerLabel} -aq`,
       {
diff --git a/lib/util/exec/hermit.ts b/lib/util/exec/hermit.ts
index f28e053ad8..11d9ba023e 100644
--- a/lib/util/exec/hermit.ts
+++ b/lib/util/exec/hermit.ts
@@ -7,12 +7,11 @@ import { rawExec } from './common';
 import type { RawExecOptions } from './types';
 
 export function isHermit(): boolean {
-  const { binarySource } = GlobalConfig.get();
-  return binarySource === 'hermit';
+  return GlobalConfig.get('binarySource') === 'hermit';
 }
 
 export async function findHermitCwd(cwd: string): Promise<string> {
-  const relativeCwd = upath.relative(GlobalConfig.get('localDir') ?? '', cwd);
+  const relativeCwd = upath.relative(GlobalConfig.get('localDir', ''), cwd);
   const hermitFile = await findUpLocal('bin/hermit', relativeCwd);
 
   if (hermitFile === null) {
diff --git a/lib/util/exec/index.ts b/lib/util/exec/index.ts
index c3e802ae89..e54f2ef35c 100644
--- a/lib/util/exec/index.ts
+++ b/lib/util/exec/index.ts
@@ -91,8 +91,7 @@ function getRawExecOptions(opts: ExecOptions): RawExecOptions {
 }
 
 function isDocker(docker: Opt<DockerOptions>): docker is DockerOptions {
-  const { binarySource } = GlobalConfig.get();
-  return binarySource === 'docker' && !!docker;
+  return GlobalConfig.get('binarySource') === 'docker' && !!docker;
 }
 
 interface RawExecArguments {
@@ -170,8 +169,7 @@ export async function exec(
   opts: ExecOptions = {}
 ): Promise<ExecResult> {
   const { docker } = opts;
-  const dockerChildPrefix =
-    GlobalConfig.get('dockerChildPrefix') ?? 'renovate_';
+  const dockerChildPrefix = GlobalConfig.get('dockerChildPrefix', 'renovate_');
 
   const { rawCommands, rawOptions } = await prepareRawExec(cmd, opts);
   const useDocker = isDocker(docker);
diff --git a/lib/util/fs/index.ts b/lib/util/fs/index.ts
index 2a9b279397..aa67dee18e 100644
--- a/lib/util/fs/index.ts
+++ b/lib/util/fs/index.ts
@@ -206,7 +206,7 @@ export async function findUpLocal(
   fileName: string | string[],
   cwd: string
 ): Promise<string | null> {
-  const { localDir } = GlobalConfig.get();
+  const localDir = GlobalConfig.get('localDir');
   const absoluteCwd = upath.join(localDir, cwd);
   const normalizedAbsoluteCwd = upath.normalizeSafe(absoluteCwd);
   const res = await findUp(fileName, {
diff --git a/lib/util/git/index.ts b/lib/util/git/index.ts
index 0c857b7f55..44b04eaf50 100644
--- a/lib/util/git/index.ts
+++ b/lib/util/git/index.ts
@@ -238,8 +238,7 @@ export async function initRepo(args: StorageConfig): Promise<void> {
   config.ignoredAuthors = [];
   config.additionalBranches = [];
   config.branchIsModified = {};
-  const { localDir } = GlobalConfig.get();
-  git = simpleGit(localDir, simpleGitConfig()).env({
+  git = simpleGit(GlobalConfig.get('localDir'), simpleGitConfig()).env({
     ...process.env,
     LANG: 'C.UTF-8',
     LC_ALL: 'C.UTF-8',
@@ -479,7 +478,7 @@ export async function syncGit(): Promise<void> {
 // istanbul ignore next
 export async function getRepoStatus(path?: string): Promise<StatusResult> {
   if (is.string(path)) {
-    const { localDir } = GlobalConfig.get();
+    const localDir = GlobalConfig.get('localDir');
     const localPath = upath.resolve(localDir, path);
     if (!localPath.startsWith(upath.resolve(localDir))) {
       logger.warn(
diff --git a/lib/util/json-writer/editor-config.ts b/lib/util/json-writer/editor-config.ts
index f7e63eaed0..27beccd5d1 100644
--- a/lib/util/json-writer/editor-config.ts
+++ b/lib/util/json-writer/editor-config.ts
@@ -7,7 +7,7 @@ import type { IndentationType } from './indentation-type';
 
 export class EditorConfig {
   public static async getCodeFormat(fileName: string): Promise<CodeFormat> {
-    const { localDir } = GlobalConfig.get();
+    const localDir = GlobalConfig.get('localDir', 'asdf');
     try {
       const knownProps = await parse(upath.join(localDir, fileName));
       return {
diff --git a/lib/workers/repository/update/branch/execute-post-upgrade-commands.ts b/lib/workers/repository/update/branch/execute-post-upgrade-commands.ts
index be8b39f4ec..82803f36f4 100644
--- a/lib/workers/repository/update/branch/execute-post-upgrade-commands.ts
+++ b/lib/workers/repository/update/branch/execute-post-upgrade-commands.ts
@@ -29,8 +29,12 @@ export async function postUpgradeCommandsExecutor(
 ): Promise<PostUpgradeCommandsExecutionResult> {
   let updatedArtifacts = [...(config.updatedArtifacts ?? [])];
   const artifactErrors = [...(config.artifactErrors ?? [])];
-  const { allowedPostUpgradeCommands, allowPostUpgradeCommandTemplating } =
-    GlobalConfig.get();
+  const allowedPostUpgradeCommands = GlobalConfig.get(
+    'allowedPostUpgradeCommands'
+  );
+  const allowPostUpgradeCommandTemplating = GlobalConfig.get(
+    'allowPostUpgradeCommandTemplating'
+  );
 
   for (const upgrade of filteredUpgradeCommands) {
     addMeta({ dep: upgrade.depName });
@@ -158,8 +162,6 @@ export async function postUpgradeCommandsExecutor(
 export default async function executePostUpgradeCommands(
   config: BranchConfig
 ): Promise<PostUpgradeCommandsExecutionResult | null> {
-  const { allowedPostUpgradeCommands } = GlobalConfig.get();
-
   const hasChangedFiles =
     (config.updatedPackageFiles && config.updatedPackageFiles.length > 0) ||
     (config.updatedArtifacts && config.updatedArtifacts.length > 0);
@@ -167,7 +169,7 @@ export default async function executePostUpgradeCommands(
   if (
     /* Only run post-upgrade tasks if there are changes to package files... */
     !hasChangedFiles ||
-    is.emptyArray(allowedPostUpgradeCommands)
+    is.emptyArray(GlobalConfig.get('allowedPostUpgradeCommands'))
   ) {
     return null;
   }
-- 
GitLab