Skip to content

Commit

Permalink
Add ignore-exporting flag to the match-regex rule.
Browse files Browse the repository at this point in the history
  • Loading branch information
selaux committed May 2, 2016
1 parent c5b5b01 commit 4c25051
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 51 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,15 @@ Modify your `.eslintrc` file to load the plugin and enable the rules you want to

A rule to enforce a certain file naming convention using a regular expression.

The convention can be configured using a regular expression (the default is `camelCase.js`):
The convention can be configured using a regular expression (the default is `camelCase.js`). Additionally
exporting files can be ignored with a second configuration parameter.

```json
"filenames/match-regex": [2, "^[a-z_]+$"]
"filenames/match-regex": [2, "^[a-z_]+$", true]
```

With these configuration options, `camelCase.js` will be reported as an error while `snake_case.js` will pass.
Additionally the files that have a named default export (according to the logic in the `match-exported` rule) will be ignored.

### Matching Exported Values (match-exported)

Expand Down
32 changes: 32 additions & 0 deletions lib/common/getExportedName.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
function getNodeName(node) {
if (node.type === "Identifier") {
return node.name;
}

if (node.id && node.id.type === "Identifier") {
return node.id.name;
}
}

module.exports = function getExportedName(programNode) {
for (var i = 0; i < programNode.body.length; i += 1) {
var node = programNode.body[i];

// export default ...
if (node.type === "ExportDefaultDeclaration") {
return getNodeName(node.declaration);
}

// module.exports = ...
if (node.type === "ExpressionStatement" &&
node.expression.type === "AssignmentExpression" &&
node.expression.left.type === "MemberExpression" &&
node.expression.left.object.type === "Identifier" &&
node.expression.left.object.name === "module" &&
node.expression.left.property.type === "Identifier" &&
node.expression.left.property.name === "exports"
) {
return getNodeName(node.expression.right);
}
}
};
2 changes: 1 addition & 1 deletion lib/common/isIgnoredFilename.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ var ignoredFilenames = [ "<text>", "<input>" ];

module.exports = function isIndexFile(filename) {
return ignoredFilenames.indexOf(filename) !== -1;
};
};
2 changes: 1 addition & 1 deletion lib/common/isIndexFile.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module.exports = function isIndexFile(parsed) {
return parsed.name === 'index';
};
};
2 changes: 1 addition & 1 deletion lib/common/parseFilename.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ module.exports = function parseFilename(filename) {
ext: ext,
name: path.basename(filename, ext)
}
};
};
34 changes: 1 addition & 33 deletions lib/rules/match-exported.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,41 +10,9 @@
var path = require('path'),
parseFilename = require('../common/parseFilename'),
isIgnoredFilename = require('../common/isIgnoredFilename'),
getExportedName = require('../common/getExportedName'),
isIndexFile = require('../common/isIndexFile');

function getNodeName(node) {
if (node.type === "Identifier") {
return node.name;
}

if (node.id && node.id.type === "Identifier") {
return node.id.name;
}
}

function getExportedName(programNode) {
for (var i = 0; i < programNode.body.length; i += 1) {
var node = programNode.body[i];

// export default ...
if (node.type === "ExportDefaultDeclaration") {
return getNodeName(node.declaration);
}

// module.exports = ...
if (node.type === "ExpressionStatement" &&
node.expression.type === "AssignmentExpression" &&
node.expression.left.type === "MemberExpression" &&
node.expression.left.object.type === "Identifier" &&
node.expression.left.object.name === "module" &&
node.expression.left.property.type === "Identifier" &&
node.expression.left.property.name === "exports"
) {
return getNodeName(node.expression.right);
}
}
}

function getStringToCheckAgainstExport(parsed) {
var dirArray = parsed.dir.split(path.sep);
var lastDirectory = dirArray[dirArray.length - 1];
Expand Down
6 changes: 5 additions & 1 deletion lib/rules/match-regex.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,25 @@

var path = require("path"),
parseFilename = require('../common/parseFilename'),
getExportedName = require('../common/getExportedName'),
isIgnoredFilename = require('../common/isIgnoredFilename');

module.exports = function(context) {
var defaultRegexp = /^([a-z0-9]+)([A-Z][a-z0-9]+)*$/g,
conventionRegexp = context.options[0] ? new RegExp(context.options[0]) : defaultRegexp;
conventionRegexp = context.options[0] ? new RegExp(context.options[0]) : defaultRegexp,
ignoreExporting = context.options[1] ? context.options[1] : false;

return {
"Program": function(node) {
var filename = context.getFilename(),
absoluteFilename = path.resolve(filename),
parsed = parseFilename(absoluteFilename),
shouldIgnore = isIgnoredFilename(filename),
isExporting = Boolean(getExportedName(node)),
matchesRegex = conventionRegexp.test(parsed.name);

if (shouldIgnore) return;
if (ignoreExporting && isExporting) return;
if (!matchesRegex) {
context.report(node, "Filename '{{name}}' does not match the naming convention.", {
name: parsed.base
Expand Down
20 changes: 8 additions & 12 deletions test/rules/match-regex.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
var regexRule = require("../../lib/rules/match-regex"),
RuleTester = require("eslint").RuleTester;

var testCode = "var foo = 'bar';",
var exportingCode = 'module.exports = foo',
testCode = "var foo = 'bar';",
ruleTester = new RuleTester();

ruleTester.run("lib/rules/match-regex", regexRule, {
Expand Down Expand Up @@ -41,19 +42,14 @@ ruleTester.run("lib/rules/match-regex", regexRule, {
filename: "/foo/dir/fooBar.js"
},
{
code: testCode,
filename: "/some/dir/exported.js",
options: [ null, "match-regex-and-exported" ]
},
{
code: testCode,
filename: "/some/dir/exported.js",
options: [ null, "match-regex-or-exported" ]
code: exportingCode,
filename: "foo_bar.js",
options: [ null, true ]
},
{
code: testCode,
filename: "/some/dir/exported.js",
options: [ null, "match-exported-or-regex" ]
code: exportingCode,
filename: "fooBar.js",
options: [ "^[a-z_]$", true ]
}
],

Expand Down

0 comments on commit 4c25051

Please sign in to comment.