From 00b87dbfc95e6aff3577947081ad25ad8c1cdc3a Mon Sep 17 00:00:00 2001
From: Rhys Arkins <rhys@arkins.net>
Date: Thu, 2 Sep 2021 12:50:53 +0200
Subject: [PATCH] refactor(git): gitAuthor writing (#11535)

---
 lib/platform/index.spec.ts                    | 27 ------------
 lib/platform/index.ts                         | 44 +------------------
 .../git/__snapshots__/author.spec.ts.snap}    |  6 +--
 lib/util/git/author.spec.ts                   | 30 +++++++++++++
 lib/util/git/author.ts                        | 44 +++++++++++++++++++
 lib/util/git/index.ts                         | 37 +++++++++-------
 6 files changed, 100 insertions(+), 88 deletions(-)
 rename lib/{platform/__snapshots__/index.spec.ts.snap => util/git/__snapshots__/author.spec.ts.snap} (50%)
 create mode 100644 lib/util/git/author.spec.ts
 create mode 100644 lib/util/git/author.ts

diff --git a/lib/platform/index.spec.ts b/lib/platform/index.spec.ts
index 54fd78d40a..1a29be4909 100644
--- a/lib/platform/index.spec.ts
+++ b/lib/platform/index.spec.ts
@@ -70,31 +70,4 @@ describe('platform/index', () => {
       platform: PLATFORM_TYPE_BITBUCKET,
     });
   });
-
-  it('returns null if empty email given', () => {
-    expect(platform.parseGitAuthor(undefined)).toBeNull();
-  });
-  it('parses bot email', () => {
-    // FIXME: explicit assert condition
-    expect(
-      platform.parseGitAuthor('some[bot]@users.noreply.github.com')
-    ).toMatchSnapshot();
-  });
-  it('parses bot name and email', () => {
-    // FIXME: explicit assert condition
-    expect(
-      platform.parseGitAuthor(
-        '"some[bot]" <some[bot]@users.noreply.github.com>'
-      )
-    ).toMatchSnapshot();
-  });
-  it('escapes names', () => {
-    // FIXME: explicit assert condition
-    expect(
-      platform.parseGitAuthor('name [what] <name@what.com>').name
-    ).toMatchSnapshot();
-  });
-  it('gives up', () => {
-    expect(platform.parseGitAuthor('a.b.c')).toBeNull();
-  });
 });
diff --git a/lib/platform/index.ts b/lib/platform/index.ts
index 8268aecdc7..5436884fda 100644
--- a/lib/platform/index.ts
+++ b/lib/platform/index.ts
@@ -1,10 +1,10 @@
 import URL from 'url';
-import addrs from 'email-addresses';
 import type { AllConfig } from '../config/types';
 import { PLATFORM_NOT_FOUND } from '../constants/error-messages';
 import { logger } from '../logger';
 import type { HostRule } from '../types';
 import { setNoVerify, setPrivateKey } from '../util/git';
+import { parseGitAuthor } from '../util/git/author';
 import * as hostRules from '../util/host-rules';
 import platforms from './api';
 import type { Platform } from './types';
@@ -39,48 +39,6 @@ export function setPlatformApi(name: string): void {
   _platform = platforms.get(name);
 }
 
-interface GitAuthor {
-  name?: string;
-  address?: string;
-}
-
-export function parseGitAuthor(input: string): GitAuthor | null {
-  let result: GitAuthor = null;
-  if (!input) {
-    return null;
-  }
-  try {
-    result = addrs.parseOneAddress(input);
-    if (result) {
-      return result;
-    }
-    if (input.includes('[bot]@')) {
-      // invalid github app/bot addresses
-      const parsed = addrs.parseOneAddress(
-        input.replace('[bot]@', '@')
-      ) as addrs.ParsedMailbox;
-      if (parsed?.address) {
-        result = {
-          name: parsed.name || input.replace(/@.*/, ''),
-          address: parsed.address.replace('@', '[bot]@'),
-        };
-        return result;
-      }
-    }
-    if (input.includes('<') && input.includes('>')) {
-      // try wrapping the name part in quotations
-      result = addrs.parseOneAddress('"' + input.replace(/(\s?<)/, '"$1'));
-      if (result) {
-        return result;
-      }
-    }
-  } catch (err) /* istanbul ignore next */ {
-    logger.error({ err }, 'Unknown error parsing gitAuthor');
-  }
-  // give up
-  return null;
-}
-
 export async function initPlatform(config: AllConfig): Promise<AllConfig> {
   setPrivateKey(config.gitPrivateKey);
   setNoVerify(config.gitNoVerify ?? []);
diff --git a/lib/platform/__snapshots__/index.spec.ts.snap b/lib/util/git/__snapshots__/author.spec.ts.snap
similarity index 50%
rename from lib/platform/__snapshots__/index.spec.ts.snap
rename to lib/util/git/__snapshots__/author.spec.ts.snap
index 3217d7d515..844b8e8eb7 100644
--- a/lib/platform/__snapshots__/index.spec.ts.snap
+++ b/lib/util/git/__snapshots__/author.spec.ts.snap
@@ -1,15 +1,15 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`platform/index escapes names 1`] = `"name [what]"`;
+exports[`util/git/author parseGitAuthor escapes names 1`] = `"name [what]"`;
 
-exports[`platform/index parses bot email 1`] = `
+exports[`util/git/author parseGitAuthor parses bot email 1`] = `
 Object {
   "address": "some[bot]@users.noreply.github.com",
   "name": "some[bot]",
 }
 `;
 
-exports[`platform/index parses bot name and email 1`] = `
+exports[`util/git/author parseGitAuthor parses bot name and email 1`] = `
 Object {
   "address": "some[bot]@users.noreply.github.com",
   "name": "some[bot]",
diff --git a/lib/util/git/author.spec.ts b/lib/util/git/author.spec.ts
new file mode 100644
index 0000000000..cd80f6a393
--- /dev/null
+++ b/lib/util/git/author.spec.ts
@@ -0,0 +1,30 @@
+import { parseGitAuthor } from './author';
+
+describe('util/git/author', () => {
+  describe('parseGitAuthor', () => {
+    it('returns null if empty email given', () => {
+      expect(parseGitAuthor(undefined)).toBeNull();
+    });
+    it('parses bot email', () => {
+      // FIXME: explicit assert condition
+      expect(
+        parseGitAuthor('some[bot]@users.noreply.github.com')
+      ).toMatchSnapshot();
+    });
+    it('parses bot name and email', () => {
+      // FIXME: explicit assert condition
+      expect(
+        parseGitAuthor('"some[bot]" <some[bot]@users.noreply.github.com>')
+      ).toMatchSnapshot();
+    });
+    it('escapes names', () => {
+      // FIXME: explicit assert condition
+      expect(
+        parseGitAuthor('name [what] <name@what.com>').name
+      ).toMatchSnapshot();
+    });
+    it('gives up', () => {
+      expect(parseGitAuthor('a.b.c')).toBeNull();
+    });
+  });
+});
diff --git a/lib/util/git/author.ts b/lib/util/git/author.ts
new file mode 100644
index 0000000000..bb149346af
--- /dev/null
+++ b/lib/util/git/author.ts
@@ -0,0 +1,44 @@
+import addrs from 'email-addresses';
+import { logger } from '../../logger';
+
+export interface GitAuthor {
+  name?: string;
+  address?: string;
+}
+
+export function parseGitAuthor(input: string): GitAuthor | null {
+  let result: GitAuthor = null;
+  if (!input) {
+    return null;
+  }
+  try {
+    result = addrs.parseOneAddress(input);
+    if (result) {
+      return result;
+    }
+    if (input.includes('[bot]@')) {
+      // invalid github app/bot addresses
+      const parsed = addrs.parseOneAddress(
+        input.replace('[bot]@', '@')
+      ) as addrs.ParsedMailbox;
+      if (parsed?.address) {
+        result = {
+          name: parsed.name || input.replace(/@.*/, ''),
+          address: parsed.address.replace('@', '[bot]@'),
+        };
+        return result;
+      }
+    }
+    if (input.includes('<') && input.includes('>')) {
+      // try wrapping the name part in quotations
+      result = addrs.parseOneAddress('"' + input.replace(/(\s?<)/, '"$1'));
+      if (result) {
+        return result;
+      }
+    }
+  } catch (err) /* istanbul ignore next */ {
+    logger.debug({ err }, 'Unknown error parsing gitAuthor');
+  }
+  // give up
+  return null;
+}
diff --git a/lib/util/git/index.ts b/lib/util/git/index.ts
index e24c808412..5194853076 100644
--- a/lib/util/git/index.ts
+++ b/lib/util/git/index.ts
@@ -234,6 +234,27 @@ async function setBranchPrefix(branchPrefix: string): Promise<void> {
   }
 }
 
+export async function writeGitAuthor(): Promise<void> {
+  const { gitAuthorName, gitAuthorEmail } = config;
+  try {
+    if (gitAuthorName) {
+      logger.debug({ gitAuthorName }, 'Setting git author name');
+      await git.addConfig('user.name', gitAuthorName);
+    }
+    if (gitAuthorEmail) {
+      logger.debug({ gitAuthorEmail }, 'Setting git author email');
+      await git.addConfig('user.email', gitAuthorEmail);
+    }
+  } catch (err) /* istanbul ignore next */ {
+    checkForPlatformFailure(err);
+    logger.debug(
+      { err, gitAuthorName, gitAuthorEmail },
+      'Error setting git author config'
+    );
+    throw new Error(TEMPORARY_ERROR);
+  }
+}
+
 export async function setUserRepoConfig({
   branchPrefix,
   gitIgnoredAuthors,
@@ -344,21 +365,7 @@ export async function syncGit(): Promise<void> {
     }
     logger.warn({ err }, 'Cannot retrieve latest commit');
   }
-  try {
-    const { gitAuthorName, gitAuthorEmail } = config;
-    if (gitAuthorName) {
-      logger.debug({ gitAuthorName }, 'Setting git author name');
-      await git.addConfig('user.name', gitAuthorName);
-    }
-    if (gitAuthorEmail) {
-      logger.debug({ gitAuthorEmail }, 'Setting git author email');
-      await git.addConfig('user.email', gitAuthorEmail);
-    }
-  } catch (err) /* istanbul ignore next */ {
-    checkForPlatformFailure(err);
-    logger.debug({ err }, 'Error setting git author config');
-    throw new Error(TEMPORARY_ERROR);
-  }
+  await writeGitAuthor();
   config.currentBranch = config.currentBranch || (await getDefaultBranch(git));
   if (config.branchPrefix) {
     await setBranchPrefix(config.branchPrefix);
-- 
GitLab