forked from mdn/browser-compat-data
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathchanges.ts
More file actions
153 lines (129 loc) · 3.8 KB
/
changes.ts
File metadata and controls
153 lines (129 loc) · 3.8 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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/* This file is a part of @mdn/browser-compat-data
* See LICENSE file for more information. */
export type FeatureChange = {
mergeCommit?: string;
number: number;
url: string;
feature: string;
};
export interface Changes {
added: FeatureChange[];
removed: FeatureChange[];
}
import chalk from 'chalk-template';
import diffFeatures from '../diff-features.js';
import { queryPRs } from './utils.js';
/**
* Format a feature change in Markdown
*
* @param {FeatureChange} obj The feature change to format
* @returns {string} The formatted feature change
*/
const featureBullet = (obj: FeatureChange) =>
`- \`${obj.feature}\` ([#${obj.number}](${obj.url}))`;
/**
* Format all the feature changes in Markdown
*
* @param {Changes} changes The changes to format
* @returns {string} The formatted changes
*/
export const formatChanges = (changes: Changes): string => {
const output: string[] = [];
if (changes.removed.length) {
output.push('### Removals', '');
for (const removal of changes.removed) {
output.push(featureBullet(removal));
}
output.push('');
}
if (changes.added.length) {
output.push('### Additions', '');
for (const addition of changes.added) {
output.push(featureBullet(addition));
}
output.push('');
}
return output.join('\n');
};
/**
* Get all the pulls that have been merged on GitHub
*
* @param {string} fromDate The start date to get merged pulls from
* @returns {FeatureChange[]} The pull requests that have been merged
*/
const pullsFromGitHub = (fromDate: string): FeatureChange[] =>
queryPRs({
search: `is:pr merged:>=${fromDate}`,
json: 'number,url,mergeCommit',
jq: '[.[] | { mergeCommit: .mergeCommit.oid, number: .number, url: .url }]', // Flatten the structure provided by GitHub
});
/**
* Get the diff from the pull request
*
* @param {FeatureChange} pull The pull request to test
* @returns {{ added: string[]; removed: string[] }} The changes from the pull request
*/
const getDiff = (
pull: FeatureChange,
): { added: string[]; removed: string[] } | null => {
process.stdout.write(
chalk`{blue - Diffing features for {bold #${pull.number}}...}`,
);
let diff;
try {
diff = diffFeatures({ ref1: pull.mergeCommit });
} catch (e) {
console.log(
chalk`{red ${e}}\n {yellow (Failed to diff features for #${pull.number}, skipping)}`,
);
return null;
}
if (diff.added.length && diff.removed.length) {
console.log(
chalk` {blue ({green ${diff.added.length} added}, {red ${diff.removed.length} removed})}`,
);
} else if (diff.added.length) {
console.log(chalk` {blue ({green ${diff.added.length} added})}`);
} else if (diff.removed.length) {
console.log(chalk` {blue ({red ${diff.removed.length} removed})}`);
} else {
console.log(chalk` {blue (No feature count changes)}`);
}
return diff;
};
/**
* Get changes from the pull requests that have been merged since a specified date
*
* @param {string} date The starting date to query pull requests from
* @returns {Changes} The changes from all of the pull requests
*/
export const getChanges = async (date: string): Promise<Changes> => {
const pulls = pullsFromGitHub(date);
const changes: Changes = {
added: [],
removed: [],
};
for (const pull of pulls) {
const diff = getDiff(pull);
if (!diff) {
continue;
}
for (const feature of diff.added) {
changes.added.push({
number: pull.number,
url: pull.url,
feature,
});
}
for (const feature of diff.removed) {
changes.removed.push({
number: pull.number,
url: pull.url,
feature,
});
}
}
changes.added.sort((a, b) => a.feature.localeCompare(b.feature));
changes.removed.sort((a, b) => a.feature.localeCompare(b.feature));
return changes;
};