Merge branch 'release/3.0.0'

* release/3.0.0:
  CHANGELOG
  pom.xml: version set to 3.0.0
  KCR22: builder: sort rules alphabetically
  version: set to 3.0.0-SNAPSHOT
  API Change: plugin: level is specified as a configuration parameter
  plugin: AbstractCheckMojo: minor tidy-up
  plugin: CheckConfiguration: simple builder toString coverage test
  plugin: DefaultPluginExecutorTest: added
  plugin: DefaultCheckstyleExecutorTest: added
  plugin: AbstractCheckMojoTest: added
  plugin: pom.xml: enable jacoco support
  plugin: extract CheckConfiguration and variour other refactorings
  plugin: add assertj and mockito test dependencies
  plugin: CheckstyleExecutor: extracted from AbstractCheckMojo
  plugin: AbstractCheckMojo: replace abstract execute() with getLevel()
  README.md,application.yml: fix typo
  plugin: AbstractCheckMojo: use PluginExecutor
  plugin: PluginExecutor: add wrapper for static methods on MojoExecutor
  {builder,plugin}: pom.xml: upgrades
  pom.xml: version set to 2.4.0-SNAPSHOT
This commit is contained in:
Paul Campbell 2017-05-27 16:46:44 +01:00
commit f7a90cedfd
31 changed files with 1237 additions and 446 deletions

View file

@ -1,6 +1,13 @@
CHANGELOG 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 2.3.0
----- -----

View file

@ -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`. To use this ruleset add the plugin `kemitix-checktyle-ruleset-maven-plugin`.
The `maven-checkstyle-plugin` will be included automatically. The `maven-checkstyle-plugin` will be included automatically.
The following goals implement increasingly strict rulesets: The following levels implement increasingly strict rulesets:
* 1-layout * 1-layout
* 2-naming * 2-naming
@ -33,6 +33,13 @@ The following goals implement increasingly strict rulesets:
* 4-tweaks * 4-tweaks
* 5-complexity * 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
```` ````
<properties> <properties>
<kemitix-checkstyle-ruleset.version>2.1.0</kemitix-checkstyle-ruleset.version> <kemitix-checkstyle-ruleset.version>2.1.0</kemitix-checkstyle-ruleset.version>
@ -45,11 +52,14 @@ The following goals implement increasingly strict rulesets:
<groupId>net.kemitix</groupId> <groupId>net.kemitix</groupId>
<artifactId>kemitix-checkstyle-ruleset-maven-plugin</artifactId> <artifactId>kemitix-checkstyle-ruleset-maven-plugin</artifactId>
<version>${kemitix-checkstyle-ruleset.version}</version> <version>${kemitix-checkstyle-ruleset.version}</version>
<configuration>
<level>${kemitix-checkstyle-ruleset.level}</level>
</configuration>
<executions> <executions>
<execution> <execution>
<phase>validate</phase> <phase>validate</phase>
<goals> <goals>
<goal>${kemitix-checkstyle-ruleset.level}</goal> <goal>check</goal>
</goals> </goals>
</execution> </execution>
</executions> </executions>
@ -75,7 +85,7 @@ Rule|Level|Source|Enabled|Suppressable
[AnnotationLocation](#annotationlocation)|layout|checkstyle|Yes| [AnnotationLocation](#annotationlocation)|layout|checkstyle|Yes|
[AnnotationUseStyle](#annotationusestyle)|layout|checkstyle|Yes| [AnnotationUseStyle](#annotationusestyle)|layout|checkstyle|Yes|
[AnonInnerLength](#anoninnerlength)|complexity|checkstyle|Yes| [AnonInnerLength](#anoninnerlength)|complexity|checkstyle|Yes|
[ArrayTrailingComma](#arraytrailingcomma)|unspecified|checkstyle|| [ArrayTrailingComma](#arraytrailingcomma)|tweaks|checkstyle||
[ArrayTypeStyle](#arraytypestyle)|layout|checkstyle|Yes| [ArrayTypeStyle](#arraytypestyle)|layout|checkstyle|Yes|
[AtclauseOrder](#atclauseorder)|javadoc|checkstyle|Yes| [AtclauseOrder](#atclauseorder)|javadoc|checkstyle|Yes|
[AvoidConditionInversion](#avoidconditioninversion)|complexity|sevntu|| [AvoidConditionInversion](#avoidconditioninversion)|complexity|sevntu||
@ -125,7 +135,7 @@ Rule|Level|Source|Enabled|Suppressable
[FileTabCharacter](#filetabcharacter)|layout|checkstyle|Yes| [FileTabCharacter](#filetabcharacter)|layout|checkstyle|Yes|
[FinalClass](#finalclass)|complexity|checkstyle|Yes| [FinalClass](#finalclass)|complexity|checkstyle|Yes|
[FinalizeImplementation](#finalizeimplementation)|unspecified|sevntu|| [FinalizeImplementation](#finalizeimplementation)|unspecified|sevntu||
[FinalLocalVariable](#finallocalvariable)|unspecified|checkstyle|| [FinalLocalVariable](#finallocalvariable)|tweaks|checkstyle||
[FinalParameters](#finalparameters)|tweaks|checkstyle|Yes| [FinalParameters](#finalparameters)|tweaks|checkstyle|Yes|
[ForbidAnnotation](#forbidannotation)|unspecified|sevntu|| [ForbidAnnotation](#forbidannotation)|unspecified|sevntu||
[ForbidCCommentsInMethods](#forbidccommentsinmethods)|layout|sevntu|Yes| [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. 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) #### [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. 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. * Inner interface declarations that are declared as static.
* Class constructors. * Class constructors.
* Nested enum definitions that are declared as static. * 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) #### [RequireThis](http://checkstyle.sourceforge.net/config_coding.html#RequireThis)
Checks that references to instance fields where a parameter name overlaps are qualified by `this.`. 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) * [PackageDeclaration](#packagedeclaration)
* [TypeName](#typename) * [TypeName](#typename)
* [VisibilityModifier](#visibilitymodifier) * [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) #### [SuppressWarningsFilter](http://checkstyle.sourceforge.net/config_annotation.html#SuppressWarningsFilter)
Allows the use of the `@SuppressWarnings` annotation. 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) #### [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. 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. 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) #### [AvoidConditionInversion](http://sevntu-checkstyle.github.io/sevntu.checkstyle/apidocs/com/github/sevntu/checkstyle/checks/design/AvoidConditionInversionCheck.html)
Should already be covered by [SimplifyBooleanExpression](simplifybooleanexpression). 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) #### [ForbidThrowAnonymousExceptions](http://sevntu-checkstyle.github.io/sevntu.checkstyle/apidocs/com/github/sevntu/checkstyle/checks/coding/ForbidThrowAnonymousExceptionsCheck.html)
[IllegalThrows](#illegalthrows) performs a similar check. [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) #### [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. Generic rule; doesn't embody a 'quality' check.

View file

@ -7,12 +7,12 @@
<parent> <parent>
<groupId>net.kemitix</groupId> <groupId>net.kemitix</groupId>
<artifactId>kemitix-parent</artifactId> <artifactId>kemitix-parent</artifactId>
<version>2.4.0</version> <version>2.8.0</version>
<relativePath/> <relativePath/>
</parent> </parent>
<artifactId>kemitix-checkstyle-ruleset-builder</artifactId> <artifactId>kemitix-checkstyle-ruleset-builder</artifactId>
<version>2.3.0</version> <version>3.0.0</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>Kemitix Checkstyle Ruleset Builder</name> <name>Kemitix Checkstyle Ruleset Builder</name>
@ -37,9 +37,8 @@
<java.version>1.8</java.version> <java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>1.5.1.RELEASE</spring-boot.version> <spring-boot.version>1.5.3.RELEASE</spring-boot.version>
<lombok.version>1.16.12</lombok.version> <assertj.version>3.8.0</assertj.version>
<assertj.version>3.6.2</assertj.version>
<mapstream.version>2.3.5</mapstream.version> <mapstream.version>2.3.5</mapstream.version>
<map-builder.version>1.0.0</map-builder.version> <map-builder.version>1.0.0</map-builder.version>
<coveralls-maven-plugin.version>4.3.0</coveralls-maven-plugin.version> <coveralls-maven-plugin.version>4.3.0</coveralls-maven-plugin.version>

View file

@ -24,10 +24,8 @@ package net.kemitix.checkstyle.ruleset.builder;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.Comparator;
import java.util.Locale; import java.util.Locale;
import java.util.Optional; import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -49,15 +47,11 @@ public class DefaultReadmeIndexBuilder implements ReadmeIndexBuilder {
public final String build() { public final String build() {
return rulesProperties.getRules() return rulesProperties.getRules()
.stream() .stream()
.sorted(Comparator.comparing(lowerCaseRuleName())) .sorted(Rule::sortByName)
.map(this::formatRuleRow) .map(this::formatRuleRow)
.collect(Collectors.joining(NEWLINE)); .collect(Collectors.joining(NEWLINE));
} }
private Function<Rule, String> lowerCaseRuleName() {
return this::getLowerCaseRuleName;
}
private String getLowerCaseRuleName(final Rule rule) { private String getLowerCaseRuleName(final Rule rule) {
return rule.getName() return rule.getName()
.toLowerCase(LOCALE); .toLowerCase(LOCALE);

View file

@ -88,6 +88,7 @@ class ReadmeWriter implements CommandLineRunner {
return rulesProperties.getRules() return rulesProperties.getRules()
.stream() .stream()
.filter(predicate) .filter(predicate)
.sorted(Rule::sortByName)
.flatMap(ruleReadmeLoader::load) .flatMap(ruleReadmeLoader::load)
.collect(Collectors.joining(NEWLINE)); .collect(Collectors.joining(NEWLINE));
} }

View file

@ -26,6 +26,7 @@ import lombok.Setter;
import java.net.URI; import java.net.URI;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale;
import java.util.Map; import java.util.Map;
/** /**
@ -37,6 +38,8 @@ import java.util.Map;
@Getter @Getter
public class Rule { public class Rule {
private static final Locale LOCALE = Locale.ENGLISH;
/** /**
* The name of the rule's Check class. * The name of the rule's Check class.
*/ */
@ -81,4 +84,24 @@ public class Rule {
* Configuration properties. * Configuration properties.
*/ */
private final Map<String, String> properties = new HashMap<>(); private final Map<String, String> 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);
}
} }

View file

@ -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`. To use this ruleset add the plugin `kemitix-checktyle-ruleset-maven-plugin`.
The `maven-checkstyle-plugin` will be included automatically. The `maven-checkstyle-plugin` will be included automatically.
The following goals implement increasingly strict rulesets: The following levels implement increasingly strict rulesets:
* 1-layout * 1-layout
* 2-naming * 2-naming
@ -33,6 +33,13 @@ The following goals implement increasingly strict rulesets:
* 4-tweaks * 4-tweaks
* 5-complexity * 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
```` ````
<properties> <properties>
<kemitix-checkstyle-ruleset.version>2.1.0</kemitix-checkstyle-ruleset.version> <kemitix-checkstyle-ruleset.version>2.1.0</kemitix-checkstyle-ruleset.version>
@ -45,11 +52,14 @@ The following goals implement increasingly strict rulesets:
<groupId>net.kemitix</groupId> <groupId>net.kemitix</groupId>
<artifactId>kemitix-checkstyle-ruleset-maven-plugin</artifactId> <artifactId>kemitix-checkstyle-ruleset-maven-plugin</artifactId>
<version>${kemitix-checkstyle-ruleset.version}</version> <version>${kemitix-checkstyle-ruleset.version}</version>
<configuration>
<level>${kemitix-checkstyle-ruleset.level}</level>
</configuration>
<executions> <executions>
<execution> <execution>
<phase>validate</phase> <phase>validate</phase>
<goals> <goals>
<goal>${kemitix-checkstyle-ruleset.level}</goal> <goal>check</goal>
</goals> </goals>
</execution> </execution>
</executions> </executions>

View file

@ -1182,7 +1182,7 @@ rules:
- -
name: ArrayTrailingComma name: ArrayTrailingComma
parent: TREEWALKER parent: TREEWALKER
level: TWEAK level: TWEAKS
enabled: false enabled: false
source: CHECKSTYLE source: CHECKSTYLE
uri: http://checkstyle.sourceforge.net/config_coding.html#ArrayTrailingComma uri: http://checkstyle.sourceforge.net/config_coding.html#ArrayTrailingComma
@ -1190,7 +1190,7 @@ rules:
- -
name: FinalLocalVariable name: FinalLocalVariable
parent: TREEWALKER parent: TREEWALKER
level: TWEAK level: TWEAKS
enabled: false enabled: false
source: CHECKSTYLE source: CHECKSTYLE
uri: http://checkstyle.sourceforge.net/config_coding.html#FinalLocalVariable uri: http://checkstyle.sourceforge.net/config_coding.html#FinalLocalVariable

View file

@ -73,10 +73,10 @@ public class ReadmeWriterTest {
"sd:sevntu-disabled" "sd:sevntu-disabled"
); );
val rules = rulesProperties.getRules(); val rules = rulesProperties.getRules();
final Rule checkstyleEnabled = rule(RuleSource.CHECKSTYLE, true); final Rule checkstyleEnabled = rule(RuleSource.CHECKSTYLE, true, "checkstyle enabled");
final Rule checkstyleDisabled = rule(RuleSource.CHECKSTYLE, false); final Rule checkstyleDisabled = rule(RuleSource.CHECKSTYLE, false, "checkstyle disabled");
final Rule sevntuEnabled = rule(RuleSource.SEVNTU, true); final Rule sevntuEnabled = rule(RuleSource.SEVNTU, true, "sevntu enabled");
final Rule sevntuDisabled = rule(RuleSource.SEVNTU, false); final Rule sevntuDisabled = rule(RuleSource.SEVNTU, false, "sevntu disabled");
rules.add(checkstyleEnabled); rules.add(checkstyleEnabled);
rules.add(checkstyleDisabled); rules.add(checkstyleDisabled);
rules.add(sevntuEnabled); rules.add(sevntuEnabled);
@ -93,10 +93,33 @@ public class ReadmeWriterTest {
assertThat(lines).containsExactlyElementsOf(expected); 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(); val rule = new Rule();
rule.setName(name);
rule.setSource(source); rule.setSource(source);
rule.setEnabled(enabled); rule.setEnabled(enabled);
return rule; 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<String> lines = Files.lines(readme, StandardCharsets.UTF_8);
assertThat(lines).containsSequence(expected);
}
} }

View file

@ -8,12 +8,12 @@
<parent> <parent>
<groupId>net.kemitix</groupId> <groupId>net.kemitix</groupId>
<artifactId>kemitix-checkstyle-ruleset-sample-parent</artifactId> <artifactId>kemitix-checkstyle-ruleset-sample-parent</artifactId>
<version>2.3.0</version> <version>3.0.0</version>
<relativePath>../sample-parent</relativePath> <relativePath>../sample-parent</relativePath>
</parent> </parent>
<artifactId>kemitix-checkstyle-ruleset-plugin-sample</artifactId> <artifactId>kemitix-checkstyle-ruleset-plugin-sample</artifactId>
<version>2.3.0</version> <version>3.0.0</version>
<name>Kemitix Checkstyle Ruleset Plugin Sample</name> <name>Kemitix Checkstyle Ruleset Plugin Sample</name>
<description>Sample usage of the Kemitix Checkstyle Ruleset Plugin</description> <description>Sample usage of the Kemitix Checkstyle Ruleset Plugin</description>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>net.kemitix</groupId> <groupId>net.kemitix</groupId>
<artifactId>kemitix-checkstyle-ruleset-parent</artifactId> <artifactId>kemitix-checkstyle-ruleset-parent</artifactId>
<version>2.3.0</version> <version>3.0.0</version>
</parent> </parent>
<artifactId>kemitix-checkstyle-ruleset-maven-plugin</artifactId> <artifactId>kemitix-checkstyle-ruleset-maven-plugin</artifactId>
@ -19,7 +19,7 @@
<java.version>1.8</java.version> <java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.version>3.3.9</maven.version> <maven.version>3.5.0</maven.version>
<maven-compiler-plugin.version>3.6.1</maven-compiler-plugin.version> <maven-compiler-plugin.version>3.6.1</maven-compiler-plugin.version>
<maven-plugin-plugin.version>3.5</maven-plugin-plugin.version> <maven-plugin-plugin.version>3.5</maven-plugin-plugin.version>
<maven-plugin-annotations.version>3.5</maven-plugin-annotations.version> <maven-plugin-annotations.version>3.5</maven-plugin-annotations.version>
@ -27,9 +27,13 @@
<maven-source-plugin.version>3.0.1</maven-source-plugin.version> <maven-source-plugin.version>3.0.1</maven-source-plugin.version>
<maven-gpg-plugin.version>1.6</maven-gpg-plugin.version> <maven-gpg-plugin.version>1.6</maven-gpg-plugin.version>
<maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version> <maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version>
<mojo-executor.version>2.2.0</mojo-executor.version> <mojo-executor.version>2.3.0</mojo-executor.version>
<lombok.version>1.16.12</lombok.version> <lombok.version>1.16.16</lombok.version>
<map-builder.version>1.0.0</map-builder.version> <map-builder.version>1.0.0</map-builder.version>
<jacoco-maven-plugin.version>0.7.9</jacoco-maven-plugin.version>
<jacoco-class-line-covered-ratio>0.50</jacoco-class-line-covered-ratio>
<jacoco-class-instruction-covered-ratio>0.80</jacoco-class-instruction-covered-ratio>
<jacoco-class-missed-count-maximum>0</jacoco-class-missed-count-maximum>
</properties> </properties>
<dependencies> <dependencies>
@ -65,6 +69,16 @@
<artifactId>map-builder</artifactId> <artifactId>map-builder</artifactId>
<version>${map-builder.version}</version> <version>${map-builder.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>
@ -96,6 +110,58 @@
<target>1.8</target> <target>1.8</target>
</configuration> </configuration>
</plugin><!-- maven-compiler-plugin --> </plugin><!-- maven-compiler-plugin -->
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco-maven-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>default-check</id>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
<configuration>
<rules>
<rule>
<element>CLASS</element>
<excludes>
<exclude>*HelpMojo</exclude>
</excludes>
<limits>
<limit>
<counter>LINE</counter>
<value>COVEREDRATIO</value>
<minimum>${jacoco-class-line-covered-ratio}</minimum>
</limit>
<limit>
<counter>INSTRUCTION</counter>
<value>COVEREDRATIO</value>
<minimum>${jacoco-class-instruction-covered-ratio}</minimum>
</limit>
<limit>
<counter>CLASS</counter>
<value>MISSEDCOUNT</value>
<maximum>${jacoco-class-missed-count-maximum}</maximum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</plugin><!-- jacoco-maven-plugin -->
</plugins> </plugins>
</build> </build>
<profiles> <profiles>

View file

@ -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));
}
}

View file

@ -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;
}

View file

@ -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");
}
}

View file

@ -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);
}

View file

@ -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");
}
}

View file

@ -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<Dependency> 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));
}
}

View file

@ -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<Dependency> dependencies(final Dependency... dependencies) {
return MojoExecutor.dependencies(dependencies);
}
@Override
public Plugin plugin(
final String groupid, final String artifactid, final String version, final List<Dependency> dependencies
) {
return MojoExecutor.plugin(groupid, artifactid, version, dependencies);
}
}

View file

@ -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");
}
}

View file

@ -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");
}
}

View file

@ -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");
}
}

View file

@ -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<Dependency> 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<Dependency> dependencies
);
}

View file

@ -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");
}
}

View file

@ -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");
}
}

View file

@ -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<CheckConfiguration> 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);
}
}

View file

@ -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<Dependency> 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);
}
}

View file

@ -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<Dependency> 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<Dependency> 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);
}
}

19
pom.xml
View file

@ -6,7 +6,7 @@
<groupId>net.kemitix</groupId> <groupId>net.kemitix</groupId>
<artifactId>kemitix-checkstyle-ruleset-parent</artifactId> <artifactId>kemitix-checkstyle-ruleset-parent</artifactId>
<version>2.3.0</version> <version>3.0.0</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>Kemitix Checkstyle Ruleset (Parent)</name> <name>Kemitix Checkstyle Ruleset (Parent)</name>
@ -23,6 +23,8 @@
<maven-checkstyle-plugin.version>2.17</maven-checkstyle-plugin.version> <maven-checkstyle-plugin.version>2.17</maven-checkstyle-plugin.version>
<checkstyle.version>7.6.1</checkstyle.version> <checkstyle.version>7.6.1</checkstyle.version>
<sevntu.version>1.23.1</sevntu.version> <sevntu.version>1.23.1</sevntu.version>
<mockito.version>1.10.19</mockito.version>
<assertj.version>3.8.0</assertj.version>
</properties> </properties>
<modules> <modules>
@ -133,6 +135,21 @@
</profile><!-- release --> </profile><!-- release -->
</profiles> </profiles>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<distributionManagement> <distributionManagement>
<snapshotRepository> <snapshotRepository>
<id>sonatype-nexus-snapshots</id> <id>sonatype-nexus-snapshots</id>

View file

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>kemitix-checkstyle-ruleset-sample-parent</artifactId> <artifactId>kemitix-checkstyle-ruleset-sample-parent</artifactId>
<groupId>net.kemitix</groupId> <groupId>net.kemitix</groupId>
<version>2.3.0</version> <version>3.0.0</version>
<relativePath>../sample-parent</relativePath> <relativePath>../sample-parent</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View file

@ -7,11 +7,11 @@
<parent> <parent>
<groupId>net.kemitix</groupId> <groupId>net.kemitix</groupId>
<artifactId>kemitix-checkstyle-ruleset-parent</artifactId> <artifactId>kemitix-checkstyle-ruleset-parent</artifactId>
<version>2.3.0</version> <version>3.0.0</version>
</parent> </parent>
<artifactId>kemitix-checkstyle-ruleset</artifactId> <artifactId>kemitix-checkstyle-ruleset</artifactId>
<version>2.3.0</version> <version>3.0.0</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>Kemitix Checkstyle Ruleset</name> <name>Kemitix Checkstyle Ruleset</name>

View file

@ -8,7 +8,7 @@
<artifactId>kemitix-checkstyle-ruleset-sample-parent</artifactId> <artifactId>kemitix-checkstyle-ruleset-sample-parent</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<version>2.3.0</version> <version>3.0.0</version>
<name>Kemitix Checkstyle Ruleset Sample Parent</name> <name>Kemitix Checkstyle Ruleset Sample Parent</name>
<description>Sample parent for modules that use kemitix-checkstyle-ruleset-maven-plugin</description> <description>Sample parent for modules that use kemitix-checkstyle-ruleset-maven-plugin</description>
@ -51,11 +51,14 @@
<groupId>net.kemitix</groupId> <groupId>net.kemitix</groupId>
<artifactId>kemitix-checkstyle-ruleset-maven-plugin</artifactId> <artifactId>kemitix-checkstyle-ruleset-maven-plugin</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
<configuration>
<level>${kemitix-checkstyle-ruleset-level}</level>
</configuration>
<executions> <executions>
<execution> <execution>
<phase>validate</phase> <phase>validate</phase>
<goals> <goals>
<goal>${kemitix-checkstyle-ruleset-level}</goal> <goal>check</goal>
</goals> </goals>
</execution> </execution>
</executions> </executions>