Skip to content

Commit 25fc2c3

Browse files
authored
feat(plugin-git): improve contributors info parsing (#405)
1 parent 9fdeaaa commit 25fc2c3

File tree

4 files changed

+50
-20
lines changed

4 files changed

+50
-20
lines changed

plugins/development/plugin-git/src/client/components/GitChangelog.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -80,15 +80,15 @@ export const GitChangelog = defineComponent({
8080
h(
8181
item.commitUrl ? 'a' : 'span',
8282
{
83-
class: 'link hash',
83+
class: 'vp-changelog-hash',
8484
href: item.commitUrl,
8585
target: '_blank',
8686
rel: 'noreferrer',
8787
},
8888
[h('code', item.hash.slice(0, 5))],
8989
),
90-
h('span', { class: 'divider' }, '-'),
91-
h('span', { class: 'message', innerHTML: item.message }),
90+
h('span', { class: 'vp-changelog-divider' }, '-'),
91+
h('span', { class: 'vp-changelog-message', innerHTML: item.message }),
9292
h('span', { 'class': 'vp-changelog-date', 'data-allow-mismatch': '' }, [
9393
locale.value.timeOn || 'on',
9494
' ',

plugins/development/plugin-git/src/node/resolveContributors.ts

+31-17
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { GitContributorInfo, KnownGitProvider } from '../shared/index.js'
22
import type { ContributorsOptions } from './options.js'
33
import type { MergedRawCommit } from './typings.js'
44
import {
5+
checkGithubUsername,
56
digestSHA256,
67
getContributorInfo,
78
getUserNameWithNoreplyEmail,
@@ -21,41 +22,48 @@ export const getRawContributors = (
2122
...commit.coAuthors,
2223
]
2324

24-
for (const { name: author, email } of authors) {
25+
for (const { name, email } of authors) {
26+
const usernameWithNoreplyEmail = getUserNameWithNoreplyEmail(email)
2527
const config = getContributorInfo(
26-
getUserNameWithNoreplyEmail(email) ?? author,
28+
usernameWithNoreplyEmail ?? name,
2729
options.info,
2830
)
29-
const username = config?.username ?? author
30-
const name = config?.name ?? username
3131

32-
const contributor = contributors.get(name + email)
32+
// Only trust the username from `info` and `noreply email`.
33+
const username = config?.username ?? usernameWithNoreplyEmail
34+
35+
const contributor = contributors.get(username ?? name)
3336

3437
if (contributor) {
3538
contributor.commits++
3639
} else {
3740
const item: GitContributorInfo = {
38-
name,
39-
username,
41+
name: config?.name ?? username ?? name,
42+
// if `username` not found, check if `name` is a valid github username
43+
username:
44+
username ??
45+
(gitProvider === 'github' && checkGithubUsername(name) ? name : ''),
4046
email,
4147
commits: 1,
4248
}
4349

4450
if (options.avatar)
4551
item.avatar =
4652
config?.avatar ??
47-
options.avatarPattern?.replace(':username', username) ??
48-
(gitProvider === 'github'
49-
? `https://avatars.githubusercontent.com/${username}?v=4`
50-
: `https://gravatar.com/avatar/${digestSHA256(email || username)}?d=retro`)
53+
(item.username
54+
? options.avatarPattern?.replace(':username', item.username)
55+
: null) ??
56+
(item.username
57+
? `https://avatars.githubusercontent.com/${item.username}?v=4`
58+
: `https://gravatar.com/avatar/${digestSHA256(email)}?d=retro`)
5159

5260
const url =
53-
(config?.url ?? gitProvider === 'github')
54-
? `https://github.com/${username}`
55-
: undefined
61+
config?.url ??
62+
(item.username ? `https://github.com/${item.username}` : undefined)
63+
5664
if (url) item.url = url
5765

58-
contributors.set(name + email, item)
66+
contributors.set(username ?? name, item)
5967
}
6068
}
6169
}
@@ -87,7 +95,13 @@ export const resolveContributors = (
8795

8896
if (options.info?.length && extraContributors.length) {
8997
for (const extraContributor of extraContributors) {
90-
if (contributors.every((item) => item.name !== extraContributor)) {
98+
if (
99+
contributors.every(
100+
(item) =>
101+
item.username !== extraContributor &&
102+
item.name !== extraContributor,
103+
)
104+
) {
91105
const contributorInfo = getContributorInfo(
92106
extraContributor,
93107
options.info,
@@ -97,7 +111,7 @@ export const resolveContributors = (
97111

98112
const result: GitContributorInfo = {
99113
name: contributorInfo.name ?? extraContributor,
100-
username: contributorInfo.name ?? extraContributor,
114+
username: contributorInfo.username,
101115
email: '',
102116
commits: 0,
103117
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* Check if the username is a valid github username
3+
*
4+
* - length <= 39
5+
* - starts with a letter
6+
* - contains only letters, numbers, and hyphens
7+
* - does not start or end with a hyphen
8+
* - does not contain consecutive hyphens
9+
*/
10+
export const checkGithubUsername = (username: string): boolean => {
11+
if (username.length > 39) return false
12+
if (username.startsWith('-') || username.endsWith('-')) return false
13+
14+
return /^[a-z\d](?:[a-z\d]|-(?=[a-z\d]))*$/i.test(username)
15+
}

plugins/development/plugin-git/src/node/utils/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ export * from './getContributorInfo.js'
55
export * from './getUserNameWithNoreplyEmail.js'
66
export * from './inferGitProvider.js'
77
export * from './injectGitOptions.js'
8+
export * from './checkGithubUsername.js'

0 commit comments

Comments
 (0)