Skip to content

Commit 46aa651

Browse files
committed
feat: implement merge modes
1 parent 658afb8 commit 46aa651

File tree

11 files changed

+356
-8
lines changed

11 files changed

+356
-8
lines changed

lib/travis/imports.js

+17-8
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@ const Yaml = require('js-yaml');
66
const Loader = require('../loader');
77
const Utils = require('../utils');
88

9+
const TravisMerge = require('./merge');
910

10-
const internals = {};
11+
12+
const internals = {
13+
validMergeModes: new Set(['deep_merge_append', 'deep_merge_prepend', 'deep_merge', 'merge'])
14+
};
1115

1216

1317
internals.log = Debug('detect-node-support');
@@ -22,6 +26,8 @@ internals.normalizeImports = (travisYaml, { relativeTo }) => {
2226
entry = { source: entry };
2327
}
2428

29+
const original = entry.source;
30+
2531
if (entry.source.startsWith('./')) {
2632
entry.source = entry.source.substring(2);
2733

@@ -33,6 +39,14 @@ internals.normalizeImports = (travisYaml, { relativeTo }) => {
3339
}
3440
}
3541

42+
if (!entry.mode) {
43+
entry.mode = 'deep_merge_append';
44+
}
45+
46+
if (!internals.validMergeModes.has(entry.mode)) {
47+
throw new Error(`Invalid merge mode for ${original} in ${relativeTo ? relativeTo.source : '.travis.yml'}: ${entry.mode}`);
48+
}
49+
3650
return entry;
3751
})
3852
.filter((entry) => !entry.if); // @todo: log a warning
@@ -82,13 +96,8 @@ exports.apply = async (yaml, { loadFile, relativeTo, cache = new Map() }) => {
8296

8397
await exports.apply(imported, { loadFile, relativeTo: entry, cache });
8498

85-
for (const key in imported) {
86-
87-
if (key === 'import') {
88-
continue;
89-
}
99+
delete imported.import;
90100

91-
yaml[key] = imported[key];
92-
}
101+
TravisMerge[entry.mode](yaml, imported);
93102
}
94103
};

lib/travis/merge.js

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
'use strict';
2+
3+
// ref: https://github.com/travis-ci/travis-yml/blob/bf82881491134c72a64778f9664a8dd3f97158e7/lib/travis/yml/support/merge.rb
4+
5+
const internals = {};
6+
7+
8+
internals.isObject = (arg) => typeof arg === 'object' && !Array.isArray(arg);
9+
10+
11+
exports.deep_merge_append = (left, right) => {
12+
13+
for (const key in right) {
14+
15+
if (internals.isObject(left[key]) && internals.isObject(right[key])) {
16+
exports.deep_merge_append(left[key], right[key]);
17+
continue;
18+
}
19+
20+
if (Array.isArray(left[key]) && Array.isArray(right[key])) {
21+
left[key].push(...right[key]);
22+
continue;
23+
}
24+
25+
left[key] = right[key];
26+
}
27+
};
28+
29+
exports.deep_merge_prepend = (left, right) => {
30+
31+
for (const key in right) {
32+
33+
if (internals.isObject(left[key]) && internals.isObject(right[key])) {
34+
exports.deep_merge_prepend(left[key], right[key]);
35+
continue;
36+
}
37+
38+
if (Array.isArray(left[key]) && Array.isArray(right[key])) {
39+
left[key].unshift(...right[key]);
40+
continue;
41+
}
42+
43+
left[key] = right[key];
44+
}
45+
};
46+
47+
exports.deep_merge = (left, right) => {
48+
49+
for (const key in right) {
50+
51+
if (internals.isObject(left[key]) && internals.isObject(right[key])) {
52+
exports.deep_merge(left[key], right[key]);
53+
continue;
54+
}
55+
56+
left[key] = right[key];
57+
}
58+
};
59+
60+
exports.merge = (left, right) => {
61+
62+
for (const key in right) {
63+
left[key] = right[key];
64+
}
65+
};

test/fixtures/index.js

+3
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ module.exports = class TestContext {
9191
Fs.mkdirSync(Path.join(this.path, 'partials'));
9292
const partialYmls = [
9393
'indirect-node-14.yml',
94+
'merge-invalid.yml',
95+
'node-10.yml',
96+
'node-12.yml',
9497
'node-14.yml'
9598
];
9699
for (const fn of partialYmls) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
language: node_js
2+
node_js:
3+
- "8"
4+
import:
5+
- source: partials/node-14.yml # default merge: deep_merge_append
6+
- source: partials/node-12.yml
7+
mode: deep_merge_prepend
8+
- source: partials/node-10.yml
9+
mode: deep_merge_append
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
language: node_js
2+
node_js:
3+
- "8"
4+
import:
5+
- source: partials/node-14.yml # default merge: deep_merge_append
6+
- source: partials/node-12.yml
7+
mode: deep_merge
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
language: node_js
2+
node_js:
3+
- "8"
4+
import:
5+
- source: partials/merge-invalid.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
language: node_js
2+
node_js:
3+
- "8"
4+
import:
5+
- source: partials/node-14.yml # default merge: deep_merge_append
6+
- source: partials/node-12.yml
7+
mode: merge
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
language: node_js
2+
node_js:
3+
- "8"
4+
import:
5+
- source: partials/node-14.yml # default merge: deep_merge_append
6+
- source: partials/node-12.yml
7+
mode: no_such_merge_mode
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_js:
2+
- "10.15"
3+
- "10.16"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_js:
2+
- "12"

0 commit comments

Comments
 (0)