diff --git a/CHANGELOG b/CHANGELOG index 05b2379..b78c0d2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,13 @@ CHANGELOG ========= +3.0.0 +----- + +* BREAKING: Replace goals for plugin: use 'check' and configuration/level (see README.md) +* Rules are properly listed in README.md alphabetically +* Add unit tests for plugin + 2.3.0 ----- diff --git a/README.md b/README.md index 98bcdf0..e0c3067 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ The ruleset includes checks from both the core Checkstyle library and from the S To use this ruleset add the plugin `kemitix-checktyle-ruleset-maven-plugin`. The `maven-checkstyle-plugin` will be included automatically. -The following goals implement increasingly strict rulesets: +The following levels implement increasingly strict rulesets: * 1-layout * 2-naming @@ -33,6 +33,13 @@ The following goals implement increasingly strict rulesets: * 4-tweaks * 5-complexity +### Change from 2.x + +In 2.x, the level was specified as the goal to invoke. In 3.x, there is only the 'check' goal. +The level is now specified as a configuration parameter. See the example below. + +### Example + ```` 2.1.0 @@ -45,11 +52,14 @@ The following goals implement increasingly strict rulesets: net.kemitix kemitix-checkstyle-ruleset-maven-plugin ${kemitix-checkstyle-ruleset.version} + + ${kemitix-checkstyle-ruleset.level} + validate - ${kemitix-checkstyle-ruleset.level} + check @@ -75,7 +85,7 @@ Rule|Level|Source|Enabled|Suppressable [AnnotationLocation](#annotationlocation)|layout|checkstyle|Yes| [AnnotationUseStyle](#annotationusestyle)|layout|checkstyle|Yes| [AnonInnerLength](#anoninnerlength)|complexity|checkstyle|Yes| -[ArrayTrailingComma](#arraytrailingcomma)|unspecified|checkstyle|| +[ArrayTrailingComma](#arraytrailingcomma)|tweaks|checkstyle|| [ArrayTypeStyle](#arraytypestyle)|layout|checkstyle|Yes| [AtclauseOrder](#atclauseorder)|javadoc|checkstyle|Yes| [AvoidConditionInversion](#avoidconditioninversion)|complexity|sevntu|| @@ -125,7 +135,7 @@ Rule|Level|Source|Enabled|Suppressable [FileTabCharacter](#filetabcharacter)|layout|checkstyle|Yes| [FinalClass](#finalclass)|complexity|checkstyle|Yes| [FinalizeImplementation](#finalizeimplementation)|unspecified|sevntu|| -[FinalLocalVariable](#finallocalvariable)|unspecified|checkstyle|| +[FinalLocalVariable](#finallocalvariable)|tweaks|checkstyle|| [FinalParameters](#finalparameters)|tweaks|checkstyle|Yes| [ForbidAnnotation](#forbidannotation)|unspecified|sevntu|| [ForbidCCommentsInMethods](#forbidccommentsinmethods)|layout|sevntu|Yes| @@ -275,22 +285,6 @@ The following is a list of each of the checks and the expectations each has on y Rules are listed in alphabetical order. -#### [RegexpOnFilename](http://checkstyle.sourceforge.net/config_regexp.html#RegexpOnFilename) - -Checks for the existence of forbidden java file names. - -File names are forbidden if they match the pattern `(.sync-conflict-| conflicted copy )`. - -N.B. only `*.java` files are checked. - -This check is intended to detect Syncthing and Dropbox conflict files. - -e.g. -```` -DataClass (Bob's conflicted copy 2017-03-11).java -DataClass.sync-conflict-20170311-1648.java -```` - #### [AbbreviationAsWordInName](http://checkstyle.sourceforge.net/config_naming.html#AbbreviationAsWordInName) Enforces proper `CamelCase` and avoids sequences of consecutive uppercase characters in identifiers. Does not apply to @Overridden methods. @@ -1749,6 +1743,22 @@ Checks for redundant modifiers. Checks for: * Inner interface declarations that are declared as static. * Class constructors. * Nested enum definitions that are declared as static. +#### [RegexpOnFilename](http://checkstyle.sourceforge.net/config_regexp.html#RegexpOnFilename) + +Checks for the existence of forbidden java file names. + +File names are forbidden if they match the pattern `(.sync-conflict-| conflicted copy )`. + +N.B. only `*.java` files are checked. + +This check is intended to detect Syncthing and Dropbox conflict files. + +e.g. +```` +DataClass (Bob's conflicted copy 2017-03-11).java +DataClass.sync-conflict-20170311-1648.java +```` + #### [RequireThis](http://checkstyle.sourceforge.net/config_coding.html#RequireThis) Checks that references to instance fields where a parameter name overlaps are qualified by `this.`. @@ -1940,12 +1950,12 @@ Prevents the use of `@SuppressWarnings` for the following checks: * [PackageDeclaration](#packagedeclaration) * [TypeName](#typename) * [VisibilityModifier](#visibilitymodifier) -#### [SuppressWarningsHolder](http://checkstyle.sourceforge.net/config_annotation.html#SuppressWarningsHolder) - -Used by Checkstyle to hold the checks to be suppressed from `@SuppressWarnings(...)` annotations. #### [SuppressWarningsFilter](http://checkstyle.sourceforge.net/config_annotation.html#SuppressWarningsFilter) Allows the use of the `@SuppressWarnings` annotation. +#### [SuppressWarningsHolder](http://checkstyle.sourceforge.net/config_annotation.html#SuppressWarningsHolder) + +Used by Checkstyle to hold the checks to be suppressed from `@SuppressWarnings(...)` annotations. #### [ThrowsCount](http://checkstyle.sourceforge.net/config_design.html#ThrowsCount) Restricts non-private methods to only `throws` 4 distinct Exception types. Exceptions should be hierarchical to allow catching suitable root Exceptions. @@ -2657,9 +2667,6 @@ Generic rule; doesn't embody a 'quality' check. As the sevntu check are considered experimental not all those that are not enabled are listed here. Only where they are disabled due to a conflict with my 'style' or there is another irreconcilable difference that prevents them from being enabled, will they be documented to prevent repeated investigations. -#### [ForbidWildcardAsReturnType](http://sevntu-checkstyle.github.io/sevntu.checkstyle/apidocs/com/github/sevntu/checkstyle/checks/design/ForbidWildcardAsReturnTypeCheck.html) - -Causes `NullPointerException` when used with `@Value.Immutables` from `org.immutables:value` #### [AvoidConditionInversion](http://sevntu-checkstyle.github.io/sevntu.checkstyle/apidocs/com/github/sevntu/checkstyle/checks/design/AvoidConditionInversionCheck.html) Should already be covered by [SimplifyBooleanExpression](simplifybooleanexpression). @@ -2696,6 +2703,9 @@ Generic rule; doesn't embody a 'quality' check. #### [ForbidThrowAnonymousExceptions](http://sevntu-checkstyle.github.io/sevntu.checkstyle/apidocs/com/github/sevntu/checkstyle/checks/coding/ForbidThrowAnonymousExceptionsCheck.html) [IllegalThrows](#illegalthrows) performs a similar check. +#### [ForbidWildcardAsReturnType](http://sevntu-checkstyle.github.io/sevntu.checkstyle/apidocs/com/github/sevntu/checkstyle/checks/design/ForbidWildcardAsReturnTypeCheck.html) + +Causes `NullPointerException` when used with `@Value.Immutables` from `org.immutables:value` #### [RequiredParameterForAnnotation](http://sevntu-checkstyle.github.io/sevntu.checkstyle/apidocs/com/github/sevntu/checkstyle/checks/annotation/RequiredParameterForAnnotationCheck.html) Generic rule; doesn't embody a 'quality' check. diff --git a/builder/pom.xml b/builder/pom.xml index fd099cc..6efcb69 100644 --- a/builder/pom.xml +++ b/builder/pom.xml @@ -7,12 +7,12 @@ net.kemitix kemitix-parent - 2.4.0 + 2.8.0 kemitix-checkstyle-ruleset-builder - 2.3.0 + 3.0.0 jar Kemitix Checkstyle Ruleset Builder @@ -37,9 +37,8 @@ 1.8 UTF-8 UTF-8 - 1.5.1.RELEASE - 1.16.12 - 3.6.2 + 1.5.3.RELEASE + 3.8.0 2.3.5 1.0.0 4.3.0 diff --git a/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/DefaultReadmeIndexBuilder.java b/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/DefaultReadmeIndexBuilder.java index 588f22c..fb7cad3 100644 --- a/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/DefaultReadmeIndexBuilder.java +++ b/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/DefaultReadmeIndexBuilder.java @@ -24,10 +24,8 @@ package net.kemitix.checkstyle.ruleset.builder; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; -import java.util.Comparator; import java.util.Locale; import java.util.Optional; -import java.util.function.Function; import java.util.stream.Collectors; /** @@ -49,15 +47,11 @@ public class DefaultReadmeIndexBuilder implements ReadmeIndexBuilder { public final String build() { return rulesProperties.getRules() .stream() - .sorted(Comparator.comparing(lowerCaseRuleName())) + .sorted(Rule::sortByName) .map(this::formatRuleRow) .collect(Collectors.joining(NEWLINE)); } - private Function lowerCaseRuleName() { - return this::getLowerCaseRuleName; - } - private String getLowerCaseRuleName(final Rule rule) { return rule.getName() .toLowerCase(LOCALE); diff --git a/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/ReadmeWriter.java b/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/ReadmeWriter.java index 09efffd..12d1c41 100644 --- a/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/ReadmeWriter.java +++ b/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/ReadmeWriter.java @@ -88,6 +88,7 @@ class ReadmeWriter implements CommandLineRunner { return rulesProperties.getRules() .stream() .filter(predicate) + .sorted(Rule::sortByName) .flatMap(ruleReadmeLoader::load) .collect(Collectors.joining(NEWLINE)); } 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 d408913..8e8055b 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 @@ -26,6 +26,7 @@ import lombok.Setter; import java.net.URI; import java.util.HashMap; +import java.util.Locale; import java.util.Map; /** @@ -37,6 +38,8 @@ import java.util.Map; @Getter public class Rule { + private static final Locale LOCALE = Locale.ENGLISH; + /** * The name of the rule's Check class. */ @@ -81,4 +84,24 @@ public class Rule { * Configuration properties. */ private final Map properties = new HashMap<>(); + + /** + * Compare two Rules lexicographically for sorting by rule name, ignoring case. + * + * @param left the first rule + * @param right the second rule + * + * @return the value 0 if the rules are equal; a value less than 0 if the left string is lexicographically less than + * the right string; and a value greater than 0 if the left string is lexicographically greater than the right + * string. + */ + static int sortByName(final Rule left, final Rule right) { + return left.getLowerCaseRuleName() + .compareTo(right.getLowerCaseRuleName()); + } + + private String getLowerCaseRuleName() { + return getName().toLowerCase(LOCALE); + } + } diff --git a/builder/src/main/resources/README-template.md b/builder/src/main/resources/README-template.md index 58c64ac..93250af 100644 --- a/builder/src/main/resources/README-template.md +++ b/builder/src/main/resources/README-template.md @@ -25,7 +25,7 @@ The ruleset includes checks from both the core Checkstyle library and from the S To use this ruleset add the plugin `kemitix-checktyle-ruleset-maven-plugin`. The `maven-checkstyle-plugin` will be included automatically. -The following goals implement increasingly strict rulesets: +The following levels implement increasingly strict rulesets: * 1-layout * 2-naming @@ -33,6 +33,13 @@ The following goals implement increasingly strict rulesets: * 4-tweaks * 5-complexity +### Change from 2.x + +In 2.x, the level was specified as the goal to invoke. In 3.x, there is only the 'check' goal. +The level is now specified as a configuration parameter. See the example below. + +### Example + ```` 2.1.0 @@ -45,11 +52,14 @@ The following goals implement increasingly strict rulesets: net.kemitix kemitix-checkstyle-ruleset-maven-plugin ${kemitix-checkstyle-ruleset.version} + + ${kemitix-checkstyle-ruleset.level} + validate - ${kemitix-checkstyle-ruleset.level} + check diff --git a/builder/src/main/resources/application.yml b/builder/src/main/resources/application.yml index 8d331fe..3380f3a 100644 --- a/builder/src/main/resources/application.yml +++ b/builder/src/main/resources/application.yml @@ -1182,7 +1182,7 @@ rules: - name: ArrayTrailingComma parent: TREEWALKER - level: TWEAK + level: TWEAKS enabled: false source: CHECKSTYLE uri: http://checkstyle.sourceforge.net/config_coding.html#ArrayTrailingComma @@ -1190,7 +1190,7 @@ rules: - name: FinalLocalVariable parent: TREEWALKER - level: TWEAK + level: TWEAKS enabled: false source: CHECKSTYLE uri: http://checkstyle.sourceforge.net/config_coding.html#FinalLocalVariable diff --git a/builder/src/test/java/net/kemitix/checkstyle/ruleset/builder/ReadmeWriterTest.java b/builder/src/test/java/net/kemitix/checkstyle/ruleset/builder/ReadmeWriterTest.java index f64ab97..bc45598 100644 --- a/builder/src/test/java/net/kemitix/checkstyle/ruleset/builder/ReadmeWriterTest.java +++ b/builder/src/test/java/net/kemitix/checkstyle/ruleset/builder/ReadmeWriterTest.java @@ -73,10 +73,10 @@ public class ReadmeWriterTest { "sd:sevntu-disabled" ); val rules = rulesProperties.getRules(); - final Rule checkstyleEnabled = rule(RuleSource.CHECKSTYLE, true); - final Rule checkstyleDisabled = rule(RuleSource.CHECKSTYLE, false); - final Rule sevntuEnabled = rule(RuleSource.SEVNTU, true); - final Rule sevntuDisabled = rule(RuleSource.SEVNTU, false); + final Rule checkstyleEnabled = rule(RuleSource.CHECKSTYLE, true, "checkstyle enabled"); + final Rule checkstyleDisabled = rule(RuleSource.CHECKSTYLE, false, "checkstyle disabled"); + final Rule sevntuEnabled = rule(RuleSource.SEVNTU, true, "sevntu enabled"); + final Rule sevntuDisabled = rule(RuleSource.SEVNTU, false, "sevntu disabled"); rules.add(checkstyleEnabled); rules.add(checkstyleDisabled); rules.add(sevntuEnabled); @@ -93,10 +93,33 @@ public class ReadmeWriterTest { assertThat(lines).containsExactlyElementsOf(expected); } - private Rule rule(final RuleSource source, final boolean enabled) { + private Rule rule(final RuleSource source, final boolean enabled, final String name) { val rule = new Rule(); + rule.setName(name); rule.setSource(source); rule.setEnabled(enabled); return rule; } + + @Test + public void rulesAreAlphabetical() throws Exception { + //given + val expected = Arrays.asList("ce:alpha", "beta", "delta"); + val rules = rulesProperties.getRules(); + final Rule alpha = rule(RuleSource.CHECKSTYLE, true, "alpha"); + final Rule beta = rule(RuleSource.CHECKSTYLE, true, "beta"); + final Rule delta = rule(RuleSource.CHECKSTYLE, true, "delta"); + rules.add(alpha); + rules.add(delta); + rules.add(beta); + given(indexBuilder.build()).willReturn("index"); + given(ruleReadmeLoader.load(alpha)).willReturn(Stream.of(alpha.getName())); + given(ruleReadmeLoader.load(beta)).willReturn(Stream.of(beta.getName())); + given(ruleReadmeLoader.load(delta)).willReturn(Stream.of(delta.getName())); + //when + readmeWriter.run(); + //then + final Stream lines = Files.lines(readme, StandardCharsets.UTF_8); + assertThat(lines).containsSequence(expected); + } } diff --git a/plugin-sample/pom.xml b/plugin-sample/pom.xml index fd93929..932f163 100644 --- a/plugin-sample/pom.xml +++ b/plugin-sample/pom.xml @@ -8,12 +8,12 @@ net.kemitix kemitix-checkstyle-ruleset-sample-parent - 2.3.0 + 3.0.0 ../sample-parent kemitix-checkstyle-ruleset-plugin-sample - 2.3.0 + 3.0.0 Kemitix Checkstyle Ruleset Plugin Sample Sample usage of the Kemitix Checkstyle Ruleset Plugin diff --git a/plugin/pom.xml b/plugin/pom.xml index d4c8c28..cc3447b 100644 --- a/plugin/pom.xml +++ b/plugin/pom.xml @@ -7,7 +7,7 @@ net.kemitix kemitix-checkstyle-ruleset-parent - 2.3.0 + 3.0.0 kemitix-checkstyle-ruleset-maven-plugin @@ -19,7 +19,7 @@ 1.8 UTF-8 UTF-8 - 3.3.9 + 3.5.0 3.6.1 3.5 3.5 @@ -27,9 +27,13 @@ 3.0.1 1.6 2.8.2 - 2.2.0 - 1.16.12 + 2.3.0 + 1.16.16 1.0.0 + 0.7.9 + 0.50 + 0.80 + 0 @@ -65,6 +69,16 @@ map-builder ${map-builder.version} + + org.assertj + assertj-core + test + + + org.mockito + mockito-core + test + @@ -96,6 +110,58 @@ 1.8 + + org.jacoco + jacoco-maven-plugin + ${jacoco-maven-plugin.version} + + + + prepare-agent + + + + report + prepare-package + + report + + + + default-check + + check + + + + + + + CLASS + + *HelpMojo + + + + LINE + COVEREDRATIO + ${jacoco-class-line-covered-ratio} + + + INSTRUCTION + COVEREDRATIO + ${jacoco-class-instruction-covered-ratio} + + + CLASS + MISSEDCOUNT + ${jacoco-class-missed-count-maximum} + + + + + + diff --git a/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/AbstractCheckMojo.java b/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/AbstractCheckMojo.java deleted file mode 100644 index b3a3102..0000000 --- a/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/AbstractCheckMojo.java +++ /dev/null @@ -1,167 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Paul Campbell - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -package net.kemitix.checkstyle.ruleset.plugin; - -import lombok.Setter; -import lombok.val; -import org.apache.maven.artifact.DefaultArtifact; -import org.apache.maven.artifact.handler.DefaultArtifactHandler; -import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.execution.MavenSession; -import org.apache.maven.model.Plugin; -import org.apache.maven.model.io.xpp3.MavenXpp3Reader; -import org.apache.maven.plugin.AbstractMojo; -import org.apache.maven.plugin.BuildPluginManager; -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.Component; -import org.apache.maven.plugins.annotations.Parameter; -import org.apache.maven.project.MavenProject; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; -import org.twdata.maven.mojoexecutor.MojoExecutor; - -import java.io.FileReader; -import java.io.IOException; -import java.util.Properties; - -/** - * Runs the Checkstyle Maven Plugin with the Kemitix Checkstyle Ruleset. - * - * @author Paul Campbell (pcampbell@kemitix.net) - */ -abstract class AbstractCheckMojo extends AbstractMojo { - - private static final String CHECKSTYLE_GROUPID = "com.puppycrawl.tools"; - - private static final String CHECKSTYLE_ARTIFACTID = "checkstyle"; - - private static final String SEVNTU_GROUPID = "com.github.sevntu.checkstyle"; - - private static final String SEVNTU_ARTIFACTID = "sevntu-checkstyle-maven-plugin"; - - private static final String KEMITIX_GROUPID = "net.kemitix"; - - private static final String KEMITIX_ARTIFACTID = "kemitix-checkstyle-ruleset"; - - private static final String APACHE_PLUGIN_GROUPID = "org.apache.maven.plugins"; - - private static final String APACHE_PLUGIN_ARTIFACTID = "maven-checkstyle-plugin"; - - private static final String CONFIG_LOCATION = "configLocation"; - - private static final String SOURCE_DIR = "sourceDirectory"; - - private String rulesetVersion; - - @Setter - @Parameter(defaultValue = "${project}", readonly = true) - private MavenProject mavenProject; - - @Setter - @Parameter(defaultValue = "${session}", readonly = true) - private MavenSession mavenSession; - - @Parameter(defaultValue = "${localRepository}", readonly = true, required = true) - private ArtifactRepository artifactRepository = null; - - @Component - private BuildPluginManager pluginManager = null; - - /** - * Execute Checkstyle Check. - * - * @param level The level of config file to use. - * - * @throws MojoExecutionException on execution error - * @throws MojoFailureException on execution failure - */ - final void performCheck(final String level) throws MojoExecutionException, MojoFailureException { - rulesetVersion = mavenProject.getPlugin(KEMITIX_GROUPID + ":" + KEMITIX_ARTIFACTID + "-maven-plugin") - .getVersion(); - debug("rulesetVersion: %s", rulesetVersion); - val properties = getProperties(); - debug("properties: %s", properties); - - // get versions from pom.xml properties - val pluginVersion = getProperty(properties, "maven-checkstyle-plugin.version"); - val checkstyleVersion = getProperty(properties, "checkstyle.version"); - val sevntuVersion = getProperty(properties, "sevntu.version"); - - // configure - val checkstylePlugin = getPlugin(pluginVersion, checkstyleVersion, sevntuVersion); - val configuration = MojoExecutor.configuration( - MojoExecutor.element(CONFIG_LOCATION, String.format("net/kemitix/checkstyle-%s.xml", level)), - MojoExecutor.element(SOURCE_DIR, mavenProject.getBuild().getSourceDirectory()) - ); - val environment = MojoExecutor.executionEnvironment(mavenProject, mavenSession, pluginManager); - - // run - info("Running Checkstyle %s (sevntu: %s) with ruleset %s (%s)", checkstyleVersion, sevntuVersion, level, - rulesetVersion - ); - MojoExecutor.executeMojo(checkstylePlugin, "check", configuration, environment); - info("Checkstyle complete"); - } - - private String getProperty(final Properties properties, final String key) { - val property = properties.getProperty(key); - debug(key + ": %s", property); - return property; - } - - private Plugin getPlugin(final String pluginVersion, final String checkstyleVersion, final String sevntuVersion) { - // create checkstyle dependencies - val checkstyle = MojoExecutor.dependency(CHECKSTYLE_GROUPID, CHECKSTYLE_ARTIFACTID, checkstyleVersion); - val sevntu = MojoExecutor.dependency(SEVNTU_GROUPID, SEVNTU_ARTIFACTID, sevntuVersion); - val ruleset = MojoExecutor.dependency(KEMITIX_GROUPID, KEMITIX_ARTIFACTID, rulesetVersion); - val dependencies = MojoExecutor.dependencies(checkstyle, sevntu, ruleset); - - return MojoExecutor.plugin(APACHE_PLUGIN_GROUPID, APACHE_PLUGIN_ARTIFACTID, pluginVersion, dependencies); - } - - private Properties getProperties() throws MojoFailureException { - // load properties from the plugin pom.xml - val pluginArtifactId = KEMITIX_ARTIFACTID + "-parent"; - val pluginArtifact = new DefaultArtifact(KEMITIX_GROUPID, pluginArtifactId, rulesetVersion, null, "", null, - new DefaultArtifactHandler("pom") - ); - try { - val pomReader = new FileReader(artifactRepository.find(pluginArtifact) - .getFile()); - return new MavenXpp3Reader().read(pomReader) - .getProperties(); - } catch (XmlPullParserException | IOException e) { - throw new MojoFailureException("Can't load properties from plugin's pom.xml", e); - } - } - - private void info(final String format, final Object... args) { - getLog().info(String.format(format, args)); - } - - private void debug(final String format, final Object... args) { - getLog().debug(String.format(format, args)); - } -} diff --git a/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/CheckConfiguration.java b/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/CheckConfiguration.java new file mode 100644 index 0000000..32572db --- /dev/null +++ b/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/CheckConfiguration.java @@ -0,0 +1,53 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2017 Paul Campbell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies + * or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package net.kemitix.checkstyle.ruleset.plugin; + +import lombok.Builder; +import lombok.Getter; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.plugin.BuildPluginManager; +import org.apache.maven.project.MavenProject; + +/** + * Configuration for performing a Checkstyle Check. + * + * @author Paul Campbell (pcampbell@kemitix.net) + */ +@Getter +@Builder +class CheckConfiguration { + + private MavenProject mavenProject; + + private MavenSession mavenSession; + + private ArtifactRepository artifactRepository; + + private BuildPluginManager pluginManager; + + private String rulesetVersion; + + private String sourceDirectory; + + private String level; +} diff --git a/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/CheckMojo.java b/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/CheckMojo.java new file mode 100644 index 0000000..5e01571 --- /dev/null +++ b/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/CheckMojo.java @@ -0,0 +1,102 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016 Paul Campbell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +package net.kemitix.checkstyle.ruleset.plugin; + +import lombok.Setter; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.Build; +import org.apache.maven.model.Plugin; +import org.apache.maven.model.io.xpp3.MavenXpp3Reader; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.BuildPluginManager; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.Component; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.project.MavenProject; + +/** + * Runs the Checkstyle Maven Plugin with the Kemitix Checkstyle Ruleset. + * + * @author Paul Campbell (pcampbell@kemitix.net) + */ +@Mojo(name = "check", defaultPhase = LifecyclePhase.VALIDATE) +public class CheckMojo extends AbstractMojo { + + private static final String KEMITIX_GROUPID = "net.kemitix"; + + private static final String KEMITIX_ARTIFACTID = "kemitix-checkstyle-ruleset"; + + @Setter + private CheckstyleExecutor checkstyleExecutor = + new DefaultCheckstyleExecutor(new DefaultPluginExecutor(), new MavenXpp3Reader()); + + @Setter + @Parameter(defaultValue = "${project}", readonly = true) + private MavenProject mavenProject; + + @Setter + @Parameter(defaultValue = "${session}", readonly = true) + private MavenSession mavenSession; + + @Setter + @Parameter(defaultValue = "${localRepository}", readonly = true, required = true) + private ArtifactRepository artifactRepository; + + @Parameter(defaultValue = "5-complexity", readonly = true) + private String level = "5-complexity"; + + @Setter + @Component + private BuildPluginManager pluginManager; + + @Override + public final void execute() throws MojoExecutionException, MojoFailureException { + checkstyleExecutor.setLog(getLog()); + CheckConfiguration config = getCheckConfiguration(); + checkstyleExecutor.performCheck(config); + } + + private CheckConfiguration getCheckConfiguration() { + final Plugin rulesetPlugin = getRulesetPlugin(); + final Build build = mavenProject.getBuild(); + return CheckConfiguration.builder() + .mavenProject(mavenProject) + .mavenSession(mavenSession) + .artifactRepository(artifactRepository) + .pluginManager(pluginManager) + .rulesetVersion(rulesetPlugin.getVersion()) + .sourceDirectory(build.getSourceDirectory()) + .level(level) + .build(); + } + + private Plugin getRulesetPlugin() { + return mavenProject.getPlugin(KEMITIX_GROUPID + ":" + KEMITIX_ARTIFACTID + "-maven-plugin"); + } +} diff --git a/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/CheckstyleExecutor.java b/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/CheckstyleExecutor.java new file mode 100644 index 0000000..212f3bf --- /dev/null +++ b/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/CheckstyleExecutor.java @@ -0,0 +1,46 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2017 Paul Campbell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies + * or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package net.kemitix.checkstyle.ruleset.plugin; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.logging.Log; + +/** + * Executes the Checkstyle plugin. + * + * @author Paul Campbell (pcampbell@kemitix.net) + */ +interface CheckstyleExecutor { + + /** + * Execute Checkstyle Check. + * + * @param configuration The Configuration + * + * @throws MojoExecutionException on execution error + * @throws MojoFailureException on execution failure + */ + void performCheck(CheckConfiguration configuration) throws MojoExecutionException, MojoFailureException; + + void setLog(Log log); +} diff --git a/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/ComplexityCheckMojo.java b/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/ComplexityCheckMojo.java deleted file mode 100644 index 94090c8..0000000 --- a/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/ComplexityCheckMojo.java +++ /dev/null @@ -1,44 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Paul Campbell - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -package net.kemitix.checkstyle.ruleset.plugin; - -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.LifecyclePhase; -import org.apache.maven.plugins.annotations.Mojo; - -/** - * Runs the Checkstyle Maven Plugin with the Kemitix Checkstyle Ruleset: COMPLEXITY, TWEAKS, JAVADOC, NAMING and LAYOUT. - * - * @author Paul Campbell (pcampbell@kemitix.net) - */ -@Mojo(name = "5-complexity", defaultPhase = LifecyclePhase.VALIDATE) -public class ComplexityCheckMojo extends AbstractCheckMojo { - - @Override - public void execute() throws MojoExecutionException, MojoFailureException { - performCheck("5-complexity"); - } -} diff --git a/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/DefaultCheckstyleExecutor.java b/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/DefaultCheckstyleExecutor.java new file mode 100644 index 0000000..24d8e7d --- /dev/null +++ b/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/DefaultCheckstyleExecutor.java @@ -0,0 +1,185 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2017 Paul Campbell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies + * or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package net.kemitix.checkstyle.ruleset.plugin; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.val; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.DefaultArtifact; +import org.apache.maven.artifact.handler.ArtifactHandler; +import org.apache.maven.artifact.handler.DefaultArtifactHandler; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.model.Dependency; +import org.apache.maven.model.Model; +import org.apache.maven.model.Plugin; +import org.apache.maven.model.io.xpp3.MavenXpp3Reader; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.logging.Log; +import org.codehaus.plexus.util.xml.Xpp3Dom; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.twdata.maven.mojoexecutor.MojoExecutor; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; +import java.util.List; +import java.util.Properties; + +/** + * Default implementation of {@link CheckstyleExecutor}. + * + * @author Paul Campbell (pcampbell@kemitix.net) + */ +@RequiredArgsConstructor +public class DefaultCheckstyleExecutor implements CheckstyleExecutor { + + private static final String CHECKSTYLE_GROUPID = "com.puppycrawl.tools"; + + private static final String CHECKSTYLE_ARTIFACTID = "checkstyle"; + + private static final String SEVNTU_GROUPID = "com.github.sevntu.checkstyle"; + + private static final String SEVNTU_ARTIFACTID = "sevntu-checkstyle-maven-plugin"; + + private static final String KEMITIX_GROUPID = "net.kemitix"; + + private static final String KEMITIX_ARTIFACTID = "kemitix-checkstyle-ruleset"; + + private static final String APACHE_PLUGIN_GROUPID = "org.apache.maven.plugins"; + + private static final String APACHE_PLUGIN_ARTIFACTID = "maven-checkstyle-plugin"; + + private static final String CONFIG_LOCATION = "configLocation"; + + private static final String SOURCE_DIR = "sourceDirectory"; + + private static final ArtifactHandler POM_ARTIFACT_HANDLER = new DefaultArtifactHandler("pom"); + + private static final String PLUGIN_ARTIFACT_ID = KEMITIX_ARTIFACTID + "-parent"; + + private final PluginExecutor pluginExecutor; + + private final MavenXpp3Reader mavenXpp3Reader; + + @Setter + @Getter + private Log log; + + private String rulesetVersion; + + @Override + public final void performCheck(final CheckConfiguration config) + throws MojoExecutionException, MojoFailureException { + rulesetVersion = config.getRulesetVersion(); + val properties = getProperties(config.getArtifactRepository()); + + // configure + val checkstylePlugin = getPlugin(properties); + final String sourceDirectory = config.getSourceDirectory(); + final String level = config.getLevel(); + info("Ruleset: %s", level); + final String configFile = String.format("net/kemitix/checkstyle-%s.xml", level); + final Xpp3Dom configuration = pluginExecutor.configuration(pluginExecutor.element(CONFIG_LOCATION, configFile), + pluginExecutor.element(SOURCE_DIR, sourceDirectory) + ); + final MojoExecutor.ExecutionEnvironment environment = pluginExecutor.executionEnvironment(config); + + // run + pluginExecutor.executeMojo(checkstylePlugin, "check", configuration, environment); + info("Checkstyle complete"); + } + + private String getProperty(final Properties properties, final String key) { + val property = properties.getProperty(key); + debug("%s: %s", key, property); + return property; + } + + private Plugin getPlugin(final Properties properties) { + // get versions from pom.xml properties + val pluginVersion = getProperty(properties, "maven-checkstyle-plugin.version"); + val checkstyleVersion = getProperty(properties, "checkstyle.version"); + val sevntuVersion = getProperty(properties, "sevntu.version"); + info("Checkstyle %s (plugin: %s, sevntu: %s, ruleset: %s)", checkstyleVersion, + pluginVersion, sevntuVersion, rulesetVersion + ); + + // create checkstyle dependencies + val checkstyle = getCheckstyleDependency(checkstyleVersion); + val sevntu = getSevntuDependency(sevntuVersion); + val ruleset = getRulesetDependency(); + final List dependencies = pluginExecutor.dependencies(checkstyle, sevntu, ruleset); + + return pluginExecutor.plugin(APACHE_PLUGIN_GROUPID, APACHE_PLUGIN_ARTIFACTID, pluginVersion, dependencies); + } + + private Dependency getRulesetDependency() { + return pluginExecutor.dependency(KEMITIX_GROUPID, KEMITIX_ARTIFACTID, rulesetVersion); + } + + private Dependency getSevntuDependency(final String sevntuVersion) { + return pluginExecutor.dependency(SEVNTU_GROUPID, SEVNTU_ARTIFACTID, sevntuVersion); + } + + private Dependency getCheckstyleDependency(final String checkstyleVersion) { + return pluginExecutor.dependency(CHECKSTYLE_GROUPID, CHECKSTYLE_ARTIFACTID, checkstyleVersion); + } + + private Properties getProperties(final ArtifactRepository artifactRepository) throws MojoFailureException { + // load properties from the plugin pom.xml + final Artifact pluginArtifact = getPluginArtifact(artifactRepository); + try { + final File pomFile = pluginArtifact.getFile(); + return parsePomFile(pomFile).getProperties(); + } catch (XmlPullParserException | IOException e) { + throw new MojoFailureException("Can't load properties from plugin's pom.xml", e); + } + } + + private Model parsePomFile(final File pomFile) throws IOException, XmlPullParserException { + final Reader pomReader = new FileReader(pomFile); + return mavenXpp3Reader.read(pomReader); + } + + private Artifact getPluginArtifact(final ArtifactRepository artifactRepository) { + final Artifact templateArtifact = getRulesetArtifactTemplate(); + return artifactRepository.find(templateArtifact); + } + + private DefaultArtifact getRulesetArtifactTemplate() { + return new DefaultArtifact(KEMITIX_GROUPID, PLUGIN_ARTIFACT_ID, rulesetVersion, null, "", null, + POM_ARTIFACT_HANDLER + ); + } + + private void info(final String format, final Object... args) { + getLog().info(String.format(format, args)); + } + + private void debug(final String format, final Object... args) { + getLog().debug(String.format(format, args)); + } +} diff --git a/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/DefaultPluginExecutor.java b/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/DefaultPluginExecutor.java new file mode 100644 index 0000000..b176c2d --- /dev/null +++ b/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/DefaultPluginExecutor.java @@ -0,0 +1,79 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2017 Paul Campbell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies + * or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package net.kemitix.checkstyle.ruleset.plugin; + +import org.apache.maven.model.Dependency; +import org.apache.maven.model.Plugin; +import org.apache.maven.plugin.MojoExecutionException; +import org.codehaus.plexus.util.xml.Xpp3Dom; +import org.twdata.maven.mojoexecutor.MojoExecutor; + +import java.util.List; + +/** + * Wrapper for {@link org.twdata.maven.mojoexecutor.MojoExecutor}. + * + * @author Paul Campbell (pcampbell@kemitix.net). + */ +public final class DefaultPluginExecutor implements PluginExecutor { + + @Override + public MojoExecutor.Element element(final String key, final String value) { + return MojoExecutor.element(key, value); + } + + @Override + public Xpp3Dom configuration(final MojoExecutor.Element... elements) { + return MojoExecutor.configuration(elements); + } + + @Override + public MojoExecutor.ExecutionEnvironment executionEnvironment(final CheckConfiguration config) { + return MojoExecutor.executionEnvironment( + config.getMavenProject(), config.getMavenSession(), config.getPluginManager()); + } + + @Override + public void executeMojo( + final Plugin plugin, final String goal, final Xpp3Dom configuration, + final MojoExecutor.ExecutionEnvironment env + ) throws MojoExecutionException { + MojoExecutor.executeMojo(plugin, goal, configuration, env); + } + + @Override + public Dependency dependency(final String groupid, final String artifactid, final String version) { + return MojoExecutor.dependency(groupid, artifactid, version); + } + + @Override + public List dependencies(final Dependency... dependencies) { + return MojoExecutor.dependencies(dependencies); + } + + @Override + public Plugin plugin( + final String groupid, final String artifactid, final String version, final List dependencies + ) { + return MojoExecutor.plugin(groupid, artifactid, version, dependencies); + } +} diff --git a/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/JavadocCheckMojo.java b/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/JavadocCheckMojo.java deleted file mode 100644 index 2952110..0000000 --- a/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/JavadocCheckMojo.java +++ /dev/null @@ -1,44 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Paul Campbell - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -package net.kemitix.checkstyle.ruleset.plugin; - -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.LifecyclePhase; -import org.apache.maven.plugins.annotations.Mojo; - -/** - * Runs the Checkstyle Maven Plugin with the Kemitix Checkstyle Ruleset: JAVADOC, NAMING and LAYOUT. - * - * @author Paul Campbell (pcampbell@kemitix.net) - */ -@Mojo(name = "3-javadoc", defaultPhase = LifecyclePhase.VALIDATE) -public class JavadocCheckMojo extends AbstractCheckMojo { - - @Override - public void execute() throws MojoExecutionException, MojoFailureException { - performCheck("3-javadoc"); - } -} diff --git a/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/LayoutCheckMojo.java b/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/LayoutCheckMojo.java deleted file mode 100644 index e6aee8e..0000000 --- a/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/LayoutCheckMojo.java +++ /dev/null @@ -1,44 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Paul Campbell - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -package net.kemitix.checkstyle.ruleset.plugin; - -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.LifecyclePhase; -import org.apache.maven.plugins.annotations.Mojo; - -/** - * Runs the Checkstyle Maven Plugin with the Kemitix Checkstyle Ruleset: LAYOUT. - * - * @author Paul Campbell (pcampbell@kemitix.net) - */ -@Mojo(name = "1-layout", defaultPhase = LifecyclePhase.VALIDATE) -public class LayoutCheckMojo extends AbstractCheckMojo { - - @Override - public void execute() throws MojoExecutionException, MojoFailureException { - performCheck("1-layout"); - } -} diff --git a/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/NamingCheckMojo.java b/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/NamingCheckMojo.java deleted file mode 100644 index a650885..0000000 --- a/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/NamingCheckMojo.java +++ /dev/null @@ -1,44 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Paul Campbell - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -package net.kemitix.checkstyle.ruleset.plugin; - -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.LifecyclePhase; -import org.apache.maven.plugins.annotations.Mojo; - -/** - * Runs the Checkstyle Maven Plugin with the Kemitix Checkstyle Rulesets: NAMING and LAYOUT. - * - * @author Paul Campbell (pcampbell@kemitix.net) - */ -@Mojo(name = "2-naming", defaultPhase = LifecyclePhase.VALIDATE) -public class NamingCheckMojo extends AbstractCheckMojo { - - @Override - public void execute() throws MojoExecutionException, MojoFailureException { - performCheck("2-naming"); - } -} diff --git a/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/PluginExecutor.java b/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/PluginExecutor.java new file mode 100644 index 0000000..91caeaf --- /dev/null +++ b/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/PluginExecutor.java @@ -0,0 +1,114 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2017 Paul Campbell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies + * or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package net.kemitix.checkstyle.ruleset.plugin; + +import org.apache.maven.model.Dependency; +import org.apache.maven.model.Plugin; +import org.apache.maven.plugin.MojoExecutionException; +import org.codehaus.plexus.util.xml.Xpp3Dom; +import org.twdata.maven.mojoexecutor.MojoExecutor; + +import java.util.List; + +/** + * Interface for wrapping calls to static methods on {@link org.twdata.maven.mojoexecutor.MojoExecutor}. + * + * @author Paul Campbell (pcampbell@kemitix.net). + */ +public interface PluginExecutor { + + /** + * Constructs the element with a textual body. + * + * @param name The element name + * @param value The element text value + * + * @return The element object + */ + MojoExecutor.Element element(String name, String value); + + /** + * Builds the configuration for the goal using Elements. + * + * @param elements A list of elements for the configuration section + * + * @return The elements transformed into the Maven-native XML format + */ + Xpp3Dom configuration(MojoExecutor.Element... elements); + + /** + * Constructs the {@link MojoExecutor.ExecutionEnvironment} instance fluently. + * + * @param configuration The Configuration + * + * @return The execution environment + */ + MojoExecutor.ExecutionEnvironment executionEnvironment(CheckConfiguration configuration); + + /** + * Entry point for executing a mojo. + * + * @param plugin The plugin to execute + * @param goal The goal to execute + * @param configuration The execution configuration + * @param env The execution environment + * + * @throws MojoExecutionException If there are any exceptions locating or executing the mojo + */ + void executeMojo( + Plugin plugin, String goal, Xpp3Dom configuration, MojoExecutor.ExecutionEnvironment env + ) throws MojoExecutionException; + + /** + * Defines a dependency. + * + * @param groupId The group id + * @param artifactId The artifact id + * @param version The plugin version + * + * @return the dependency instance + */ + Dependency dependency(String groupId, String artifactId, String version); + + /** + * Creates a list of dependencies. + * + * @param dependencies the dependencies + * + * @return A list of dependencies + */ + List dependencies(Dependency... dependencies); + + /** + * Defines a plugin. + * + * @param groupId The group id + * @param artifactId The artifact id + * @param version The plugin version + * @param dependencies The plugin dependencies + * + * @return The plugin instance + */ + Plugin plugin( + String groupId, String artifactId, String version, List dependencies + ); +} diff --git a/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/TweaksCheckMojo.java b/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/TweaksCheckMojo.java deleted file mode 100644 index 6cb2144..0000000 --- a/plugin/src/main/java/net/kemitix/checkstyle/ruleset/plugin/TweaksCheckMojo.java +++ /dev/null @@ -1,44 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Paul Campbell - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -package net.kemitix.checkstyle.ruleset.plugin; - -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.LifecyclePhase; -import org.apache.maven.plugins.annotations.Mojo; - -/** - * Runs the Checkstyle Maven Plugin with the Kemitix Checkstyle Ruleset: TWEAKS, JAVADOC, NAMING and LAYOUT. - * - * @author Paul Campbell (pcampbell@kemitix.net) - */ -@Mojo(name = "4-tweaks", defaultPhase = LifecyclePhase.VALIDATE) -public class TweaksCheckMojo extends AbstractCheckMojo { - - @Override - public void execute() throws MojoExecutionException, MojoFailureException { - performCheck("4-tweaks"); - } -} diff --git a/plugin/src/test/java/net/kemitix/checkstyle/ruleset/plugin/CheckConfigurationTest.java b/plugin/src/test/java/net/kemitix/checkstyle/ruleset/plugin/CheckConfigurationTest.java new file mode 100644 index 0000000..15c63ac --- /dev/null +++ b/plugin/src/test/java/net/kemitix/checkstyle/ruleset/plugin/CheckConfigurationTest.java @@ -0,0 +1,26 @@ +package net.kemitix.checkstyle.ruleset.plugin; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Paul Campbell (pcampbell@kemitix.net). + */ +public class CheckConfigurationTest { + + @Test + public void toStringCoverage() { + //given + final String rulesetVersion = "ruleset version"; + final String sourceDirectory = "source directory"; + //when + final String result = CheckConfiguration.builder() + .rulesetVersion(rulesetVersion) + .sourceDirectory(sourceDirectory) + .toString(); + //then + assertThat(result).contains("rulesetVersion=ruleset version") + .contains("sourceDirectory=source directory"); + } +} diff --git a/plugin/src/test/java/net/kemitix/checkstyle/ruleset/plugin/CheckMojoTest.java b/plugin/src/test/java/net/kemitix/checkstyle/ruleset/plugin/CheckMojoTest.java new file mode 100644 index 0000000..0008532 --- /dev/null +++ b/plugin/src/test/java/net/kemitix/checkstyle/ruleset/plugin/CheckMojoTest.java @@ -0,0 +1,80 @@ +package net.kemitix.checkstyle.ruleset.plugin; + +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.Build; +import org.apache.maven.model.Plugin; +import org.apache.maven.plugin.BuildPluginManager; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.project.MavenProject; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; +import static org.mockito.Matchers.any; + +/** + * Tests for {@link CheckMojo}. + * + * @author Paul Campbell (pcampbell@kemitix.net) + */ +public class CheckMojoTest { + + @Mock + private CheckstyleExecutor checkstyleExecutor; + + @Mock + private MavenProject mavenProject; + + @Mock + private MavenSession mavenSession; + + @Mock + private ArtifactRepository artifactRepository; + + @Mock + private BuildPluginManager pluginManager; + + @Captor + private ArgumentCaptor configuration; + + @Mock + private Plugin rulesetPlugin; + + @Mock + private Build build; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void canExecute() throws MojoFailureException, MojoExecutionException { + //given + final CheckMojo mojo = new CheckMojo(); + mojo.setCheckstyleExecutor(checkstyleExecutor); + mojo.setMavenProject(mavenProject); + mojo.setMavenSession(mavenSession); + mojo.setArtifactRepository(artifactRepository); + mojo.setPluginManager(pluginManager); + given(mavenProject.getPlugin(any())).willReturn(rulesetPlugin); + given(mavenProject.getBuild()).willReturn(build); + //when + mojo.execute(); + //then + then(checkstyleExecutor).should() + .performCheck(configuration.capture()); + assertThat(configuration.getValue()).returns(mavenProject, CheckConfiguration::getMavenProject) + .returns(mavenSession, CheckConfiguration::getMavenSession) + .returns(artifactRepository, CheckConfiguration::getArtifactRepository) + .returns(pluginManager, CheckConfiguration::getPluginManager); + } +} diff --git a/plugin/src/test/java/net/kemitix/checkstyle/ruleset/plugin/DefaultCheckstyleExecutorTest.java b/plugin/src/test/java/net/kemitix/checkstyle/ruleset/plugin/DefaultCheckstyleExecutorTest.java new file mode 100644 index 0000000..b230eeb --- /dev/null +++ b/plugin/src/test/java/net/kemitix/checkstyle/ruleset/plugin/DefaultCheckstyleExecutorTest.java @@ -0,0 +1,163 @@ +package net.kemitix.checkstyle.ruleset.plugin; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.Dependency; +import org.apache.maven.model.Model; +import org.apache.maven.model.Plugin; +import org.apache.maven.model.io.xpp3.MavenXpp3Reader; +import org.apache.maven.plugin.BuildPluginManager; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.logging.Log; +import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.util.xml.Xpp3Dom; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.twdata.maven.mojoexecutor.MojoExecutor; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; + +/** + * Tests for {@link DefaultCheckstyleExecutor}. + * + * @author Paul Campbell (pcampbell@kemitix.net) + */ +public class DefaultCheckstyleExecutorTest { + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Mock + private PluginExecutor pluginExecutor; + + @Mock + private MavenProject mavenProject; + + @Mock + private MavenSession mavenSession; + + @Mock + private ArtifactRepository artifactRepository; + + @Mock + private BuildPluginManager pluginManager; + + @Mock + private Plugin rulesetPlugin; + + @Mock + private Log log; + + private DefaultCheckstyleExecutor checkstyleExecutor; + + private String level; + + @Mock + private Artifact artifact; + + private File artifactFile; + + @Mock + private MavenXpp3Reader mavenXpp3Reader; + + @Mock + private Model pomModel; + + @Mock + private MojoExecutor.Element configElement; + + @Mock + private MojoExecutor.Element sourceElement; + + @Mock + private Xpp3Dom pluginConfig; + + @Mock + private MojoExecutor.ExecutionEnvironment env; + + @Mock + private Dependency checkstyle; + + @Mock + private Dependency sevntu; + + @Mock + private Dependency ruleset; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + level = "test level"; + checkstyleExecutor = new DefaultCheckstyleExecutor(pluginExecutor, mavenXpp3Reader); + checkstyleExecutor.setLog(log); + } + + @Test + public void canPerformCheck() + throws MojoFailureException, MojoExecutionException, IOException, XmlPullParserException { + //given + final CheckConfiguration configuration = CheckConfiguration.builder() + .mavenProject(mavenProject) + .mavenSession(mavenSession) + .artifactRepository(artifactRepository) + .pluginManager(pluginManager) + .rulesetVersion("ruleset version") + .level(level) + .build(); + + artifactFile = folder.newFile("pom.xml"); + given(artifactRepository.find(any())).willReturn(artifact); + given(artifact.getFile()).willReturn(artifactFile); + given(mavenXpp3Reader.read(any(FileReader.class))).willReturn(pomModel); + final Properties properties = new Properties(); + given(pomModel.getProperties()).willReturn(properties); + given(pluginExecutor.element(eq("configLocation"), any())).willReturn(configElement); + given(pluginExecutor.element(eq("sourceDirectory"), any())).willReturn(sourceElement); + given(pluginExecutor.configuration(configElement, sourceElement)).willReturn(pluginConfig); + given(pluginExecutor.executionEnvironment(configuration)).willReturn(env); + final List dependencies = new ArrayList<>(); + dependencies.add(checkstyle); + dependencies.add(sevntu); + dependencies.add(ruleset); + final String pluginVersion = "plugin version"; + final String checkstyleVersion = "checkstyle version"; + final String sevntuVersion = "sevntu version"; + final String rulesetVersion = "ruleset version"; + given(pluginExecutor.dependencies(checkstyle, sevntu, ruleset)).willReturn(dependencies); + given(pluginExecutor.dependency("com.puppycrawl.tools", "checkstyle", checkstyleVersion)).willReturn( + checkstyle); + given(pluginExecutor.dependency( + "com.github.sevntu.checkstyle", "sevntu-checkstyle-maven-plugin", sevntuVersion)).willReturn(sevntu); + given(pluginExecutor.dependency("net.kemitix", "kemtiix-checkstyle-ruleset", rulesetVersion)).willReturn( + ruleset); + properties.setProperty("maven-checkstyle-plugin.version", pluginVersion); + properties.setProperty("checkstyle.version", checkstyleVersion); + properties.setProperty("sevntu.version", sevntuVersion); + given(pluginExecutor.plugin( + eq("org.apache.maven.plugins"), eq("maven-checkstyle-plugin"), eq(pluginVersion), any())).willReturn( + rulesetPlugin); + //when + checkstyleExecutor.performCheck(configuration); + //then + + then(pluginExecutor).should() + .executeMojo(rulesetPlugin, "check", pluginConfig, env); + } +} diff --git a/plugin/src/test/java/net/kemitix/checkstyle/ruleset/plugin/DefaultPluginExecutorTest.java b/plugin/src/test/java/net/kemitix/checkstyle/ruleset/plugin/DefaultPluginExecutorTest.java new file mode 100644 index 0000000..9ce752c --- /dev/null +++ b/plugin/src/test/java/net/kemitix/checkstyle/ruleset/plugin/DefaultPluginExecutorTest.java @@ -0,0 +1,177 @@ +package net.kemitix.checkstyle.ruleset.plugin; + +import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.Dependency; +import org.apache.maven.model.Plugin; +import org.apache.maven.plugin.BuildPluginManager; +import org.apache.maven.plugin.InvalidPluginDescriptorException; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.PluginConfigurationException; +import org.apache.maven.plugin.PluginDescriptorParsingException; +import org.apache.maven.plugin.PluginManagerException; +import org.apache.maven.plugin.PluginNotFoundException; +import org.apache.maven.plugin.PluginResolutionException; +import org.apache.maven.plugin.descriptor.MojoDescriptor; +import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.configuration.PlexusConfiguration; +import org.codehaus.plexus.util.xml.Xpp3Dom; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.twdata.maven.mojoexecutor.MojoExecutor; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; + +/** + * Tests for {@link DefaultPluginExecutor}. + * + * @author Paul Campbell (pcampbell@kemitix.net) + */ +public class DefaultPluginExecutorTest { + + private PluginExecutor pluginExecutor; + + @Mock + private MavenProject mavenProject; + + @Mock + private MavenSession mavenSession; + + @Mock + private BuildPluginManager pluginManager; + + @Mock + private Plugin plugin; + + @Mock + private Xpp3Dom configuration; + + @Mock + private PluginDescriptor pluginDescriptor; + + @Mock + private MojoDescriptor mojoDescriptor; + + @Mock + private PlexusConfiguration mojoConfiguration; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + pluginExecutor = new DefaultPluginExecutor(); + } + + @Test + public void canElement() { + //when + final MojoExecutor.Element element = pluginExecutor.element("name", "value"); + //then + assertThat(element.toDom()).returns("name", Xpp3Dom::getName) + .returns("value", Xpp3Dom::getValue); + } + + @Test + public void canConfiguration() { + //given + final MojoExecutor.Element alpha = pluginExecutor.element("alpha", "first"); + final MojoExecutor.Element beta = pluginExecutor.element("beta", "second"); + //when + final Xpp3Dom configuration = pluginExecutor.configuration(alpha, beta); + //then + assertThat(configuration.getChild("alpha")).returns("alpha", Xpp3Dom::getName) + .returns("first", Xpp3Dom::getValue); + assertThat(configuration.getChild("beta")).returns("beta", Xpp3Dom::getName) + .returns("second", Xpp3Dom::getValue); + } + + @Test + public void canExecutionEnvironment() { + //given + final CheckConfiguration configuration = createCheckConfiguration(); + //when + final MojoExecutor.ExecutionEnvironment environment = pluginExecutor.executionEnvironment(configuration); + //then + assertThat(environment).returns(mavenProject, MojoExecutor.ExecutionEnvironment::getMavenProject) + .returns(mavenSession, MojoExecutor.ExecutionEnvironment::getMavenSession) + .returns(pluginManager, MojoExecutor.ExecutionEnvironment::getPluginManager); + } + + private CheckConfiguration createCheckConfiguration() { + return CheckConfiguration.builder() + .mavenProject(mavenProject) + .mavenSession(mavenSession) + .pluginManager(pluginManager) + .build(); + } + + @Test + public void canExecuteMojo() + throws MojoExecutionException, InvalidPluginDescriptorException, PluginResolutionException, + PluginDescriptorParsingException, PluginNotFoundException, PluginManagerException, + PluginConfigurationException, MojoFailureException { + //given + final String goal = "check"; + final MojoExecutor.ExecutionEnvironment environment = + pluginExecutor.executionEnvironment(createCheckConfiguration()); + given(mavenSession.getCurrentProject()).willReturn(mavenProject); + given(pluginManager.loadPlugin(eq(plugin), any(), any())).willReturn(pluginDescriptor); + given(pluginDescriptor.getMojo(goal)).willReturn(mojoDescriptor); + given(mojoDescriptor.getMojoConfiguration()).willReturn(mojoConfiguration); + given(mojoConfiguration.getAttributeNames()).willReturn(new String[]{}); + given(mojoConfiguration.getChildren()).willReturn(new PlexusConfiguration[]{}); + //when + pluginExecutor.executeMojo(plugin, goal, configuration, environment); + //then + then(pluginManager).should() + .executeMojo(eq(mavenSession), any()); + } + + @Test + public void canDependency() { + //given + final String groupId = "groupId"; + final String artifactId = "artifactId"; + final String version = "version"; + //when + final Dependency dependency = pluginExecutor.dependency(groupId, artifactId, version); + //then + assertThat(dependency).returns(groupId, Dependency::getGroupId) + .returns(artifactId, Dependency::getArtifactId) + .returns(version, Dependency::getVersion); + } + + @Test + public void canDependencies() { + //given + final Dependency dependency = pluginExecutor.dependency("groupId", "artifactId", "version"); + //when + final List dependencies = pluginExecutor.dependencies(dependency); + //then + assertThat(dependencies).containsExactly(dependency); + } + + @Test + public void canPlugin() { + //given + final String groupId = "groupId"; + final String artifactId = "artifactId"; + final String version = "version"; + final List dependencies = pluginExecutor.dependencies(pluginExecutor.dependency("pg", "pa", "pv")); + //when + final Plugin plugin = pluginExecutor.plugin(groupId, artifactId, version, dependencies); + //then + assertThat(plugin).returns(groupId, Plugin::getGroupId) + .returns(artifactId, Plugin::getArtifactId) + .returns(version, Plugin::getVersion) + .returns(dependencies, Plugin::getDependencies); + } +} diff --git a/pom.xml b/pom.xml index 1604305..7417e62 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ net.kemitix kemitix-checkstyle-ruleset-parent - 2.3.0 + 3.0.0 pom Kemitix Checkstyle Ruleset (Parent) @@ -23,6 +23,8 @@ 2.17 7.6.1 1.23.1 + 1.10.19 + 3.8.0 @@ -133,6 +135,21 @@ + + + + org.mockito + mockito-core + ${mockito.version} + + + org.assertj + assertj-core + ${assertj.version} + + + + sonatype-nexus-snapshots diff --git a/regressions/pom.xml b/regressions/pom.xml index cf9b4bb..ffc5933 100644 --- a/regressions/pom.xml +++ b/regressions/pom.xml @@ -5,7 +5,7 @@ kemitix-checkstyle-ruleset-sample-parent net.kemitix - 2.3.0 + 3.0.0 ../sample-parent 4.0.0 diff --git a/ruleset/pom.xml b/ruleset/pom.xml index 9268290..82c61de 100644 --- a/ruleset/pom.xml +++ b/ruleset/pom.xml @@ -7,11 +7,11 @@ net.kemitix kemitix-checkstyle-ruleset-parent - 2.3.0 + 3.0.0 kemitix-checkstyle-ruleset - 2.3.0 + 3.0.0 jar Kemitix Checkstyle Ruleset diff --git a/sample-parent/pom.xml b/sample-parent/pom.xml index 28ea834..f6b1661 100644 --- a/sample-parent/pom.xml +++ b/sample-parent/pom.xml @@ -8,7 +8,7 @@ kemitix-checkstyle-ruleset-sample-parent pom - 2.3.0 + 3.0.0 Kemitix Checkstyle Ruleset Sample Parent Sample parent for modules that use kemitix-checkstyle-ruleset-maven-plugin @@ -51,11 +51,14 @@ net.kemitix kemitix-checkstyle-ruleset-maven-plugin ${project.version} + + ${kemitix-checkstyle-ruleset-level} + validate - ${kemitix-checkstyle-ruleset-level} + check