The point is to prevent unfortunate field name problems like this: https://github.com/appsmithorg/appsmith/pull/31760/files. This NodeJS script does a very rudimentary analysis on all Java files, with a few regular expressions, and finds anomalies. As such, since it's not very smart, it's quite strict. I intend to make it a little more strict in the coming days, but it's a start. It's not hooked into any processes/CI yet, but that will also come in next. Since it's not very smart, it actually runs quite fast (.8s on EE). The script also doesn't exit with a non-zero exit code when it finds a problem. Also will be solved as part of integrating it into CI.
66 lines
2.0 KiB
JavaScript
66 lines
2.0 KiB
JavaScript
import {promises as fs} from "fs";
|
|
import path from "path";
|
|
|
|
async function findInnerClassDefinitions(directory) {
|
|
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()) {
|
|
await findInnerClassDefinitions(filePath);
|
|
} else if (path.extname(filePath) === '.java') {
|
|
await processJavaFile(filePath);
|
|
}
|
|
}
|
|
} catch (err) {
|
|
console.error(err);
|
|
}
|
|
}
|
|
|
|
async function processJavaFile(filePath) {
|
|
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];
|
|
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 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("key is", key);
|
|
console.log("val is", match[2]);
|
|
console.log("pattern", valMatcher);
|
|
console.error(`Field ${key} in ${filePath} is not looking right.`);
|
|
}
|
|
}
|
|
}
|
|
|
|
// if (finds.length > 1) {
|
|
// console.error(`Found multiple inner class definitions in file: ${filePath}`);
|
|
// return;
|
|
// }
|
|
|
|
} catch (err) {
|
|
console.error(err);
|
|
}
|
|
}
|
|
|
|
const directoryPath = '.';
|
|
findInnerClassDefinitions(directoryPath);
|