Skip to content

Commit d719ee1

Browse files
committed
Added doc, benchmark and deps/X node core PR labels (#32)
* Added `doc` and `benchmark` node core auto labels * Added `deps/X` node core auto labels * Avoid c++ label when only src/node_version.h is affected
1 parent 1a3c78a commit d719ee1

File tree

2 files changed

+125
-16
lines changed

2 files changed

+125
-16
lines changed

lib/node-labels.js

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,42 @@
11
'use strict'
22

3-
const subSystemLabels = {
4-
'c++': /^src\//
3+
// order of entries in this map *does* matter for the resolved labels
4+
const subSystemLabelsMap = {
5+
// don't want to label it a c++ update when we're "only" bumping the Node.js version
6+
'c++': /^src\/(?!node_version\.h)/,
7+
// libuv needs an explicit mapping, as the ordinary /deps/ mapping below would
8+
// end up as libuv changes labeled with "uv" (which is a non-existing label)
9+
'libuv': /^deps\/uv\//,
10+
'$1': /^deps\/([^/]+)/
511
}
612

7-
const rxTests = /^test\//
13+
const exclusiveLabelsMap = {
14+
test: /^test\//,
15+
doc: /^doc\//,
16+
benchmark: /^benchmark\//
17+
}
818

919
function resolveLabels (filepathsChanged) {
10-
if (isOnly(rxTests, filepathsChanged)) {
11-
return ['test']
12-
}
20+
const exclusiveLabels = matchExclusiveSubSystem(filepathsChanged)
21+
22+
return (exclusiveLabels.length > 0)
23+
? exclusiveLabels
24+
: matchAllSubSystem(filepathsChanged)
25+
}
1326

14-
return matchBySubSystemRegex(filepathsChanged)
27+
function matchExclusiveSubSystem (filepathsChanged) {
28+
const labels = matchSubSystemsByRegex(exclusiveLabelsMap, filepathsChanged)
29+
return labels.length === 1 ? labels : []
1530
}
1631

17-
function isOnly (regexToMatch, filepathsChanged) {
18-
return filepathsChanged.every((filepath) => regexToMatch.test(filepath))
32+
function matchAllSubSystem (filepathsChanged) {
33+
return matchSubSystemsByRegex(subSystemLabelsMap, filepathsChanged)
1934
}
2035

21-
function matchBySubSystemRegex (filepathsChanged) {
36+
function matchSubSystemsByRegex (rxLabelsMap, filepathsChanged) {
2237
// by putting matched labels into a map, we avoid duplicate labels
2338
const labelsMap = filepathsChanged.reduce((map, filepath) => {
24-
const mappedSubSystem = mappedSubSystemForFile(filepath)
39+
const mappedSubSystem = mappedSubSystemForFile(rxLabelsMap, filepath)
2540

2641
if (mappedSubSystem) {
2742
map[mappedSubSystem] = true
@@ -33,12 +48,31 @@ function matchBySubSystemRegex (filepathsChanged) {
3348
return Object.keys(labelsMap)
3449
}
3550

36-
function mappedSubSystemForFile (filepath) {
37-
return Object.keys(subSystemLabels).find((labelName) => {
38-
const rxForLabel = subSystemLabels[labelName]
51+
function mappedSubSystemForFile (labelsMap, filepath) {
52+
return Object.keys(labelsMap).map((labelName) => {
53+
const rxForLabel = labelsMap[labelName]
54+
const matches = rxForLabel.exec(filepath)
55+
56+
// return undefined when subsystem regex didn't match,
57+
// we'll filter out these values with the .filter() below
58+
if (matches === null) {
59+
return undefined
60+
}
61+
62+
// label names starting with $ means we want to extract a matching
63+
// group from the regex we've just matched against
64+
if (labelName.startsWith('$')) {
65+
const wantedMatchGroup = labelName.substr(1)
66+
return matches[wantedMatchGroup]
67+
}
68+
69+
// use label name as is when label doesn't look like a regex matching group
70+
return labelName
71+
}).filter(withoutUndefinedValues)[0]
72+
}
3973

40-
return rxForLabel.test(filepath) ? labelName : undefined
41-
})
74+
function withoutUndefinedValues (label) {
75+
return label !== undefined
4276
}
4377

4478
exports.resolveLabels = resolveLabels

test/node-labels.test.js

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,40 @@ tap.test('label: "test" when only ./test/ files has been changed', (t) => {
1616
t.end()
1717
})
1818

19+
tap.test('no labels: when ./test/ and ./doc/ files has been changed', (t) => {
20+
const labels = nodeLabels.resolveLabels([
21+
'test/debugger/test-debugger-pid.js',
22+
'doc/api/fs.md'
23+
])
24+
25+
t.same(labels, [])
26+
27+
t.end()
28+
})
29+
30+
tap.test('label: "doc" when only ./doc/ files has been changed', (t) => {
31+
const labels = nodeLabels.resolveLabels([
32+
'doc/api/fs.md',
33+
'doc/api/http.md',
34+
'doc/onboarding.md'
35+
])
36+
37+
t.same(labels, ['doc'])
38+
39+
t.end()
40+
})
41+
42+
tap.test('label: "benchmark" when only ./benchmark/ files has been changed', (t) => {
43+
const labels = nodeLabels.resolveLabels([
44+
'benchmark/http_server_lag.js',
45+
'benchmark/http/check_is_http_token.js'
46+
])
47+
48+
t.same(labels, ['benchmark'])
49+
50+
t.end()
51+
})
52+
1953
tap.test('label: "c++" when ./src/* has been changed', (t) => {
2054
const labels = nodeLabels.resolveLabels([
2155
'src/async-wrap.h',
@@ -27,6 +61,47 @@ tap.test('label: "c++" when ./src/* has been changed', (t) => {
2761
t.end()
2862
})
2963

64+
tap.test('label: not "c++" when ./src/node_version.h has been changed', (t) => {
65+
const labels = nodeLabels.resolveLabels([
66+
'src/node_version.h'
67+
])
68+
69+
t.same(labels, [])
70+
71+
t.end()
72+
})
73+
74+
tap.test('label: "v8" when ./deps/v8/ files has been changed', (t) => {
75+
const labels = nodeLabels.resolveLabels([
76+
'deps/v8/src/arguments.cc'
77+
])
78+
79+
t.same(labels, ['v8'])
80+
81+
t.end()
82+
})
83+
84+
tap.test('label: "libuv" when ./deps/ub/ files has been changed', (t) => {
85+
const labels = nodeLabels.resolveLabels([
86+
'deps/uv/src/fs-poll.c'
87+
])
88+
89+
t.same(labels, ['libuv'])
90+
91+
t.end()
92+
})
93+
94+
tap.test('label: "v8", "openssl" when ./deps/v8/ and ./deps/openssl/ files has been changed', (t) => {
95+
const labels = nodeLabels.resolveLabels([
96+
'deps/v8/src/arguments.cc',
97+
'deps/openssl/openssl/ssl/ssl_rsa.c'
98+
])
99+
100+
t.same(labels, ['v8', 'openssl'])
101+
102+
t.end()
103+
})
104+
30105
//
31106
// Planned tests to be resolved later
32107
//

0 commit comments

Comments
 (0)