refactor(git): gitAuthor writing (#11535)

This commit is contained in:
Rhys Arkins 2021-09-02 12:50:53 +02:00 committed by GitHub
parent 37c507a042
commit 00b87dbfc9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 100 additions and 88 deletions

View file

@ -70,31 +70,4 @@ describe('platform/index', () => {
platform: PLATFORM_TYPE_BITBUCKET, 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();
});
}); });

View file

@ -1,10 +1,10 @@
import URL from 'url'; import URL from 'url';
import addrs from 'email-addresses';
import type { AllConfig } from '../config/types'; import type { AllConfig } from '../config/types';
import { PLATFORM_NOT_FOUND } from '../constants/error-messages'; import { PLATFORM_NOT_FOUND } from '../constants/error-messages';
import { logger } from '../logger'; import { logger } from '../logger';
import type { HostRule } from '../types'; import type { HostRule } from '../types';
import { setNoVerify, setPrivateKey } from '../util/git'; import { setNoVerify, setPrivateKey } from '../util/git';
import { parseGitAuthor } from '../util/git/author';
import * as hostRules from '../util/host-rules'; import * as hostRules from '../util/host-rules';
import platforms from './api'; import platforms from './api';
import type { Platform } from './types'; import type { Platform } from './types';
@ -39,48 +39,6 @@ export function setPlatformApi(name: string): void {
_platform = platforms.get(name); _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> { export async function initPlatform(config: AllConfig): Promise<AllConfig> {
setPrivateKey(config.gitPrivateKey); setPrivateKey(config.gitPrivateKey);
setNoVerify(config.gitNoVerify ?? []); setNoVerify(config.gitNoVerify ?? []);

View file

@ -1,15 +1,15 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // 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 { Object {
"address": "some[bot]@users.noreply.github.com", "address": "some[bot]@users.noreply.github.com",
"name": "some[bot]", "name": "some[bot]",
} }
`; `;
exports[`platform/index parses bot name and email 1`] = ` exports[`util/git/author parseGitAuthor parses bot name and email 1`] = `
Object { Object {
"address": "some[bot]@users.noreply.github.com", "address": "some[bot]@users.noreply.github.com",
"name": "some[bot]", "name": "some[bot]",

View file

@ -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();
});
});
});

44
lib/util/git/author.ts Normal file
View file

@ -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;
}

View file

@ -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({ export async function setUserRepoConfig({
branchPrefix, branchPrefix,
gitIgnoredAuthors, gitIgnoredAuthors,
@ -344,21 +365,7 @@ export async function syncGit(): Promise<void> {
} }
logger.warn({ err }, 'Cannot retrieve latest commit'); logger.warn({ err }, 'Cannot retrieve latest commit');
} }
try { await writeGitAuthor();
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);
}
config.currentBranch = config.currentBranch || (await getDefaultBranch(git)); config.currentBranch = config.currentBranch || (await getDefaultBranch(git));
if (config.branchPrefix) { if (config.branchPrefix) {
await setBranchPrefix(config.branchPrefix); await setBranchPrefix(config.branchPrefix);