Skip to content

Commit a9b9028

Browse files
authored
feat(contribution-types): support plural forms, multi word types and any case (#53)
* feat: support plurals * feat: support multi words, ignore case * test: tweaks * pr: lint * no need to lump
1 parent e241b5d commit a9b9028

File tree

3 files changed

+152
-47
lines changed

3 files changed

+152
-47
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ A bot for automatically adding all-contributors.
1818
### Adding contributions
1919
Comment on Issue or Pull Request with text:
2020
```
21-
@all-contributors please add @jakebolam for infrastructure, test and code
21+
@all-contributors please add @jakebolam for infrastructure, tests and code
2222
```
2323

2424
The bot will then create a Pull Request to add the contributor, then reply with the pull request details.

src/utils/parse-comment/index.js

Lines changed: 74 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
const nlp = require('compromise')
22

3+
// Types that are valid (multi words must all be lower case)
34
const validContributionTypes = [
45
'blog',
56
'bug',
67
'code',
78
'design',
89
'doc',
9-
'eventOrganizing',
10+
'eventorganizing',
1011
'example',
1112
'financial',
12-
'fundingFinding',
13+
'fundingfinding',
1314
'ideas',
1415
'infra',
1516
'maintenance',
@@ -23,17 +24,59 @@ const validContributionTypes = [
2324
'tool',
2425
'translation',
2526
'tutorial',
26-
'userTesting',
27+
'usertesting',
2728
'video',
2829
]
2930

31+
// Types that are valid multi words, that we need to re map back to there camelCase parts
32+
const validMultiContributionTypesMapping = {
33+
eventorganizing: 'eventOrganizing',
34+
fundingfinding: 'fundingFinding',
35+
usertesting: 'userTesting',
36+
}
37+
38+
// Additional terms to match to types (plurals, aliases etc)
3039
const contributionTypeMappings = {
31-
'event organizing': 'eventOrganizing',
32-
'funding finding': 'fundingFinding',
33-
'user testing': 'userTesting',
40+
blogs: 'blog',
41+
blogging: 'blog',
42+
bugs: 'bug',
43+
codes: 'code',
44+
coding: 'code',
45+
designing: 'design',
46+
desigs: 'design',
47+
doc: 'doc',
48+
docs: 'doc',
49+
documenting: 'doc',
3450
documentation: 'doc',
51+
examples: 'example',
52+
finance: 'financial',
53+
financials: 'financial',
54+
funds: 'fundingfinding',
55+
idea: 'ideas',
56+
infras: 'infra',
3557
infrastructure: 'infra',
3658
maintaining: 'maintenance',
59+
platforms: 'platform',
60+
plugins: 'plugin',
61+
questions: 'question',
62+
reviews: 'review',
63+
securing: 'security',
64+
talks: 'talk',
65+
tests: 'test',
66+
testing: 'test',
67+
tools: 'tool',
68+
tooling: 'tool',
69+
translations: 'translation',
70+
tutorials: 'tutorial',
71+
videoes: 'video',
72+
}
73+
74+
// Additional terms to match to types (plurals, aliases etc) that are multi word
75+
const contributionTypeMultiWordMapping = {
76+
'event organizing': 'eventOrganizing',
77+
'fund finding': 'fundingFinding',
78+
'funding finding': 'fundingFinding',
79+
'user testing': 'userTesting',
3780
}
3881

3982
const Contributions = {}
@@ -51,15 +94,12 @@ const plugin = {
5194
...Contributions,
5295
add: 'Action',
5396
},
54-
patterns: {
55-
// 'add #person for #Contribution': 'AddContributor',
56-
// "i can't (log|sign|get) in to my? #Software": 'LoginIssue'
57-
},
5897
}
98+
5999
nlp.plugin(plugin)
60100

61-
function parseAddComment(doc, action) {
62-
const whoMatched = doc
101+
function parseAddComment(message, action) {
102+
const whoMatched = nlp(message)
63103
.match(`${action} [.]`)
64104
.normalize({
65105
whitespace: true, // remove hyphens, newlines, and force one space between words
@@ -79,20 +119,32 @@ function parseAddComment(doc, action) {
79119

80120
const who = whoMatched.startsWith('@') ? whoMatched.substr(1) : whoMatched
81121

82-
// TODO: handle plurals (e.g. some said docs)
83-
let contributions = doc
122+
// Contributions
123+
const doc = nlp(message).toLowerCase()
124+
// This is to support multi word 'matches' (altho the compromise docs say it supports this *confused*)
125+
Object.entries(contributionTypeMultiWordMapping).forEach(
126+
([multiWordType, singleWordType]) => {
127+
doc.replace(multiWordType, singleWordType)
128+
},
129+
)
130+
const contributions = doc
84131
.match('#Contribution')
85132
.data()
86133
.map(data => {
87134
// This removes whitespace, commas etc
88135
return data.normal
89136
})
90-
91-
contributions = contributions.map(type => {
92-
if (contributionTypeMappings[type])
93-
return contributionTypeMappings[type]
94-
return type
95-
})
137+
.map(type => {
138+
if (contributionTypeMappings[type])
139+
return contributionTypeMappings[type]
140+
return type
141+
})
142+
.map(type => {
143+
// Convert usertesting to userTesting for the node api
144+
if (validMultiContributionTypesMapping[type])
145+
return validMultiContributionTypesMapping[type]
146+
return type
147+
})
96148

97149
return {
98150
action: 'add',
@@ -105,12 +157,13 @@ function parseComment(message) {
105157
const doc = nlp(message)
106158

107159
const action = doc
160+
.toLowerCase()
108161
.match('#Action')
109162
.normalize()
110163
.out('string')
111164

112165
if (action === 'add') {
113-
return parseAddComment(doc, action)
166+
return parseAddComment(message, action)
114167
}
115168

116169
return {

test/utils/parse-comment/index.test.js

Lines changed: 77 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,18 @@ describe('parseComment', () => {
1515
})
1616
})
1717

18+
test('Basic intent to add - ignore case (for action and contributions, NOT for user)', () => {
19+
expect(
20+
parseComment(
21+
`@${testBotName} please Add jakeBolam for DOC, inFra and coDe`,
22+
),
23+
).toEqual({
24+
action: 'add',
25+
who: 'jakeBolam',
26+
contributions: ['doc', 'infra', 'code'],
27+
})
28+
})
29+
1830
test('Basic intent to add - non name username', () => {
1931
expect(
2032
parseComment(`@${testBotName} please add tbenning for design`),
@@ -35,11 +47,13 @@ describe('parseComment', () => {
3547
})
3648
})
3749

38-
test('Intent unknown', () => {
50+
test('Basic intent to add - with plurals', () => {
3951
expect(
40-
parseComment(`@${testBotName} please lollmate for tool`),
52+
parseComment(`@${testBotName} please add dat2 for docs`),
4153
).toEqual({
42-
action: false,
54+
action: 'add',
55+
who: 'dat2',
56+
contributions: ['doc'],
4357
})
4458
})
4559

@@ -67,27 +81,65 @@ describe('parseComment', () => {
6781
})
6882
})
6983

70-
// TODO: make it so this works
71-
// test('Support split words (like user testing)', () => {
72-
// expect(
73-
// parseComment(
74-
// `@${testBotName} please add jakebolam for infrastructure, user testing`,
75-
// ),
76-
// ).toEqual({
77-
// action: 'add',
78-
// who: 'jakebolam',
79-
// contributions: ['infra', 'userTesting'],
80-
// })
81-
// })
84+
test('Support alternative sentences', () => {
85+
expect(
86+
parseComment(`@${testBotName} add @sinchang for infrastructure`),
87+
).toEqual({
88+
action: 'add',
89+
who: 'sinchang',
90+
contributions: ['infra'],
91+
})
92+
93+
expect(
94+
parseComment(
95+
`Jane you're crushing it in documentation and infrastructure, let's add jane.doe23 for her contributions. cc @${testBotName}`,
96+
),
97+
).toEqual({
98+
action: 'add',
99+
who: 'jane.doe23',
100+
contributions: ['doc', 'infra'],
101+
})
102+
})
103+
104+
test('Support split words (like user testing)', () => {
105+
expect(
106+
parseComment(
107+
`@${testBotName} please add jakebolam for infrastructure, fund finding`,
108+
),
109+
).toEqual({
110+
action: 'add',
111+
who: 'jakebolam',
112+
contributions: ['infra', 'fundingFinding'],
113+
})
114+
115+
expect(
116+
parseComment(
117+
`@${testBotName} please add jakebolam for infrastructure, user testing and testing`,
118+
),
119+
).toEqual({
120+
action: 'add',
121+
who: 'jakebolam',
122+
contributions: ['infra', 'userTesting', 'test'],
123+
})
124+
})
125+
126+
test('Support split words types that are referenced via other terms (e.g. a plural split word)', () => {
127+
expect(
128+
parseComment(
129+
`@${testBotName} please add @jakebolam for infrastructure, funds`,
130+
),
131+
).toEqual({
132+
action: 'add',
133+
who: 'jakebolam',
134+
contributions: ['infra', 'fundingFinding'],
135+
})
136+
})
82137

83-
//
84-
// test('Basic intent to add (with plurals)', () => {
85-
// expect(
86-
// parseComment(`@${testBotName} please add dat2 for docs`),
87-
// ).toEqual({
88-
// action: 'add',
89-
// who: 'dat2',
90-
// contributions: ['doc'],
91-
// })
92-
// })
138+
test('Intent unknown', () => {
139+
expect(
140+
parseComment(`@${testBotName} please lollmate for tool`),
141+
).toEqual({
142+
action: false,
143+
})
144+
})
93145
})

0 commit comments

Comments
 (0)