Skip to content
This repository has been archived by the owner on Nov 23, 2024. It is now read-only.

Accept multiple input nodes #122

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ const isString = require('./is-string');
const getResultSeverity = require('./get-result-severity');
const testGenerators = require('./test-generators');
const testGeneratorNames = Object.keys(testGenerators);
const nodeIncludesOverrides = require('./node-includes-overrides');

const FACTORY_METHOD_USED = Symbol('create() factory method was used');

function resolveInputDirectory(inputNode) {
function resolveInputDirectory(inputNode, eslintIncludesOverrides) {
if (typeof inputNode === 'string') {
return inputNode;
}
Expand All @@ -27,12 +28,14 @@ function resolveInputDirectory(inputNode) {
return nodeInfo.sourceDirectory;
}

if (nodeInfo.inputNodes.length > 1) {
if (nodeInfo.inputNodes.length > 1 && !eslintIncludesOverrides) {
// eslint-disable-next-line max-len
throw new Error('EslintValidationFilter can only handle one:* broccoli nodes, but part of the given input pipeline is a many:* node. (broccoli-merge-trees is an example of a many:* node) Please perform many:* operations after linting.');
throw new Error(
'EslintValidationFilter can only handle one:* broccoli nodes, but part of the given input pipeline is a many:* node. (broccoli-merge-trees is an example of a many:* node) Please perform many:* operations after linting.'
);
}

return resolveInputDirectory(nodeInfo.inputNodes[0]);
return resolveInputDirectory(nodeInfo.inputNodes[0], eslintIncludesOverrides);
}

/**
Expand Down Expand Up @@ -80,7 +83,10 @@ function EslintValidationFilter(inputNode, options) {

this.cli = new CLIEngine(options.options);

this.eslintrc = resolveInputDirectory(inputNode);
this.eslintrc = resolveInputDirectory(
inputNode,
nodeIncludesOverrides(inputNode, this.cli)
);

if (isString(this.internalOptions.testGenerator)) {
this.testGenerator = testGenerators[this.internalOptions.testGenerator];
Expand Down
36 changes: 36 additions & 0 deletions lib/node-includes-overrides.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Uses eslint (private) api to see if eslint config includes a `overrides` flag.
*
* inputNode type is a bit tricky here. We are expecting three different cases:
* if it's string, we will use it as a directory and let eslint do the work.
*
* if it's a source node, use the `sourceDirectory` property.
*
* if it's a transform node, recursively call same function with all of its
* inputNodes. if any of the input directories contain `overrides` eslint
* config, return true
*
* While it's not ideal we iterate through all the `inputNodes` of a transform node,
* the input size should be very small.
*/
const nodeIncludesOverrides = (inputNode, eslintCli) => {
if (typeof inputNode === 'string') {
return eslintCli.config
.getConfigHierarchy(inputNode)
.some(node => node.overrides);
}

const nodeInfo = inputNode.__broccoliGetInfo__();
const nodeType = nodeInfo.nodeType;
const sourceDirectory = nodeInfo.sourceDirectory;
if (nodeType === 'transform') {
const nodesIncludesOverrides = inputNode._inputNodes.map(node =>
nodeIncludesOverrides(node, eslintCli)
);
return nodesIncludesOverrides.some(Boolean);
}

return nodeIncludesOverrides(sourceDirectory, eslintCli);
Copy link
Contributor Author

@sangm sangm Nov 29, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rwjblue

This is a bit questionable, mostly due to my lack of knowledge in Broccoli.

I feel it's safer to do

if (nodeType === 'transform') {
...
} else if (nodeType === 'source') {
...
}

return false

Let me know

};

module.exports = nodeIncludesOverrides;
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
"version": "4.2.1",
"description": "broccoli filter that runs eslint",
"main": "lib/index.js",
"engines": {
"node": ">=4"
},
"scripts": {
"lint": "eslint .",
"test": "mocha test/*test.js test/**/*test.js"
Expand Down
33 changes: 33 additions & 0 deletions test/eslint-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,39 @@ describe('broccoli-lint-eslint', function() {
.to.contain(`DEPRECATION: Please use the create() factory method`);
}));

it('accept many:* node if eslintrc specifies overrides', co.wrap(function*() {
// we need to create two temp folders with eslintrc files in it
const firstDirectory = yield createTempDir();
const secondDirectory = yield createTempDir();

firstDirectory.write({
'.eslintrc.js': `module.exports = { rules: { 'no-console': 'error'}, overrides: [ { files: 'a.js', rules: { 'no-console': 'disable' } }] }`,
'a.js': `console.log('foo');\n`,
});

secondDirectory.write({
'.eslintrc.js': `module.exports = { }`,
'a.js': `console.log('foo');\n`,
});

let messages = [];
let console = {
log(message) {
messages.push(message);
},
};

const mergedDirectories = new MergeTrees([
firstDirectory.path(),
secondDirectory.path(),
]);

expect(() => new ESLint(mergedDirectories, { console })).to.not.throw();

yield firstDirectory.dispose();
yield secondDirectory.dispose();
}));

it('logs errors to the console (using new)', co.wrap(function *() {
input.write({
'.eslintrc.js': `module.exports = { rules: { 'no-console': 'error', 'no-unused-vars': 'warn' } };\n`,
Expand Down