-
Notifications
You must be signed in to change notification settings - Fork 5
/
generate-changelog.js
96 lines (81 loc) · 2.43 KB
/
generate-changelog.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
/** Copyright (c) 2017 Uber Technologies, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
module.exports = function generateChangelog(changes, labelWeight) {
const indexed = indexByWeight(changes, labelWeight);
const [weighted, nonweighted] = partitionMap(
indexed,
([weight]) => weight > 0,
);
let lines = [];
if (weighted.length) {
lines.push('### Highlighted Changes');
for (let [, value] of weighted) {
lines.push(changeSection(value.labels));
for (let change of value.changes) {
lines.push(changeItem(change, true));
}
}
}
if (nonweighted.length) {
if (weighted.length) {
lines.push('');
lines.push('### Other Changes');
}
for (let [, value] of nonweighted) {
for (let change of value.changes) {
lines.push(changeItem(change, false));
}
}
}
if (!nonweighted.length && !weighted.length) {
lines.push('No pull requests in this release');
}
return lines.join('\n');
};
function partitionMap(map, filter) {
return filterMap(map, [filter, (...args) => !filter(...args)]);
}
function filterMap(map, filters) {
return filters.map(filter => Array.from(map.entries()).filter(filter));
}
/**
* Calculates the weight of a given array of labels
*/
function getWeight(labels, labelWeight) {
const places = labels.map(label => labelWeight.indexOf(label.name));
let binary = '';
for (let i = 0; i < labelWeight.length; i++) {
binary += places.includes(i) ? '1' : '0';
}
return parseInt(binary, 2);
}
function indexByWeight(changes, labelWeight) {
const index = new Map();
for (let change of changes) {
const weight = getWeight(change.labels, labelWeight);
if (!index.has(weight)) {
index.set(weight, {
changes: new Set(),
labels: change.labels
.filter(label => labelWeight.includes(label.name))
.sort(label => labelWeight.indexOf(label.name)),
});
}
index.get(weight).changes.add(change);
}
return index;
}
function changeSection(labels) {
return `<div>${labels
.map(label => `<img src="${labelImage(label)}"/>`)
.join(' ')}</div>\n`;
}
function changeItem(pr, indent = false) {
return `${indent ? ' ' : ''}- ${pr.title} ([#${pr.number}](${pr.url}))`;
}
function labelImage({color, name}) {
return `https://gh-label-svg.now.sh/label.svg?color=${color}&text=${name}`;
}