From 9743f1ef7da2e1488002f83c2627d2cc49857874 Mon Sep 17 00:00:00 2001
From: Sergei Zharinov <zharinov@users.noreply.github.com>
Date: Thu, 6 Jan 2022 11:53:01 +0300
Subject: [PATCH] refactor: More strict null checks (#13387)

* refactor: More strict null checks

* Update lib/manager/terragrunt/providers.ts

Co-authored-by: Michael Kriese <michael.kriese@visualon.de>

* Fix coverage

Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
---
 lib/datasource/helm/common.ts           | 25 +++++++++++-------
 lib/manager/gradle/deep/build-gradle.ts |  2 +-
 lib/manager/gradle/deep/types.ts        |  8 +++---
 lib/manager/gradle/shallow/tokenizer.ts |  3 ++-
 lib/manager/terragrunt/providers.ts     | 19 +++++++-------
 lib/versioning/gradle/compare.ts        | 35 ++++++++++++++++---------
 tsconfig.strict.json                    | 10 +++++++
 7 files changed, 63 insertions(+), 39 deletions(-)

diff --git a/lib/datasource/helm/common.ts b/lib/datasource/helm/common.ts
index c183ad7c5e..b9797fcfa2 100644
--- a/lib/datasource/helm/common.ts
+++ b/lib/datasource/helm/common.ts
@@ -11,14 +11,19 @@ const githubRelease = regEx(
 
 export function findSourceUrl(release: HelmRelease): RepoSource {
   // it's a github release :)
-  let match = githubRelease.exec(release.urls[0]);
-  if (match) {
-    return { sourceUrl: match[1] };
+  const releaseMatch = githubRelease.exec(release.urls[0]);
+  if (releaseMatch) {
+    return { sourceUrl: releaseMatch[1] };
   }
 
-  match = githubUrl.exec(release.home);
-  if (chartRepo.test(match?.groups.repo)) {
-    return { sourceUrl: match.groups.url, sourceDirectory: match.groups.path };
+  if (release.home) {
+    const githubUrlMatch = githubUrl.exec(release.home);
+    if (githubUrlMatch?.groups && chartRepo.test(githubUrlMatch?.groups.repo)) {
+      return {
+        sourceUrl: githubUrlMatch.groups.url,
+        sourceDirectory: githubUrlMatch.groups.path,
+      };
+    }
   }
 
   if (!release.sources?.length) {
@@ -26,11 +31,11 @@ export function findSourceUrl(release: HelmRelease): RepoSource {
   }
 
   for (const url of release.sources) {
-    match = githubUrl.exec(url);
-    if (chartRepo.test(match?.groups.repo)) {
+    const githubUrlMatch = githubUrl.exec(url);
+    if (githubUrlMatch?.groups && chartRepo.test(githubUrlMatch?.groups.repo)) {
       return {
-        sourceUrl: match.groups.url,
-        sourceDirectory: match.groups.path,
+        sourceUrl: githubUrlMatch.groups.url,
+        sourceDirectory: githubUrlMatch.groups.path,
       };
     }
   }
diff --git a/lib/manager/gradle/deep/build-gradle.ts b/lib/manager/gradle/deep/build-gradle.ts
index e47cc2d814..181918af9f 100644
--- a/lib/manager/gradle/deep/build-gradle.ts
+++ b/lib/manager/gradle/deep/build-gradle.ts
@@ -314,7 +314,7 @@ function updateGlobalMapVariables(
   newValue: string
 ): string | null {
   let variable = variables[`${dependency.group}:${dependency.name}`];
-  if (variable) {
+  if (variable && dependency.version) {
     while (variable && variable.split('.').length > 0) {
       const regex = variableMapDefinitionFormatMatch(
         variable,
diff --git a/lib/manager/gradle/deep/types.ts b/lib/manager/gradle/deep/types.ts
index 00994f1429..ba4df121fc 100644
--- a/lib/manager/gradle/deep/types.ts
+++ b/lib/manager/gradle/deep/types.ts
@@ -5,11 +5,9 @@ export interface GradleDependency {
 }
 
 export interface UpdateFunction {
-  (
-    dependency: GradleDependency,
-    buildGradleContent: string,
-    newValue: string
-  ): string;
+  (dependency: GradleDependency, buildGradleContent: string, newValue: string):
+    | string
+    | null;
 }
 
 export interface GradleProject {
diff --git a/lib/manager/gradle/shallow/tokenizer.ts b/lib/manager/gradle/shallow/tokenizer.ts
index b599d41f9b..161c53b4c4 100644
--- a/lib/manager/gradle/shallow/tokenizer.ts
+++ b/lib/manager/gradle/shallow/tokenizer.ts
@@ -8,6 +8,7 @@ const escapedChars = {
   [TokenType.EscapedChar]: {
     match: escapedCharRegex,
     value: (x: string): string =>
+      /* istanbul ignore next */
       ({
         "\\'": "'",
         '\\"': '"',
@@ -17,7 +18,7 @@ const escapedChars = {
         '\\r': '\r',
         '\\t': '\t',
         '\\\\': '\\',
-      }[x]),
+      }[x] ?? x),
   },
 };
 
diff --git a/lib/manager/terragrunt/providers.ts b/lib/manager/terragrunt/providers.ts
index f44650ecee..83fc1046cf 100644
--- a/lib/manager/terragrunt/providers.ts
+++ b/lib/manager/terragrunt/providers.ts
@@ -8,7 +8,7 @@ export const sourceExtractionRegex = regEx(
   /^(?:(?<hostname>(?:[a-zA-Z0-9]+\.+)+[a-zA-Z0-9]+)\/)?(?:(?<namespace>[^/]+)\/)?(?<type>[^/]+)/
 );
 
-function extractBracesContent(content): number {
+function extractBracesContent(content: string): number {
   const stack = [];
   let i = 0;
   for (i; i < content.length; i += 1) {
@@ -32,12 +32,11 @@ export function extractTerragruntProvider(
   const lineNumber = startingLine;
   let line: string;
   const deps: PackageDependency[] = [];
-  const dep: PackageDependency = {
-    managerData: {
-      moduleName,
-      terragruntDependencyType: TerragruntDependencyTypes.terragrunt,
-    },
+  const managerData: Record<string, unknown> = {
+    moduleName,
+    terragruntDependencyType: TerragruntDependencyTypes.terragrunt,
   };
+  const dep: PackageDependency = { managerData };
   const teraformContent = lines
     .slice(lineNumber)
     .join('\n')
@@ -46,10 +45,10 @@ export function extractTerragruntProvider(
 
   for (let lineNo = 0; lineNo < teraformContent.length; lineNo += 1) {
     line = teraformContent[lineNo];
-    const kvMatch = keyValueExtractionRegex.exec(line);
-    if (kvMatch) {
-      dep.managerData.source = kvMatch.groups.value;
-      dep.managerData.sourceLine = lineNumber + lineNo;
+    const kvGroups = keyValueExtractionRegex.exec(line)?.groups;
+    if (kvGroups) {
+      managerData.source = kvGroups.value;
+      managerData.sourceLine = lineNumber + lineNo;
     }
   }
   deps.push(dep);
diff --git a/lib/versioning/gradle/compare.ts b/lib/versioning/gradle/compare.ts
index bd5c85bfb0..dc8c210e51 100644
--- a/lib/versioning/gradle/compare.ts
+++ b/lib/versioning/gradle/compare.ts
@@ -1,3 +1,4 @@
+import is from '@sindresorhus/is';
 import { regEx } from '../../util/regex';
 
 export enum TokenType {
@@ -10,7 +11,10 @@ type Token = {
   val: string | number;
 };
 
-function iterateChars(str: string, cb: (p: string, n: string) => void): void {
+function iterateChars(
+  str: string,
+  cb: (p: string | null, n: string | null) => void
+): void {
   let prev = null;
   let next = null;
   for (let i = 0; i < str.length; i += 1) {
@@ -41,7 +45,7 @@ function isTransition(prevChar: string, nextChar: string): boolean {
 }
 
 export function tokenize(versionStr: string): Token[] | null {
-  let result = [];
+  let result: Token[] | null = [];
   let currentVal = '';
 
   function yieldToken(): void {
@@ -142,7 +146,7 @@ function stringTokenCmp(left: string, right: string): number {
 
 function tokenCmp(left: Token | null, right: Token | null): number {
   if (left === null) {
-    if (right.type === TokenType.String) {
+    if (right?.type === TokenType.String) {
       return 1;
     }
     return -1;
@@ -174,8 +178,8 @@ function tokenCmp(left: Token | null, right: Token | null): number {
 }
 
 export function compare(left: string, right: string): number {
-  const leftTokens = tokenize(left);
-  const rightTokens = tokenize(right);
+  const leftTokens = tokenize(left) ?? [];
+  const rightTokens = tokenize(right) ?? [];
   const length = Math.max(leftTokens.length, rightTokens.length);
   for (let idx = 0; idx < length; idx += 1) {
     const leftToken = leftTokens[idx] || null;
@@ -252,23 +256,30 @@ export function parseMavenBasedRange(input: string): MavenBasedRange | null {
     return null;
   }
 
-  const match = mavenBasedRangeRegex.exec(input);
-  if (match) {
-    const { leftBoundStr, separator, rightBoundStr } = match.groups;
-    let { leftVal, rightVal } = match.groups;
+  const matchGroups = mavenBasedRangeRegex.exec(input)?.groups;
+  if (matchGroups) {
+    const { leftBoundStr, separator, rightBoundStr } = matchGroups;
+    let leftVal: string | null = matchGroups.leftVal;
+    let rightVal: string | null = matchGroups.rightVal;
     if (!leftVal) {
       leftVal = null;
     }
     if (!rightVal) {
       rightVal = null;
     }
-    const isVersionLeft = isVersion(leftVal);
-    const isVersionRight = isVersion(rightVal);
+    const isVersionLeft = is.string(leftVal) && isVersion(leftVal);
+    const isVersionRight = is.string(rightVal) && isVersion(rightVal);
     if (
       (leftVal === null || isVersionLeft) &&
       (rightVal === null || isVersionRight)
     ) {
-      if (isVersionLeft && isVersionRight && compare(leftVal, rightVal) === 1) {
+      if (
+        isVersionLeft &&
+        isVersionRight &&
+        leftVal &&
+        rightVal &&
+        compare(leftVal, rightVal) === 1
+      ) {
         return null;
       }
       const leftBound =
diff --git a/tsconfig.strict.json b/tsconfig.strict.json
index 2008407999..e1883cb404 100644
--- a/tsconfig.strict.json
+++ b/tsconfig.strict.json
@@ -15,6 +15,7 @@
     "lib/datasource/**/common.ts",
     "lib/datasource/**/types.ts",
     "lib/datasource/gitlab-tags/util.ts",
+    "lib/datasource/helm/common.ts",
     "lib/datasource/metadata.ts",
     "lib/datasource/sbt-plugin/util.ts",
     "lib/globals.d.ts",
@@ -24,14 +25,20 @@
     "lib/manager/ansible-galaxy/util.ts",
     "lib/manager/argocd/util.ts",
     "lib/manager/gitlabci/utils.ts",
+    "lib/manager/gradle/deep/build-gradle.ts",
+    "lib/manager/gradle/shallow/tokenizer.ts",
     "lib/manager/gradle/shallow/utils.ts",
     "lib/manager/helm-values/util.ts",
     "lib/manager/homebrew/util.ts",
+    "lib/manager/npm/extract/type.ts",
     "lib/manager/npm/post-update/rules.ts",
+    "lib/manager/pre-commit/parsing.ts",
+    "lib/manager/terragrunt/providers.ts",
     "lib/manager/terragrunt/util.ts",
     "lib/platform/**/types.ts",
     "lib/platform/github/graphql.ts",
     "lib/platform/utils/pr-body.ts",
+    "lib/platform/utils/read-only-issue-body.ts",
     "lib/proxy.ts",
     "lib/types/**/*.ts",
     "lib/util/cache/**/*.ts",
@@ -48,7 +55,9 @@
     "lib/util/http/types.ts",
     "lib/util/index.ts",
     "lib/util/json-writer/code-format.ts",
+    "lib/util/json-writer/editor-config.ts",
     "lib/util/json-writer/indentation-type.ts",
+    "lib/util/json-writer/json-writer.ts",
     "lib/util/markdown.ts",
     "lib/util/mask.spec.ts",
     "lib/util/mask.ts",
@@ -59,6 +68,7 @@
     "lib/util/sanitize.ts",
     "lib/util/split.ts",
     "lib/util/url.ts",
+    "lib/versioning/gradle/compare.ts",
     "lib/versioning/maven/**/*.ts",
     "lib/versioning/ruby/**/*.ts",
     "lib/versioning/semver-coerced/**/*.ts",
-- 
GitLab