PromucFlow_constructor/app/server/scripts/check-field-constants.mjs
Shrikant Sharat Kandula 97e3791d3a
chore: Add a lint step for field name constants (#32769)
We have a small linter NodeJS script that checks if any field name
constants are defined incorrectly. This PR adds this linter to the build
script, so it'll be run in CI.
2024-04-19 10:01:09 +05:30

97 lines
2.9 KiB
JavaScript

/**
* This script checks if the field constants in the Java files are named and defined correctly.
*/
import {promises as fs} from "fs";
import path from "path";
async function findInnerClassDefinitions(directory) {
let isPass = true;
try {
const files = await fs.readdir(directory);
for (const file of files) {
const filePath = path.join(directory, file);
const stats = await fs.stat(filePath);
if (stats.isDirectory()) {
if (!await findInnerClassDefinitions(filePath)) {
isPass = false;
}
} else if (path.extname(filePath) === ".java") {
if (!await processJavaFile(filePath)) {
isPass = false;
}
}
}
} catch (err) {
console.error(err);
isPass = false;
}
return isPass;
}
async function processJavaFile(filePath) {
let isPass = true;
try {
const contents = await fs.readFile(filePath, "utf8");
const innerClassRegex = /^ {4}([\w ]+?)\s+class\s+Fields\s+(extends (\w+)\.Fields)?\s*{(.+?\n {4})?}$/gsm;
for (const innerClassMatch of contents.matchAll(innerClassRegex)) {
const classQualifiers = innerClassMatch[1]; // we don't care much about this
const expectedParentClass = innerClassMatch[3];
for (const match of innerClassMatch[0].matchAll(/\bpublic\s+static\s+final\s+String\s+(\w+)\s+=\s+(.+?);/gs)) {
const key = match[1];
const valMatcherParts = [`^dotted\\(`];
for (const [i, field] of key.split("_").entries()) {
if (i > 0) {
valMatcherParts.push(`\\s*,\\s+`);
}
valMatcherParts.push(`(\\w+\\.\\w+\\.)?${field}`);
}
valMatcherParts.push(`\\s*\\)$`);
const valMatcher = new RegExp(valMatcherParts.join(""));
if (!valMatcher.test(match[2])) {
console.log(filePath, classQualifiers, expectedParentClass);
console.log("\tkey is", key);
console.log("\tval is", match[2]);
console.log("\tpattern", valMatcher);
console.error(`\tField ${key} in ${filePath} is not looking right.`);
isPass = false;
}
}
}
// if (finds.length > 1) {
// console.error(`Found multiple inner class definitions in file: ${filePath}`);
// return;
// }
} catch (err) {
console.error(err);
isPass = false;
}
return isPass;
}
// Can't use `import.meta.dirname` because it's not available in Node.js 18.
// And v18 is what is included in GitHub Actions today.
// See <https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md#language-and-runtime>.
const directoryPath = import.meta.resolve("..").replace("file://", "");
findInnerClassDefinitions(directoryPath)
.then(isPass => {
if (isPass) {
console.log("All okay.");
} else {
console.error("Some field constants are not looking good.");
process.exitCode = 1;
}
});