Skip to content

Commit

Permalink
Merge pull request #173 from rkotze/refactor-message-format
Browse files Browse the repository at this point in the history
Refactor to have a public message format function
  • Loading branch information
rkotze authored Dec 5, 2024
2 parents 51808b4 + edf43df commit adc5086
Show file tree
Hide file tree
Showing 10 changed files with 128 additions and 25 deletions.
8 changes: 6 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

Follows [Semantic Versioning](https://semver.org/).

## git-mob-core Next

## git-mob 4.0.0

### Added
Expand All @@ -17,6 +15,12 @@ Follows [Semantic Versioning](https://semver.org/).
- `git delete-coauthor`
- `git edit-coauthor`

## git-mob-core 0.10.0

### Added

- Expose a public function to format Git message co-author trailers in one place. For consumers like Git Mob VS Code extension.

## git-mob-core 0.9.3

### Added
Expand Down
4 changes: 3 additions & 1 deletion packages/git-mob-core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ createCoAuthorsFile(authors: Author[]): <Promise<boolean>>
updateGitTemplate(selectedAuthors?: Author[]): void
solo(): <Promise<void>>
setCoAuthors(keys: string[]): <Promise<Author[]>>
messageFormatter(txt: string, authors: Author[]): string

// Read actions
getAllAuthors(): <Promise<Author[]>>
Expand Down Expand Up @@ -66,7 +67,7 @@ gitConfig = {

### Author class

Main class for Author data exchange between function.
Do not change the structure of the class.

```TS
class Author;
Expand All @@ -75,6 +76,7 @@ class Author;
Author.key: string
Author.name: string
Author.email: string
Author.trailer: AuthorTrailers // defaults to AuthorTrailers.CoAuthorBy

//Methods
Author.format(): string
Expand Down
13 changes: 11 additions & 2 deletions packages/git-mob-core/src/git-mob-api/author.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
import { AuthorTrailers } from './git-message/message-formatter';

export class Author {
key: string;
name: string;
email: string;
trailer: AuthorTrailers;

constructor(key: string, name: string, email: string) {
constructor(
key: string,
name: string,
email: string,
trailer: AuthorTrailers = AuthorTrailers.CoAuthorBy
) {
this.key = key;
this.name = name;
this.email = email;
this.trailer = trailer;
}

format() {
return `Co-authored-by: ${this.toString()}`;
return `${this.trailer} ${this.toString()}`;
}

toString() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { type BasicResponse, httpFetch } from '../fetch/http-fetch';
import { AuthorTrailers } from '../git-message/message-formatter';
import { fetchGitHubAuthors, searchGitHubAuthors } from './fetch-github-authors';

jest.mock('../fetch/http-fetch');
Expand Down Expand Up @@ -68,6 +69,7 @@ test('Query for one GitHub user and return in AuthorList', async () => {
key: 'dideler',
name: 'Dennis',
email: '[email protected]',
trailer: AuthorTrailers.CoAuthorBy,
},
]);
});
Expand All @@ -87,11 +89,13 @@ test('Query for two GitHub users and build AuthorList', async () => {
key: 'dideler',
name: 'Dennis',
email: '[email protected]',
trailer: AuthorTrailers.CoAuthorBy,
},
{
key: 'rkotze',
name: 'Richard Kotze',
email: '[email protected]',
trailer: AuthorTrailers.CoAuthorBy,
},
]);
});
Expand All @@ -112,6 +116,7 @@ test('Handle GitHub user with no name', async () => {
key: 'kotze',
name: 'kotze',
email: '[email protected]',
trailer: AuthorTrailers.CoAuthorBy,
},
]);
});
Expand Down Expand Up @@ -159,11 +164,13 @@ test('Search for users by name', async () => {
key: 'dideler',
name: 'Dennis',
email: '[email protected]',
trailer: AuthorTrailers.CoAuthorBy,
},
{
key: 'rkotze',
name: 'Richard Kotze',
email: '[email protected]',
trailer: AuthorTrailers.CoAuthorBy,
},
]);
});
12 changes: 7 additions & 5 deletions packages/git-mob-core/src/git-mob-api/git-message/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import { EOL } from 'node:os';
import { jest } from '@jest/globals';
import { readFile, writeFile } from 'node:fs/promises';
import { Author } from '../author.js';
import { gitMessage } from './index.js';

jest.mock('node:fs/promises');

test('Append co-authors to .gitmessage append file mock', async () => {
const appendMock = jest.fn(async () => undefined);
const message = gitMessage('.git/.gitmessage', appendMock);
const message = gitMessage('.fake/.gitmessage');
await message.writeCoAuthors([
new Author('jd', 'Jane Doe', '[email protected]'),
new Author('fb', 'Frances Bar', '[email protected]'),
]);

expect(appendMock).toHaveBeenCalledTimes(1);
expect(appendMock).toHaveBeenCalledWith(
expect(readFile).toHaveBeenCalledTimes(1);
expect(writeFile).toHaveBeenCalledTimes(1);
expect(writeFile).toHaveBeenCalledWith(
expect.stringContaining('.gitmessage'),
[
EOL,
Expand Down
19 changes: 5 additions & 14 deletions packages/git-mob-core/src/git-mob-api/git-message/index.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import { readFile, writeFile } from 'node:fs/promises';
import { EOL } from 'node:os';
import { type Author } from '../author';
import { messageFormatter } from './message-formatter';

function fileExists(error: NodeJS.ErrnoException) {
return error.code !== 'ENOENT';
}

async function append(messagePath: string, newAuthors: string): Promise<void> {
async function append(messagePath: string, newAuthors: Author[]): Promise<void> {
const data = await read(messagePath);

let result = newAuthors;
if (data) {
result = data.replaceAll(/(\r\n|\r|\n){1,2}Co-authored-by.*/g, '') + newAuthors;
}
const result = messageFormatter(data || '', newAuthors);

await writeFile(messagePath, result);
}
Expand All @@ -27,10 +24,6 @@ async function read(messagePath: string) {
}
}

function formatCoAuthorList(coAuthorList: Author[]): string {
return coAuthorList.map(coAuthor => coAuthor.format()).join(EOL);
}

function gitMessage(
messagePath: string,
appendFilePromise?: () => Promise<void>,
Expand All @@ -41,15 +34,13 @@ function gitMessage(

return {
writeCoAuthors: async (coAuthorList: Author[]) => {
const coAuthorText = formatCoAuthorList(coAuthorList);

await appendPromise(messagePath, EOL + EOL + coAuthorText);
await appendPromise(messagePath, coAuthorList);
},
readCoAuthors: async () => {
return readPromise(messagePath);
},
removeCoAuthors: async () => {
return appendPromise(messagePath, '');
return appendPromise(messagePath, []);
},
};
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { EOL } from 'node:os';
import { Author } from '../author';
import { messageFormatter } from './message-formatter';

test('MessageFormatter: No authors to append to git message', () => {
const txt = `git message`;
const message = messageFormatter(txt, []);

expect(message).toBe(txt);
});

test('MessageFormatter: Append co-authors to git message', () => {
const txt = `git message`;
const message = messageFormatter(txt, [
new Author('jd', 'Jane Doe', '[email protected]'),
new Author('fb', 'Frances Bar', '[email protected]'),
]);

expect(message).toBe(
[
txt,
EOL,
EOL,
'Co-authored-by: Jane Doe <[email protected]>',
EOL,
'Co-authored-by: Frances Bar <[email protected]>',
].join('')
);
});

test('MessageFormatter: Replace co-author in the git message', () => {
const firstLine = 'git message';
const txt = [
firstLine,
EOL,
EOL,
'Co-authored-by: Jane Doe <[email protected]>',
].join('');
const message = messageFormatter(txt, [
new Author('fb', 'Frances Bar', '[email protected]'),
]);

expect(message).toBe(
[
firstLine,
EOL,
EOL,
'Co-authored-by: Frances Bar <[email protected]>',
].join('')
);
});

test('MessageFormatter: Replace co-author in the git message with no line break', () => {
const firstLine = 'git message';
const txt = [firstLine, 'Co-authored-by: Jane Doe <[email protected]>'].join('');
const message = messageFormatter(txt, [
new Author('fb', 'Frances Bar', '[email protected]'),
]);

expect(message).toBe(
[
firstLine,
EOL,
EOL,
'Co-authored-by: Frances Bar <[email protected]>',
].join('')
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { EOL } from 'node:os';
import { type Author } from '../author';

export enum AuthorTrailers {
CoAuthorBy = 'Co-authored-by:',
}

export function messageFormatter(txt: string, authors: Author[]): string {
const trailers = AuthorTrailers.CoAuthorBy;
const regex = new RegExp(`(\r\n|\r|\n){0,2}(${trailers}).*`, 'g');
const message = txt.replaceAll(regex, '');

if (authors && authors.length > 0) {
const authorTrailerTxt = authors.map(author => author.format()).join(EOL);
return [message, EOL, EOL, authorTrailerTxt].join('');
}

return message;
}
1 change: 1 addition & 0 deletions packages/git-mob-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,4 @@ export {
} from './git-mob-api/git-authors/fetch-github-authors.js';
export { getConfig, updateConfig } from './config-manager.js';
export { Author } from './git-mob-api/author.js';
export { messageFormatter } from './git-mob-api/git-message/message-formatter.js';
2 changes: 1 addition & 1 deletion packages/git-mob/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ $ git add-coauthor bb "Barry Butterworth" [email protected]
### Suggest co-authors
Suggest co-authors to save based on contributors to the current Git repository.
Suggest co-authors from contributors in local Git repository and add to `.git-coauthors` file.
Optional author filter by name or email.
Expand Down

0 comments on commit adc5086

Please sign in to comment.