-
-
Notifications
You must be signed in to change notification settings - Fork 20
/
index.js
130 lines (112 loc) · 3.35 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/**
* @fileoverview It removes all the duplicates comments by this bot and
* leaves the last one of each type. It uses a unique hash from the comment message.
* Makesure all comments have a hash at the end
* @example
*
* hi
*
* [//]: # (hi)
* @author Gyandeep Singh
*/
"use strict";
const botType = "Bot";
/**
* Filters the comments based on the current user
* @param {Array<Object>} comments collection of comments as returned by the github
* @returns {Array<Object>} filtered comments
* @private
*/
function filterBotComments(comments) {
return comments.filter(comment => comment.user.type === botType);
}
/**
* Extract the comment hash from the comment
* @param {string} comment comment body
* @returns {string} comment hash
* @private
*/
function getCommentHash(comment) {
const startIdx = comment.indexOf("[//]: # (") + 9;
const endIndex = comment.indexOf(")", startIdx);
return comment.slice(startIdx, endIndex);
}
/**
* Creates the collection of comments based on the hash present inside the comments
* ignore the comments which doesnt have a hash
* @param {Array<Object>} comments collection of comments as returned by the github
* @returns {Map} comments by hash map
* @private
*/
function commentsByHash(comments) {
return comments.reduce((coll, comment) => {
const commentHash = getCommentHash(comment.body);
// if there is no hash then just skip
if (commentHash.length === 0) {
return coll;
}
if (coll.has(commentHash)) {
coll.get(commentHash).push(comment);
} else {
coll.set(commentHash, [comment]);
}
return coll;
}, new Map());
}
/**
* Filter comments that need to be deleted and return them
* @param {Map} commentsMap comments collection by hash value inside the comment
* @returns {Array} Comments to be deleted
* @private
*/
function getCommentsTobeDeleted(commentsMap) {
const comments = [];
commentsMap.forEach(commentSet => {
if (commentSet.length > 1) {
comments.push(...commentSet.slice(0, commentSet.length - 1));
}
});
return comments;
}
/**
* Process the comments and return the comments which are duplicate and needs to be deleted
* @param {Array<Object>} comments collection of comments as returned by the github
* @returns {Array<Object>} comments to be deleted
* @private
*/
function processComments(comments) {
return getCommentsTobeDeleted(
commentsByHash(
filterBotComments(comments)
)
);
}
/**
* Checks for duplicates comments and removes all the duplicates leaving the last one
* @param {Object} context context given by the probot
* @returns {Promise.<void>} done when comments are removed
* @private
*/
async function duplicateCheck(context) {
const { payload, github } = context;
if (payload.issue.state === "open") {
const allComments = await github.issues.listComments(context.issue());
await Promise.all(processComments(allComments.data)
.map(
comment => github.issues.deleteComment(
context.repo({ comment_id: comment.id })
)
));
}
}
/**
* Make sure all comments have a hash at the end
* @example
*
* hi
*
* [//]: # (hi)
*/
module.exports = robot => {
robot.on("issue_comment.created", duplicateCheck);
};