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.
This commit is contained in:
Shrikant Sharat Kandula 2024-04-19 10:01:09 +05:30 committed by GitHub
parent 7a50b9095f
commit 97e3791d3a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 45 additions and 13 deletions

View File

@ -34,6 +34,7 @@ if [[ -f .env ]]; then
source .env
fi
node scripts/check-field-constants.mjs
# Build the code. $@ accepts all the parameters from the input command line and uses it in the maven build command
mvn clean package "$@"

View File

@ -1,7 +1,13 @@
/**
* 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);
@ -10,29 +16,37 @@ async function findInnerClassDefinitions(directory) {
const stats = await fs.stat(filePath);
if (stats.isDirectory()) {
await findInnerClassDefinitions(filePath);
} else if (path.extname(filePath) === '.java') {
await processJavaFile(filePath);
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 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];
console.log(filePath, classQualifiers, expectedParentClass);
for (const match of innerClassMatch[0].matchAll(/\bpublic\s+static\s+final\s+String\s+(\w+)\s+=\s+(.+?);/gs)) {
const key = match[1]
const key = match[1];
const valMatcherParts = [`^dotted\\(`];
for (const [i, field] of key.split("_").entries()) {
if (i > 0) {
@ -41,12 +55,14 @@ async function processJavaFile(filePath) {
valMatcherParts.push(`(\\w+\\.\\w+\\.)?${field}`);
}
valMatcherParts.push(`\\s*\\)$`);
const valMatcher = new RegExp(valMatcherParts.join(''));
const valMatcher = new RegExp(valMatcherParts.join(""));
if (!valMatcher.test(match[2])) {
console.log("key is", key);
console.log("val is", match[2]);
console.log("pattern", valMatcher);
console.error(`Field ${key} in ${filePath} is not looking right.`);
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;
}
}
}
@ -58,8 +74,23 @@ async function processJavaFile(filePath) {
} catch (err) {
console.error(err);
isPass = false;
}
return isPass;
}
const directoryPath = '.';
findInnerClassDefinitions(directoryPath);
// 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;
}
});