Skip to content

Commit

Permalink
Allow subclasses to add additional input nodes.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
rwjblue committed Jun 10, 2021
1 parent 7845bf3 commit a7ed4fa
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 2 deletions.
5 changes: 3 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ function existsSync(path) {
}

class Funnel extends Plugin {
constructor(inputNode, options = {}) {
super([inputNode], {
constructor(inputs, options = {}) {
let inputNodes = Array.isArray(inputs) ? inputs : [inputs];
super(inputNodes, {
annotation: options.annotation,
persistentOutput: true,
needsCache: false,
Expand Down
62 changes: 62 additions & 0 deletions tests/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1106,4 +1106,66 @@ describe('broccoli-funnel', function() {
expect(getDestPathCalled).to.be.equal(1);
});
});

describe('subclassing', function() {
it('can be subclassed, simple destDir modification', async function() {
class FunnelSubclass extends Funnel.Funnel {
constructor(input, options) {
super(input, options);

this._hasBuilt = false;
}

build() {
if (this._hasBuilt === false) {
this.destDir = 'lol';
this._hasBuilt = true;
}

return super.build();
}
}

let inputPath = input.path('lib/utils');
let node = new FunnelSubclass(inputPath, {});
output = createBuilder(node);

await output.build();
let outputPath = output.path();

expect(walkSync(outputPath)).to.eql(['lol/', 'lol/foo.js']);
});

it('subclasses can provide additional trees', async function() {
class FunnelSubclass extends Funnel.Funnel {
constructor(inputNode, options) {
super([inputNode, input.path('dir1/subdir2')], options);

this._hasBuilt = false;
}

build() {
if (this._hasBuilt === false) {
if (!fs.existsSync(`${this.inputPaths[1]}/bar.css`)) {
throw new Error('Could not find file!!!');
}
// set custom destDir to ensure our custom build code ran
this.destDir = 'lol';
this._hasBuilt = true;
}

return super.build();
}
}

let inputPath = input.path('lib/utils');
let node = new FunnelSubclass(inputPath, {});
output = createBuilder(node);

await output.build();
let outputPath = output.path();

expect(walkSync(outputPath)).to.eql(['lol/', 'lol/foo.js']);
});
});
});

0 comments on commit a7ed4fa

Please # to comment.