Implementation Repo for JSONCustomLintr
Highlighting simplicity and gradle build integration
The file structure for this repo is pretty simple.
src/
java.main/
linting/
linting.rules/
ArraySizeRule.java
DisallowedStringRule.java
JSONObjectKeyRule.java
linting.Register.java
linting.Runner.java
In our linting.rules folder we have a static method which will generate our LintRule
to be used in the linting.Register.java
file.
An example lint rule to prevent Array sizes from becoming too large is ArraySizeRule.java
which looks like:
/**
* Prevent Arrays from being certain over size
*/
public class ArraySizeRule {
private static final int MAX_ARRAY_SIZE = 3;
private static final String ISSUE_ID = "Array Size Rule";
public static LintRule getArraySizeRule() throws LintRule.Builder.LintRuleBuilderException {
LintImplementation<JSONArray> maxArraySizeImplementation = new LintImplementation<JSONArray>() {
@Override
public Class<?> getClazz() {
return JSONArray.class;
}
@Override
public boolean shouldReport(JSONArray jsonArray) {
return jsonArray.toList().size() > MAX_ARRAY_SIZE;
}
@Override
public String report(JSONArray jsonArray) {
return "JSONArray with contents " + jsonArray.toString() + " has more than " + MAX_ARRAY_SIZE + " objects";
}
};
return new LintRule.Builder()
.setImplementation(maxArraySizeImplementation)
.setIssueId(ISSUE_ID)
.setLevel(LintLevel.ERROR)
.build();
}
}
We simply make a LintImplementation
and build it into our LintRule
.
After that we register all of our linting.rules in linting.Register.java
as so:
public class linting.Register {
public static LintRegister getLintRegister() {
LintRegister lintRegister = new LintRegister();
try {
lintRegister.register(
ArraySizeRule.getArraySizeRule(),
DisallowedStringRule.getDissalowedStringRule(),
JSONObjectKeyRule.getJsonObjectKeyRule()
);
} catch (LintRule.Builder.LintRuleBuilderException e) {
throw new RuntimeException("Error in rule creation.");
}
return lintRegister;
}
}
We then use the LintRegister
in the main linting.Runner.java
class.
public class linting.Runner {
public static void main(String[] args) {
if (args.length != 1) {
System.exit(1);
}
String filePath = args[0];
ReportRunner reportRunner =
new ReportRunner(new LintRunner(linting.Register.getLintRegister(), filePath));
reportRunner.report("build/reports");
}
}
The ReportRunner
class handles setting exit codes if we fail a lint check.
In this repo we implemented a gradle task to be able to be tied into any build integration we want to do with out project.
In the build.gradle
we made a simple task to run our main method.
task lintJson(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = 'linting.Runner'
args './src/resources'
}
Since our ReportRunner
class handles exit codes automatically for us, we can simply tie this build task however we want into our pipeline and we will either fail or succeed based on our lint status.
When trying to hook up to existing repos we can take 2 approaches:
- Make lint linting.rules in an existing project that holds our json files (as seen here)
- Make a separate library to hold our json lint linting.rules, import into an existing project, and set up a build integration from there.