eslint-plugin-folder-name-convention
Version:
ESLint plugin to enforce folder naming conventions (kebab-case, camelCase, etc.)
79 lines (66 loc) • 1.98 kB
JavaScript
const fs = require('fs');
const path = require('path');
const NAMING_PATTERNS = {
'kebab-case': /^[a-z0-9]+(-[a-z0-9]+)*$/,
'camelCase': /^[a-z][a-zA-Z0-9]*$/,
'PascalCase': /^[A-Z][a-zA-Z0-9]*$/,
'snake_case': /^[a-z0-9_]+$/,
};
function isValid(name, pattern) {
const regex = NAMING_PATTERNS[pattern] || new RegExp(pattern);
return regex.test(name);
}
function checkFolders(baseDir, pattern, ignoreList) {
const invalid = [];
const entries = fs.readdirSync(baseDir, { withFileTypes: true });
for (const entry of entries) {
if (entry.isDirectory()) {
if (!ignoreList.includes(entry.name) && !isValid(entry.name, pattern)) {
invalid.push(path.join(baseDir, entry.name));
}
invalid.push(...checkFolders(path.join(baseDir, entry.name), pattern, ignoreList));
}
}
return invalid;
}
module.exports = {
meta: {
type: 'problem',
docs: {
description: 'Enforce folder naming conventions',
category: 'Stylistic Issues',
recommended: false,
},
schema: [
{
type: 'object',
properties: {
pattern: { type: 'string' },
ignore: { type: 'array', items: { type: 'string' } },
rootDir: { type: 'string' },
},
additionalProperties: false,
},
],
},
create(context) {
let reported = false;
const options = context.options[0] || {};
const pattern = options.pattern || 'kebab-case';
const ignore = options.ignore || ['node_modules', '.git'];
const rootDir = options.rootDir || context.getCwd();
return {
'Program:exit'() {
if (reported) return;
reported = true;
const invalid = checkFolders(rootDir, pattern, ignore);
for (const folder of invalid) {
context.report({
loc: { line: 1, column: 0 },
message: `Folder name "${folder}" does not match pattern "${pattern}".`,
});
}
},
};
},
};