mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2025-12-29 19:52:43 +00:00
Custom eslint plugin
This commit is contained in:
@@ -1,13 +1,14 @@
|
||||
import react from "eslint-plugin-react";
|
||||
import jest from "eslint-plugin-jest";
|
||||
import globals from "globals";
|
||||
import localPlugin from "./eslint_plugins/index.js";
|
||||
|
||||
export default [{
|
||||
ignores: ["build/"]
|
||||
},
|
||||
{
|
||||
files : ['**/*.js', '**/*.jsx'],
|
||||
plugins : { react, jest },
|
||||
plugins : { react, jest, local: localPlugin },
|
||||
languageOptions : {
|
||||
ecmaVersion : "latest",
|
||||
sourceType : "module",
|
||||
@@ -65,7 +66,10 @@ export default [{
|
||||
"key-spacing" : ["warn", {
|
||||
multiLine : { beforeColon: true, afterColon: true, align: "colon" },
|
||||
singleLine : { beforeColon: false, afterColon: true }
|
||||
}]
|
||||
}],
|
||||
|
||||
"local/aligned-useState-pairs": "warn"
|
||||
|
||||
}
|
||||
}
|
||||
];
|
||||
7
eslint_plugins/index.js
Normal file
7
eslint_plugins/index.js
Normal file
@@ -0,0 +1,7 @@
|
||||
import alignedUseStatePairs from './rules/aligned-useState-pairs.js';
|
||||
|
||||
export default {
|
||||
rules: {
|
||||
'aligned-useState-pairs': alignedUseStatePairs
|
||||
}
|
||||
};
|
||||
104
eslint_plugins/rules/aligned-useState-pairs.js
Normal file
104
eslint_plugins/rules/aligned-useState-pairs.js
Normal file
@@ -0,0 +1,104 @@
|
||||
export default {
|
||||
meta: {
|
||||
type: "layout",
|
||||
docs: {
|
||||
description: "Enforce alignment of adjacent useState variable pairs",
|
||||
},
|
||||
fixable: "whitespace",
|
||||
schema: [],
|
||||
},
|
||||
create(context) {
|
||||
const sourceCode = context.getSourceCode();
|
||||
const useStateDeclarations = [];
|
||||
|
||||
return {
|
||||
VariableDeclaration(node) {
|
||||
for (const decl of node.declarations) {
|
||||
const init = decl.init;
|
||||
if (
|
||||
init &&
|
||||
init.type === "CallExpression" &&
|
||||
init.callee.name === "useState" &&
|
||||
decl.id.type === "ArrayPattern"
|
||||
) {
|
||||
useStateDeclarations.push(decl);
|
||||
}
|
||||
}
|
||||
},
|
||||
"Program:exit"() {
|
||||
if (useStateDeclarations.length < 2) return;
|
||||
|
||||
// Sort by line number
|
||||
useStateDeclarations.sort(
|
||||
(a, b) => a.loc.start.line - b.loc.start.line
|
||||
);
|
||||
|
||||
// Group adjacent lines
|
||||
const groups = [];
|
||||
let currentGroup = [useStateDeclarations[0]];
|
||||
|
||||
for (let i = 1; i < useStateDeclarations.length; i++) {
|
||||
const prev = useStateDeclarations[i - 1];
|
||||
const curr = useStateDeclarations[i];
|
||||
|
||||
if (curr.loc.start.line === prev.loc.end.line + 1) {
|
||||
currentGroup.push(curr);
|
||||
} else {
|
||||
if (currentGroup.length > 1) groups.push(currentGroup);
|
||||
currentGroup = [curr];
|
||||
}
|
||||
}
|
||||
if (currentGroup.length > 1) groups.push(currentGroup);
|
||||
|
||||
// Analyze each group
|
||||
for (const group of groups) {
|
||||
const positions = group.map((decl) => {
|
||||
const text = sourceCode.getText(decl);
|
||||
const commaIndex = text.indexOf(",");
|
||||
const closingBracketIndex = text.lastIndexOf("]");
|
||||
return {
|
||||
node: decl,
|
||||
comma: commaIndex,
|
||||
closing: closingBracketIndex,
|
||||
};
|
||||
});
|
||||
|
||||
const maxComma = Math.max(...positions.map((p) => p.comma));
|
||||
const maxClosing = Math.max(
|
||||
...positions.map((p) => p.closing)
|
||||
);
|
||||
|
||||
for (const pos of positions) {
|
||||
if (
|
||||
pos.comma !== maxComma ||
|
||||
pos.closing !== maxClosing
|
||||
) {
|
||||
context.report({
|
||||
node: pos.node,
|
||||
message: "useState pair is not aligned with others in its block.",
|
||||
fix(fixer) {
|
||||
const text = sourceCode.getText(pos.node);
|
||||
const parts = text.match(/^\[\s*(.+?)\s*,\s*(.+?)\s*\]\s*=\s*useState\((.+)\)$/);
|
||||
if (!parts) return null;
|
||||
|
||||
const [_, left, right, value] = parts;
|
||||
|
||||
const paddedLeft = left.padEnd(maxComma - 1);
|
||||
const paddedRight = right.padEnd(maxClosing - maxComma - 2);
|
||||
const aligned = `[${paddedLeft}, ${paddedRight}] = useState(${value})`;
|
||||
console.log("Pre: " + text);
|
||||
console.log("Post: " + aligned);
|
||||
return [
|
||||
fixer.replaceText(pos.node, aligned),
|
||||
fixer.insertTextBefore(pos.node.parent, ""),
|
||||
fixer.insertTextAfter(pos.node.parent, "")
|
||||
];
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user