forked from adamlaska/browser-compat-data
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrelease-stats.js
More file actions
138 lines (120 loc) · 3.78 KB
/
release-stats.js
File metadata and controls
138 lines (120 loc) · 3.78 KB
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
131
132
133
134
135
136
137
138
const http = require('https');
const readline = require('readline');
const { exec, releaseYargsBuilder } = require('./release-utils');
const { walk } = require('../utils');
const { argv } = require('yargs').command(
'$0 [start-version-tag [end-version-tag]]',
'Generate statistics for release notes',
releaseYargsBuilder,
);
const getJSON = url =>
new Promise((resolve, reject) =>
http.get(
url,
{ headers: { 'User-Agent': 'bcd-release-script' } },
response => {
let body = '';
response.on('data', data => {
body += data;
});
response.on('error', error => reject(error));
response.on('end', () => {
resolve(JSON.parse(body));
});
},
),
);
const question = async query => {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const response = await new Promise(resolve => rl.question(query, resolve));
rl.close();
console.log();
return response;
};
const prompt = async questions => {
const results = {};
for (const q of questions) {
results[q.name] = await question(`${q.message} `).then(q.type);
}
return results;
};
const stargazers = () =>
getJSON('https://api.github.com/repos/mdn/browser-compat-data').then(
json => json.stargazers_count,
);
function stats(start, end) {
// Get just the diff stats summary
const diff = exec(`git diff --shortstat ${start}...${end}`);
if (diff === '') {
console.log('No changes for which to generate statistics.');
process.exit(1);
}
// Extract the numbers from a line like this:
// 50 files changed, 1988 insertions(+), 2056 deletions(-)
const [, changed, insertions, deletions] = diff.match(
/(\d+) files* changed, (\d+) insertions*\(\+\), (\d+) deletions*/,
);
// Get the number of commits
const commits = exec(`git rev-list --count ${start}...${end}`);
return {
commits,
changed,
insertions,
deletions,
};
}
const contributors = (start, end) =>
prompt([
{
name: 'releaseContributors',
type: Number,
message: `Find "contributors" at https://github.com/mdn/browser-compat-data/compare/${start}...${end}\nHow many people have contributed to this release?`,
},
{
name: 'totalContributors',
type: Number,
message:
'Find "contributors" at https://github.com/mdn/browser-compat-data/\nHow many people have contributed to browser-compat-data overall?',
},
]);
function countFeatures() {
return [...walk()].length;
}
const formatter = new Intl.NumberFormat('en-US');
function formatNumber(n) {
return formatter.format(n);
}
function formatStats(details) {
const releaseContributors = formatNumber(details.releaseContributors);
const totalContributors = formatNumber(details.totalContributors);
const changed = formatNumber(details.changed);
const insertions = formatNumber(details.insertions);
const deletions = formatNumber(details.deletions);
const commits = formatNumber(details.commits);
const features = formatNumber(details.features);
const stars = formatNumber(details.stars);
const { start, end } = details;
return `\
### Statistics
- ${releaseContributors} contributors have changed ${changed} files with ${insertions} additions and ${deletions} deletions in ${commits} commits ([\`${start}...${end}\`](https://github.com/mdn/browser-compat-data/compare/${start}...${end}))
- ${features} total features
- ${totalContributors} total contributors
- ${stars} total stargazers`;
}
async function main() {
const { startVersionTag: start, endVersionTag: end } = argv;
console.log(
formatStats({
start,
end,
...stats(start, end),
...(await contributors(start, end)),
stars: await stargazers(),
features: countFeatures(),
}),
);
}
main();