Skip to content

Commit a7ed4fa

Browse files
author
Robert Jackson
committed
Allow subclasses to add additional input nodes.
Subclassing broccoli-funnel has become somewhat common (e.g. Embroider and ember-css-modules both do it). This adds a basic test to confirm that it generally works. Additionally, this adds the ability for the subclass to add additional nodes to be considered as part of the broccoli tree graph. This ensures that if you happen to subclass and need to read from another tree to know where to write, you can add that other tree to your inputs and be *guaranteed* that they will have been built before you are called. Without this change, it _might_ seem to work **sometimes** but it is absolutely not guaranteed to work.
1 parent 7845bf3 commit a7ed4fa

File tree

2 files changed

+65
-2
lines changed

2 files changed

+65
-2
lines changed

index.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,9 @@ function existsSync(path) {
5050
}
5151

5252
class Funnel extends Plugin {
53-
constructor(inputNode, options = {}) {
54-
super([inputNode], {
53+
constructor(inputs, options = {}) {
54+
let inputNodes = Array.isArray(inputs) ? inputs : [inputs];
55+
super(inputNodes, {
5556
annotation: options.annotation,
5657
persistentOutput: true,
5758
needsCache: false,

tests/index.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,4 +1106,66 @@ describe('broccoli-funnel', function() {
11061106
expect(getDestPathCalled).to.be.equal(1);
11071107
});
11081108
});
1109+
1110+
describe('subclassing', function() {
1111+
it('can be subclassed, simple destDir modification', async function() {
1112+
class FunnelSubclass extends Funnel.Funnel {
1113+
constructor(input, options) {
1114+
super(input, options);
1115+
1116+
this._hasBuilt = false;
1117+
}
1118+
1119+
build() {
1120+
if (this._hasBuilt === false) {
1121+
this.destDir = 'lol';
1122+
this._hasBuilt = true;
1123+
}
1124+
1125+
return super.build();
1126+
}
1127+
}
1128+
1129+
let inputPath = input.path('lib/utils');
1130+
let node = new FunnelSubclass(inputPath, {});
1131+
output = createBuilder(node);
1132+
1133+
await output.build();
1134+
let outputPath = output.path();
1135+
1136+
expect(walkSync(outputPath)).to.eql(['lol/', 'lol/foo.js']);
1137+
});
1138+
1139+
it('subclasses can provide additional trees', async function() {
1140+
class FunnelSubclass extends Funnel.Funnel {
1141+
constructor(inputNode, options) {
1142+
super([inputNode, input.path('dir1/subdir2')], options);
1143+
1144+
this._hasBuilt = false;
1145+
}
1146+
1147+
build() {
1148+
if (this._hasBuilt === false) {
1149+
if (!fs.existsSync(`${this.inputPaths[1]}/bar.css`)) {
1150+
throw new Error('Could not find file!!!');
1151+
}
1152+
// set custom destDir to ensure our custom build code ran
1153+
this.destDir = 'lol';
1154+
this._hasBuilt = true;
1155+
}
1156+
1157+
return super.build();
1158+
}
1159+
}
1160+
1161+
let inputPath = input.path('lib/utils');
1162+
let node = new FunnelSubclass(inputPath, {});
1163+
output = createBuilder(node);
1164+
1165+
await output.build();
1166+
let outputPath = output.path();
1167+
1168+
expect(walkSync(outputPath)).to.eql(['lol/', 'lol/foo.js']);
1169+
});
1170+
});
11091171
});

0 commit comments

Comments
 (0)