From 423255b704fdc0d52fcf50e7deca4c6aa1c13284 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Fri, 9 Mar 2018 19:51:08 +0000 Subject: [PATCH 1/6] ruleset: update to match kemitix-pmd-ruleset FileLength: restrict to 500 lines JavaNCSS: reduce limits (class & file 250, method 12) MethodCount: reduce to 10 MethodLength: reduce to 30 --- builder/src/main/resources/application.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/builder/src/main/resources/application.yml b/builder/src/main/resources/application.yml index 7d504a7..5d888f0 100644 --- a/builder/src/main/resources/application.yml +++ b/builder/src/main/resources/application.yml @@ -296,6 +296,8 @@ rules: enabled: true source: CHECKSTYLE uri: http://checkstyle.sourceforge.net/config_sizes.html#FileLength + properties: + max: 500 - name: FileTabCharacter parent: CHECKER @@ -463,9 +465,9 @@ rules: source: CHECKSTYLE uri: http://checkstyle.sourceforge.net/config_metrics.html#JavaNCSS properties: - classMaximum: 1200 - fileMaximum: 1600 - methodMaximum: 40 + classMaximum: 250 + fileMaximum: 250 + methodMaximum: 12 - name: LeftCurly parent: TREEWALKER @@ -518,7 +520,7 @@ rules: source: CHECKSTYLE uri: http://checkstyle.sourceforge.net/config_sizes.html#MethodCount properties: - maxTotal: 30 + maxTotal: 10 - name: MethodLength parent: TREEWALKER @@ -527,7 +529,7 @@ rules: source: CHECKSTYLE uri: http://checkstyle.sourceforge.net/config_sizes.html#MethodLength properties: - max: 40 + max: 30 - name: MethodName parent: TREEWALKER From de5530e696cbb5e48772684db7d6691158a17501 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Fri, 9 Mar 2018 19:51:08 +0000 Subject: [PATCH 2/6] ruleset: update ruleset XML to match kemitix-pmd-ruleset FileLength: restrict to 500 lines JavaNCSS: reduce limits (class & file 250, method 12) MethodCount: reduce to 10 MethodLength: reduce to 30 --- .../net/kemitix/checkstyle-5-complexity.xml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/ruleset/src/main/resources/net/kemitix/checkstyle-5-complexity.xml b/ruleset/src/main/resources/net/kemitix/checkstyle-5-complexity.xml index 87eebaa..75bdce0 100644 --- a/ruleset/src/main/resources/net/kemitix/checkstyle-5-complexity.xml +++ b/ruleset/src/main/resources/net/kemitix/checkstyle-5-complexity.xml @@ -8,7 +8,9 @@ - + + + @@ -97,9 +99,9 @@ - - - + + + @@ -110,10 +112,10 @@ - + - + From 77394ad5d34d62b4d0470367c3de8c09c09e386b Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Sun, 11 Mar 2018 16:24:41 +0000 Subject: [PATCH 3/6] builder: refactoring to reduce complexity --- builder/pom.xml | 6 + .../ruleset/builder/CheckstyleWriter.java | 114 ++++++++++-------- .../checkstyle/ruleset/builder/Rule.java | 71 +++++++++++ 3 files changed, 142 insertions(+), 49 deletions(-) diff --git a/builder/pom.xml b/builder/pom.xml index 18f07d5..73d39c3 100644 --- a/builder/pom.xml +++ b/builder/pom.xml @@ -31,6 +31,7 @@ 1.0.0 2.13.0 3.9.0 + 0.3.0 2.18.1 3.0.0 @@ -59,6 +60,11 @@ ${lombok.version} provided + + net.kemitix + conditional + ${conditional.version} + io.github.lukehutch fast-classpath-scanner diff --git a/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleWriter.java b/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleWriter.java index 5c9e137..54a55d9 100644 --- a/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleWriter.java +++ b/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleWriter.java @@ -21,21 +21,22 @@ package net.kemitix.checkstyle.ruleset.builder; -import com.speedment.common.mapstream.MapStream; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import lombok.val; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; +import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import java.util.Arrays; -import java.util.Map; +import java.nio.file.Path; +import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; +import static java.util.Arrays.asList; + /** * Writes the Checkstyle XML files. * @@ -46,8 +47,6 @@ import java.util.stream.Stream; @RequiredArgsConstructor class CheckstyleWriter implements CommandLineRunner { - private static final String NEWLINE = System.getProperty("line.separator"); - private final OutputProperties outputProperties; private final TemplateProperties templateProperties; @@ -56,62 +55,79 @@ class CheckstyleWriter implements CommandLineRunner { private final RuleClassLocator ruleClassLocator; + private static Predicate excludeUnspecifiedRuleLevel() { + return level -> !level.equals(RuleLevel.UNSPECIFIED); + } + + private static void writeRuleset( + final Path filePath, + final String content + ) throws IOException { + Files.write(filePath, asList(content.split(System.lineSeparator())), StandardCharsets.UTF_8); + } + + private static String ruleset( + final String checkerRules, + final String treeWalkerRules, + final String template + ) { + return String.format(template, checkerRules, treeWalkerRules); + } + + private static boolean fileExists(final File file) { + return file.exists(); + } + + private static void writeCheckstyleFileWithException( + final Path outputPath, + final String checkerRules, + final String treeWalkerRules, + final Path template + ) throws IOException { + if (fileExists(template.toFile())) { + log.info("Writing ruleset: {}", outputPath); + final String xmlTemplate = new String(Files.readAllBytes(template), StandardCharsets.UTF_8); + writeRuleset(outputPath, ruleset(checkerRules, treeWalkerRules, xmlTemplate)); + } else { + throw new TemplateNotFoundException(template); + } + } + @Override public void run(final String... args) { Stream.of(RuleLevel.values()) - .filter(level -> !level.equals(RuleLevel.UNSPECIFIED)) - .forEach(this::writeCheckstyleFile); + .filter(excludeUnspecifiedRuleLevel()) + .forEach(this::writeCheckstyleFile); } private void writeCheckstyleFile(final RuleLevel ruleLevel) { - val xmlFile = outputProperties.getDirectory() - .resolve(outputProperties.getRulesetFiles() - .get(ruleLevel)); - val checkerRules = rulesProperties.getRules() - .stream() - .filter(Rule::isEnabled) - .filter(rule -> RuleParent.CHECKER.equals(rule.getParent())) - .filter(rule -> ruleLevel.compareTo(rule.getLevel()) >= 0) - .map(this::formatRuleAsModule) - .collect(Collectors.joining(NEWLINE)); - val treeWalkerRules = rulesProperties.getRules() - .stream() - .filter(Rule::isEnabled) - .filter(rule -> RuleParent.TREEWALKER.equals(rule.getParent())) - .filter(rule -> ruleLevel.compareTo(rule.getLevel()) >= 0) - .map(this::formatRuleAsModule) - .collect(Collectors.joining(NEWLINE)); + final Path outputPath = outputPath(ruleLevel); + final String checkerRules = enabledRules(ruleLevel, RuleParent.CHECKER); + final String treeWalkerRules = enabledRules(ruleLevel, RuleParent.TREEWALKER); + final Path template = templateProperties.getCheckstyleXml(); try { - val checkstyleXmlTemplate = templateProperties.getCheckstyleXml(); - if (checkstyleXmlTemplate.toFile() - .exists()) { - val bytes = Files.readAllBytes(checkstyleXmlTemplate); - val template = new String(bytes, StandardCharsets.UTF_8); - val output = Arrays.asList(String.format(template, checkerRules, treeWalkerRules) - .split(NEWLINE)); - log.info("Writing xmlFile: {}", xmlFile); - Files.write(xmlFile, output, StandardCharsets.UTF_8); - } else { - throw new TemplateNotFoundException(checkstyleXmlTemplate); - } + writeCheckstyleFileWithException(outputPath, checkerRules, treeWalkerRules, template); } catch (IOException e) { throw new CheckstyleWriterException(e); } } - private String formatRuleAsModule(final Rule rule) { - if (rule.getProperties() - .isEmpty()) { - return String.format("", ruleClassLocator.apply(rule)); - } - return String.format("%n %s%n", ruleClassLocator.apply(rule), - formatProperties(rule.getProperties()) - ); + private Path outputPath(final RuleLevel ruleLevel) { + return outputProperties.getDirectory() + .resolve(outputProperties.getRulesetFiles() + .get(ruleLevel)); } - private String formatProperties(final Map properties) { - return MapStream.of(properties) - .map((k, v) -> String.format("", k, v)) - .collect(Collectors.joining(NEWLINE)); + private String enabledRules( + final RuleLevel ruleLevel, + final RuleParent ruleParent + ) { + return rulesProperties.getRules() + .stream() + .filter(Rule::isEnabled) + .filter(Rule.hasParent(ruleParent)) + .filter(Rule.isIncludedInLevel(ruleLevel)) + .map(rule -> Rule.asModule(ruleClassLocator.apply(rule), rule)) + .collect(Collectors.joining(System.lineSeparator())); } } diff --git a/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/Rule.java b/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/Rule.java index 33c5624..30848f7 100644 --- a/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/Rule.java +++ b/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/Rule.java @@ -21,13 +21,17 @@ package net.kemitix.checkstyle.ruleset.builder; +import com.speedment.common.mapstream.MapStream; import lombok.Getter; import lombok.Setter; +import net.kemitix.conditional.Value; import java.net.URI; import java.util.HashMap; import java.util.Locale; import java.util.Map; +import java.util.function.Predicate; +import java.util.stream.Collectors; /** * A single Checkstyle Check. @@ -40,6 +44,10 @@ public class Rule { private static final Locale LOCALE = Locale.ENGLISH; + private static final String MODULE_NO_PROPERTIES = ""; + + private static final String MODULE_WITH_PROPERTIES = "%n %s%n"; + /** * Configuration properties. */ @@ -100,6 +108,69 @@ public class Rule { .compareTo(right.getLowerCaseRuleName()); } + /** + * Predicate to check that the Rule has the given RuleParent. + * + * @param ruleParent the RuleParent to match + * + * @return a Predicate to check a Rule + */ + static Predicate hasParent(final RuleParent ruleParent) { + return rule -> ruleParent.equals(rule.getParent()); + } + + + /** + * Predicate to check that the Rule is included in the given RuleLevel. + * + * @param ruleLevel the RuleLevel to match + * + * @return a Predicate to check a Rule + */ + static Predicate isIncludedInLevel(final RuleLevel ruleLevel) { + return rule -> ruleLevel.compareTo(rule.getLevel()) >= 0; + } + + private static String formatProperties(final Map properties) { + return MapStream.of(properties) + .map((k, v) -> String.format("", k, v)) + .collect(Collectors.joining(System.lineSeparator())); + } + + private static boolean hasProperties(final Rule rule) { + return !rule.getProperties().isEmpty(); + } + + /** + * Formats the Rule as an XML module fragment. + * + * @param rule the Rule to format + * @param ruleClassname the classname for the Rule + * + * @return an XML {@code } fragment + */ + static String asModule( + final String ruleClassname, + final Rule rule + ) { + return Value.where(hasProperties(rule)) + .then(() -> moduleWithParameters(rule, ruleClassname)) + .otherwise(() -> moduleNoParameters(ruleClassname)); + } + + private static String moduleNoParameters( + final String ruleClassname + ) { + return String.format(MODULE_NO_PROPERTIES, ruleClassname); + } + + private static String moduleWithParameters( + final Rule rule, + final String ruleClassname + ) { + return String.format(MODULE_WITH_PROPERTIES, ruleClassname, formatProperties(rule.getProperties())); + } + private String getLowerCaseRuleName() { return getName().toLowerCase(LOCALE); } From 6c083e073d056c4913cd19f7d32988f7937f883c Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Sun, 11 Mar 2018 16:40:53 +0000 Subject: [PATCH 4/6] jenkins: set java.version for Java Next build and a note --- Jenkinsfile.groovy | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Jenkinsfile.groovy b/Jenkinsfile.groovy index 53c9049..af48017 100644 --- a/Jenkinsfile.groovy +++ b/Jenkinsfile.groovy @@ -48,14 +48,17 @@ pipeline { stage('Build Java Next') { steps { withMaven(maven: 'maven', jdk: 'JDK Next') { - sh "${mvn} clean install" + sh "${mvn} clean install -Djava.version=9" + //TODO: check that git status is still clean - i.e. builder didn't update any rulesets } } } stage('Build Java LTS') { steps { withMaven(maven: 'maven', jdk: 'JDK LTS') { + sh "${mvn} clean install" + //TODO: check that git status is still clean - i.e. builder didn't update any rulesets } } } From 82a0f162ed5ffff7d2dfcd667d4b6e873bd0eea0 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Sun, 11 Mar 2018 18:41:43 +0000 Subject: [PATCH 5/6] mvn: upgrade to maven 3.5.3 --- .mvn/wrapper/maven-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 56bb016..b573bb5 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1 +1 @@ -distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip \ No newline at end of file +distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.3/apache-maven-3.5.3-bin.zip From 8d88f9153aefc83856ed6eb42c6b0d402d8a1a3d Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Sun, 11 Mar 2018 18:52:15 +0000 Subject: [PATCH 6/6] jenkins: use upgraded maven-enforcer-plugin for java 9 compatibility --- Jenkinsfile.groovy | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Jenkinsfile.groovy b/Jenkinsfile.groovy index af48017..baea78b 100644 --- a/Jenkinsfile.groovy +++ b/Jenkinsfile.groovy @@ -48,7 +48,7 @@ pipeline { stage('Build Java Next') { steps { withMaven(maven: 'maven', jdk: 'JDK Next') { - sh "${mvn} clean install -Djava.version=9" + sh "${mvn} clean install -Djava.version=9 -Dmaven-enforcer-plugin.version=3.0.0-M1" //TODO: check that git status is still clean - i.e. builder didn't update any rulesets } } @@ -56,7 +56,6 @@ pipeline { stage('Build Java LTS') { steps { withMaven(maven: 'maven', jdk: 'JDK LTS') { - sh "${mvn} clean install" //TODO: check that git status is still clean - i.e. builder didn't update any rulesets }