1. Introduction
Enforce build and project settings. A port of the popular maven-enforcer-plugin.
2. Usage
2.1. Applying the plugin
There are two modes for applying the plugin: build and project
Add the following to your settings.gradle
file
buildscript {
repositories {
mavenCentral()
gradlePluginPortal()
}
dependencies {
classpath 'org.kordamp.gradle:enforcer-gradle-plugin:0.14.0'
}
}
apply plugin: 'org.kordamp.gradle.enforcer'
enforce {
// configure rules
}
Add the following to a project build file (build.gradle
)
Option #1
buildscript {
repositories {
mavenCentral()
gradlePluginPortal()
}
dependencies {
classpath 'org.kordamp.gradle:enforcer-gradle-plugin:0.14.0'
}
}
apply plugin: 'org.kordamp.gradle.project-enforcer'
enforce {
// configure rules
}
Option #2
plugins {
id 'org.kordamp.gradle.project-enforcer' version '0.14.0'
}
enforce {
// configure rules
}
2.3. Rule DSL
There are two variations of the Rule DSL depending on which mode (build or project) you are running the plugin
void configure(Class<? extends Action<? extends BuildEnforcerExtension>> configurerClass)
Configures build rules based on a classpath resource. Useful for sharing rule definitions across different builds.
Example:
import org.gradle.api.Action;
public class MyEnforcerRulesConfigurer implements Action<BuildEnforcerExtension> {
@Override
public void execute(BuildEnforcerExtension extension) {
extension.rule(AlwaysPass.class);
}
}
void configure(Class<? extends Action<? extends ProjectEnforcerExtension>> configurerClass)
Configures project rules based on a classpath resource. Useful for sharing rule definitions across different builds.
Example:
import org.gradle.api.Action;
public class MyEnforcerRulesConfigurer implements Action<ProjectEnforcerExtension> {
@Override
public void execute(ProjectEnforcerExtension extension) {
extension.rule(AlwaysPass.class);
}
}
<R extends EnforcerRule> void rule(Class<R> ruleType)
<R extends EnforcerRule> void rule(Class<R> ruleType, Action<R> configurer)
Defines a rule for the build. Use the configurer
variant if you need to configure the rule. Note that this configuration
will be applied lazily, that is, when the rule is about to be invoked.
Rules will be executed in the following phases:
BEFORE_BUILD
, BEFORE_PROJECT
, AFTER_PROJECT
, PROJECTS_EVALUATED
, AFTER_BUILD
.
<R extends EnforcerRule> void rule(Class<R> ruleType)
<R extends EnforcerRule> void rule(Class<R> ruleType, Action<R> configurer)
Defines a rule for the current project. Use the configurer
variant if you need to configure the rule. Note that this configuration
will be applied lazily, that is, when the rule is about to be invoked.
Rules will be executed in the following phases:
BEFORE_PROJECT
, AFTER_PROJECT
.
void allprojects(Action<? extends EnforcerRuleConfiguration> configurer)
Configures rules for all projects. Rules will be executed in the following phases:
BEFORE_PROJECT
, AFTER_PROJECT
.
void project(String projectPath, Action<? extends EnforcerRuleConfiguration> configurer)
Configures rules for a single project. Rules will be executed in the following phases:
BEFORE_PROJECT
, AFTER_PROJECT
.
void projects(List<String> projectPaths, Action<? extends EnforcerRuleConfiguration> configurer)
Configures rules for a group of projects. Rules will be executed in the following phases:
BEFORE_PROJECT
, AFTER_PROJECT
.
The DSL exposes the following properties regardless of the mode choice
Name | Type | Default | Required | Description |
---|---|---|---|---|
enabled |
Property<Boolean> |
|
Enables or disables all rules. |
|
failFast |
Property<Boolean> |
|
Fails and reports the first rule violation if set to |
|
mergeStrategy |
MergeStrategy |
MergeStrategy.OVERRIDE |
Controls how duplicate rule definitions should be handled. |
|
enforcerLevel |
Property<EnforcerLevel> |
EnforcerLevel.ERROR |
Fails the build if set to |
2.4. MergeStrategy
The mergeStrategy
property takes effect when duplicate rule definitions are encountered during the configuration phase.
Duplicate rule definitions may occur when configuring the enforcer using any of the two configure() variants. Once a value for
this property is set it cannot be changed, thus it’s a good idea to set it in your build before invoking
configure() if you need your build to have a choice in how duplicates should be handled.
OVERRIDE |
The last configuration action wins. All previous configuration(s) (if any) will be discarded. |
APPEND |
Executes all configurations on a single rule instance, in FIFO order. |
PREPEND |
Executes all configurations on a single rule instance, in LIFO order. |
DUPLICATE |
Creates a duplicate rule with no shared configuration. |
DENY |
Does not allow configuration to be changed. First (if any) wins. |
2.5. Enforcer Phase
Rules are invoked during phases. A single rule may trigger for more than one phase during a build. The following list shows all possible values and the order of invocation.
BEFORE_BUILD |
After |
BEFORE_PROJECTS |
When projects have been loaded and before any is evaluated. |
BEFORE_PROJECT |
When a project is about to be evaluated. |
AFTER_PROJECT |
When a project has been evaluated. |
AFTER_PROJECTS |
When all projects have been evaluated. |
AFTER_BUILD |
When the build finishes. |
If rules are configured using the org.kordamp.gradle.project-enforcer plugin then they will only trigger during the
BEFORE_PROJECT (if project is not Root), AFTER_PROJECT , AFTER_PROJECTS , and AFTER_BUILD phases.
|
2.6. Enforcer Level
The enforcer may configured to fail the build when a rule triggers if its enforcerLevel
is set to ERROR
or
if any of the triggered rules has its enforcerLevel
set to ERROR
.
ERROR |
Fail the build when a rule triggers. |
WARN |
Do not fail the build when a rule triggers. |
2.7. Version Ranges
Some rules require a version range. The following table describes the supported formats and their meanings
Range | Meaning |
---|---|
1.0 |
x >= 1.0 |
(,1.0] |
x ⇐ 1.0 |
(,1.0) |
x < 1.0 |
[1.0] |
x == 1.0 |
[1.0,) |
x >= 1.0 |
(1.0,) |
x > 1.0 |
(1.0,2.0) |
1.0 < x < 2.0 |
[1.0,2.0] |
1.0 ⇐ x ⇐ 2.0 |
(,1.0],[1.2,) |
x ⇐ 1.0 or x >= 1.2. Multiple sets are comma-separated |
(,1.1),(1.1,) |
x != 1.1 |
2.8. System Properties
The behavior of the enforcer and configured rules can be changed with the following System
properties
- enforcer.enabled
-
Enables of disables all enforcer rules.
- enforcer.fail.fast
-
Fails and reports the first rule violation if set to
true
otherwise reports all rule violations within the same phase. - enforcer.phase.<phase-name>.enabled
-
Enables or disables all rules in the given phase. The value of
phase-name
must be any of the enforcer phases, in lower case; a.
may be used instead of_
. - <rule-class-name>.enabled
-
Enables or disables a specific rule. The value of
rule-class-name
is the fully qualified classname of the rule.
2.9. Comparison to Maven
The following table shows rules available to both plugins
Rule | Maven | Gradle |
---|---|---|
BanCircularDependencies |
||
BanDistributionManagement |
||
BanDuplicatePomDependencyVersions |
||
BanTransitiveDependencies |
||
EvaluateBeanshell |
||
ReactorModuleConvergence |
||
RequireActiveProfile |
||
RequireContributorRoles |
||
RequireDeveloperRoles |
||
RequireMavenVersion |
||
RequireNoRepositories |
||
RequirePluginVersions |
||
RequirePrerequisite |
||
RequireProfileIdsExist |
||
RequireProjectUrl |
||
RequireProperty |
||
RequirePropertyDiverges |
||
RequireReleaseVersion |
||
RequireSnapshotVersion |
||
RequireSameVersions |
||
RequireUpperBoundDeps |
||
See Maven enforcer rules, Maven extra enforcer rules for reference.
3. Rules
All rules share the following properties
Name | Type | Default | Required | Description |
---|---|---|---|---|
enabled |
Property<Boolean> |
|
Enables or disables the rule. Can be overridden using a |
|
enforcerLevel |
Property<EnforcerLevel> |
<unset> |
Fails the build if set to |
|
message |
Property<String> |
An optional message to provide when the rule fails. |
||
phases |
Property<EnforcerPhase> |
The list of phases where the check should be run. |
The following icons indicate the required state of a property: required optional conditionally required |
3.1. AlwaysFail
This rule will always fail. It is useful for testing proper plugin configuration.
3.1.1. Allowed Phases
-
BEFORE_BUILD
-
BEFORE_PROJECTS
-
BEFORE_PROJECT
-
AFTER_PROJECT
-
AFTER_PROJECTS
-
AFTER_BUILD
3.2. AlwaysPass
This rule will always succeed. It is useful for testing proper plugin configuration.
3.2.1. Allowed Phases
-
BEFORE_BUILD
-
BEFORE_PROJECTS
-
BEFORE_PROJECT
-
AFTER_PROJECT
-
AFTER_PROJECTS
-
AFTER_BUILD
3.3. BanDuplicateClasses
This rule checks the dependencies and fails if any class is present in more than one dependency.
The following exclusions are enabled by default: module-info , META-INF/versions/*/module-info
|
This rule will resolve configurations eagerly, once the target project or projects have been evaluated. |
3.3.3. Configuration
enforce {
rule(enforcer.rules.BanDuplicateClasses) { r ->
r.enabled
r.enforcerLevel
r.message
r.phases
r.findAllDuplicates
r.ignoreWhenIdentical
r.configurations
r.ignoreClasses
r.ignore()
r.dependencies
r.dependency() { d ->
d.ignore()
}
}
}
Name | Type | Default | Required | Description |
---|---|---|---|---|
findAllDuplicates |
Property<Boolean> |
|
Indicate whether the rule should find all duplicates or fail fast at the first duplicate. |
|
ignoreWhenIdentical |
Property<Boolean> |
|
When |
|
configurations |
ListProperty<String> |
|
Only verify dependencies within these configurations. Unresolvable configurations will be ignored. This rule applies |
|
ignoreClasses |
ListProperty<String> |
|
A list of classes to ignore duplicates of. Wildcards can be specified using the * character. |
|
dependencies |
ListProperty<Dependency> |
|
A list of dependencies for which you want to ignore specific classes. |
3.3.4. Methods
ignore(String str)
Adds a class to ignore duplicates of. Wildcards can be specified using the * character.
dependency(String str, Action<? extends Dependency> configurer)
dependency(Map<String, String> map, Action<? extends Dependency> configurer)
Adds an explicit dependency from which classes will be ignored of. Wildcards can be specified using the * character.
Accepted format for str
is groupId:artifactId:version[:classifier]
.
Accepted keys for map
are groupId
, artifactId
, version
, classifier
.
3.3.5. Example
enforce {
rule(enforcer.rules.BanDuplicateClasses) { r ->
// search only on compile and runtime classpaths
r.configurations.addAll(['compileClasspath', 'runtimeClasspath'])
// ignore all classes under the following package
r.ignore('org.log4j.impl.*')
// ignore classes from commons-codec
r.dependency('commons-codec:commons-codec:1.14') { d ->
// ignore all classes under a specific package
d.ignore('org.apache.commons.codec.cli.*)
}
}
}
3.4. BannedDependencies
This rule checks the dependencies and fails if any of the matching excludes are found.
This rule will resolve configurations eagerly, once the target project or projects have been evaluated. |
3.4.3. Configuration
enforce {
rule(enforcer.rules.BannedDependencies) { r ->
r.enabled
r.enforcerLevel
r.message
r.phases
r.configurations
r.excludes
r.includes
r.exclude()
r.include()
}
}
3.4.4. Properties
Name | Type | Default | Required | Description |
---|---|---|---|---|
configurations |
ListProperty<String> |
|
Only verify dependencies within these configurations. Unresolvable configurations will be ignored. This rule applies |
|
excludes |
ListProperty<String> |
|
A list of artifacts to ban. The format is |
|
includes |
ListProperty<String> |
|
A list of artifacts to include. These are exceptions to the excludes. It is meant to allow wide exclusion rules with |
Artifact pattern examples:
-
org.apache.maven
-
org.apache.maven:badArtifact
-
org.apache.maven:artifact:badVersion
-
org.apache.maven:*:1.2 (exclude version 1.2 and above, equivalent to [1.2,) )
-
org.apache.maven:*:[1.2] (explicit exclude of version 1.2)
-
org.apache.maven:*:*:test
-
org.apache.*:maven-*:*
3.4.5. Methods
exclude(String str)
Add a dependency pattern to be excluded.
include(String str)
Add a dependency pattern to be included.
3.4.6. Example
enforce {
rule(enforcer.rules.BannedDependencies) { r ->
// search only on compile and runtime classpaths
r.configurations.addAll(['compileClasspath', 'runtimeClasspath'])
// ignore all classes under the following package
r.exclude('org.apache.maven')
r.exclude('org.apache.maven:badArtifact')
r.exclude('*:badArtifact')
// only 1.0 of badArtifact is allowed
r.include('org.apache.maven:badArtifact:1.0')
}
}
3.5. BannedPlugins
This rule checks the set of plugins used during the build and enforces that specific excluded plugins are not used.
3.5.3. Configuration
enforce {
rule(enforcer.rules.BannedPlugins) { r ->
r.enabled
r.enforcerLevel
r.message
r.phases
r.excludes
r.includes
r.failFast
}
}
3.5.4. Properties
Name | Type | Default | Required | Description |
---|---|---|---|---|
excludes |
ListProperty<String> |
|
Specify the plugin ids to be excluded. |
|
includes |
ListProperty<String> |
|
Specify the plugin ids to be included as exceptions to the exclusions. |
|
failFast |
Property<Boolean> |
|
Should the rule fail after the first error or should the errors be aggregated. |
3.6. BannedRepositories
This rule checks whether the build or project include a specified banned repository.
3.6.2. Default Phases
-
AFTER_PROJECT
-
AFTER_PROJECTS == Configuration
enforce { rule(enforcer.rules.BannedRepositories) { r -> r.enabled r.enforcerLevel r.message r.phases r.mavenLocalAllowed r.bannedRepositories r.allowedRepositories } }
Name | Type | Default | Required | Description |
---|---|---|---|---|
mavenLocalAllowed |
Property<Boolean> |
|
Whether usage of the local Maven repository is allowed or not. |
|
bannedRepositories |
ListProperty<String> |
|
Specify banned non-plugin repositories. This is an exclusion list of http/https url patterns. |
|
allowedRepositories |
ListProperty<String> |
|
Specify explicitly allowed non-plugin repositories. This is an inclusion list of http/https url patterns. |
3.7. DependencyConvergence
This rule requires that dependency version numbers converge. If a project has two dependencies, A and B, both depending on the same artifact, C, this rule will fail the build if A depends on a different version of C than the version of C depended on by B.
This rule also configures additional settings applicable to the resolutionStrategy
property of all Configuration
instances
that can be resolved.
This rule will resolve configurations eagerly, once the target project or projects have been evaluated. |
3.7.3. Configuration
enforce {
rule(enforcer.rules.DependencyConvergence) { r ->
r.enabled
r.enforcerLevel
r.message
r.phases
r.failOnDynamicVersions
r.failOnChangingVersions
r.failOnNonReproducibleResolution
r.activateDependencyLocking
r.deactivateDependencyLocking
}
}
3.7.4. Properties
Name | Type | Default | Required | Description |
---|---|---|---|---|
failOnDynamicVersions |
Property<Boolean> |
|
Gradle will make sure that no dynamic version was used in the resulting dependency graph. In practice, it means that if |
|
failOnChangingVersions |
Property<Boolean> |
|
Gradle will make sure that no changing version participates in resolution. This can be used in cases you want to make |
|
failOnNonReproducibleResolution |
Property<Boolean> |
|
Configures Gradle to fail the build is the resolution result is expected to be unstable, that is to say that it includes |
|
activateDependencyLocking |
Property<Boolean> |
|
Activates dependency locking support in Gradle. Once turned on on a configuration, resolution result can be saved and |
|
deactivateDependencyLocking |
Property<Boolean> |
|
Deactivates dependency locking support in Gradle. |
3.7.5. Example
Given the following configuration found in settings.gradle
buildscript {
repositories {
gradlePluginPortal()
}
dependencies {
classpath 'org.kordamp.gradle:enforcer-gradle-plugin:0.14.0'
}
}
apply plugin: 'org.kordamp.gradle.enforcer'
enforce {
rule(enforcer.rules.DependencyConvergence)
}
And a simple project
plugins {
id 'java-library'
}
repositories {
mavenCentral()
}
dependencies {
api 'org.slf4j:slf4j-jdk14:1.6.1'
api 'org.slf4j:slf4j-nop:1.6.0'
}
The build will fail with the following message
FAILURE: Build failed with an exception. * What went wrong: Could not resolve all dependencies for configuration ':compileClasspath'. > Conflict(s) found for the following module(s): - org.slf4j:slf4j-api between versions 1.6.1 and 1.6.0 Run with: --scan or :dependencyInsight --configuration compileClasspath --dependency org.slf4j:slf4j-api to get more insight on how to solve the conflict.
You’ll have to temporarily disable this rule in order to invoke the suggested command, like so
$ gradle -Denforcer.rules.DependencyConvergence.enabled=false \ :dependencyInsight --configuration compileClasspath \ --dependency org.slf4j:slf4j-api > Task :dependencyInsight org.slf4j:slf4j-api:1.6.1 variant "compile" [ org.gradle.status = release (not requested) org.gradle.usage = java-api org.gradle.libraryelements = jar (compatible with: classes) org.gradle.category = library (not requested) Requested attributes not found in the selected variant: org.gradle.dependency.bundling = external org.gradle.jvm.version = 8 ] Selection reasons: - By conflict resolution : between versions 1.6.1 and 1.6.0 org.slf4j:slf4j-api:1.6.1 \--- org.slf4j:slf4j-jdk14:1.6.1 \--- compileClasspath org.slf4j:slf4j-api:1.6.0 -> 1.6.1 \--- org.slf4j:slf4j-nop:1.6.0 \--- compileClasspath
You may exclude the offending dependency, either by manually adding an exclusion (doing so in this example it’s trivial)
or enabling the ExcludeDependencies
rule (affecting all configurations). You may also force the version of
slf4j-api with the ForceDependencies
rule (affecting all configurations).
3.8. EnforceBytecodeVersion
This rule checks the dependencies transitively and fails if any class of any dependency is having its bytecode version higher than the one specified.
The following exclusions are enabled by default: module-info , META-INF/versions/(\d+)/.*
|
This rule will resolve configurations eagerly, once the target project or projects have been evaluated. |
3.8.3. Configuration
enforce {
rule(enforcer.rules.EnforceBytecodeVersion) { r ->
r.enabled
r.enforcerLevel
r.message
r.phases
r.maxJdkVersion
r.maxJavaMajorVersionNumber
r.maxJavaMinorVersionNumber
r.ignoreClasses
r.includes
r.excludes
r.configurations
r.showErrors
r.ignore()
r.include()
r.exclude()
}
}
3.8.4. Properties
Name | Type | Default | Required | Description |
---|---|---|---|---|
maxJdkVersion |
Property<String> |
The maximum target jdk version in the 1.x form (e.g. 1.6, 1.7, 1.8, 1.9 or 6, 7, 8, 9, 10, 11…). |
||
maxJavaMajorVersionNumber |
Property<Integer> |
An integer indicating the maximum bytecode major version number (cannot be specified if |
||
maxJavaMinorVersionNumber |
Property<Integer> |
|
An integer indicating the maximum bytecode minor version number (cannot be specified if |
|
excludes |
ListProperty<String> |
|
An optional list of artifacts to exclude. The format is |
|
includes |
ListProperty<String> |
|
An optional list of artifacts to include. These are exceptions to the excludes. It is meant to allow wide exclusion rules with |
|
configurations |
ListProperty<String> |
|
Only verify dependencies within these configurations. Unresolvable configurations will be ignored. This rule applies |
|
ignoreClasses |
ListProperty<String> |
|
A list of classes to ignore. Wildcards can be specified using the * character. |
|
showErrors |
Property<Boolean> |
|
The rule stops on the first violation. Set this property to |
Artifact pattern examples:
-
org.apache.maven
-
org.apache.maven:badArtifact
-
org.apache.maven:artifact:badVersion
-
org.apache.maven:*:1.2 (exclude version 1.2 and above, equivalent to [1.2,) )
-
org.apache.maven:*:[1.2] (explicit exclude of version 1.2)
-
org.apache.maven:*:*:test
-
org.apache.*:maven-*:*
3.8.5. Methods
ignore(String str)
Adds a class to ignore for verification. Wildcards can be specified using the * character.
exclude(String str)
exclude(Map<String, String> map)
Adds a dependency pattern from which classes will be excluded for verification. Wildcards can be specified using the * character.
Accepted format for str
is [groupId]:[artifactId]:[version]:[classifier]
.
Accepted keys for map
are groupId
, artifactId
, version
, classifier
.
include(String str)
include(Map<String, String> map)
Adds a dependency pattern from which classes will be included for verification. Wildcards can be specified using the * character.
Accepted format for str
is [groupId]:[artifactId]:[version]:[classifier]
.
Accepted keys for map
are groupId
, artifactId
, version
, classifier
.
3.8.6. Example
Given the following configuration found in settings.gradle
buildscript {
repositories {
gradlePluginPortal()
}
dependencies {
classpath 'org.kordamp.gradle:enforcer-gradle-plugin:0.14.0'
}
}
apply plugin: 'org.kordamp.gradle.enforcer'
enforce {
rule(enforcer.rules.EnforceBytecodeVersion) { r ->
r.maxJdkVersion = '1.8'
}
}
And a simple project
plugins {
id 'java-library'
}
repositories {
mavenCentral()
}
dependencies {
api 'org.kordamp.ikonli:ikonli-javafx:11.4.0'
}
Running the build will fail with the following message
FAILURE: Build failed with an exception. * What went wrong: [AFTER_PROJECTS] A Enforcer rule has failed > Enforcer rule 'enforcer.rules.EnforceBytecodeVersion' was triggered. Found Banned Dependency: org.kordamp.ikonli:ikonli-javafx:11.4.0 Found Banned Dependency: org.kordamp.ikonli:ikonli-core:11.4.0 Disable this rule temporarily with -Denforcer.rules.EnforceBytecodeVersion.enabled=false and invoke 'dependencyInsight' or 'dependencies' to locate the source of the banned dependencies.
If the enforcer configuration is changed to show all errors
buildscript {
repositories {
gradlePluginPortal()
}
dependencies {
classpath 'org.kordamp.gradle:enforcer-gradle-plugin:0.14.0'
}
}
apply plugin: 'org.kordamp.gradle.enforcer'
enforce {
rule(enforcer.rules.EnforceBytecodeVersion) { r ->
r.maxJdkVersion = '1.8'
r.showErrors = true
}
}
We get a better picture on why these dependencies cause the build to fail when running the build once more
[build-enforcer] Restricted to JDK 1.8 yet ikonli-javafx-11.4.0.jar (org.kordamp.ikonli:ikonli-javafx:11.4.0) contains org/kordamp/ikonli/javafx/FontIcon$1.class targeted to JDK 11 [build-enforcer] Restricted to JDK 1.8 yet ikonli-core-11.4.0.jar (org.kordamp.ikonli:ikonli-core:11.4.0) contains org/kordamp/ikonli/Ikon.class targeted to JDK 11 FAILURE: Build failed with an exception. * What went wrong: [AFTER_PROJECTS] A Enforcer rule has failed > Enforcer rule 'enforcer.rules.EnforceBytecodeVersion' was triggered. Found Banned Dependency: org.kordamp.ikonli:ikonli-javafx:11.4.0 Found Banned Dependency: org.kordamp.ikonli:ikonli-core:11.4.0 Disable this rule temporarily with -Denforcer.rules.EnforceBytecodeVersion.enabled=false and invoke 'dependencyInsight' or 'dependencies' to locate the source of the banned dependencies.
3.9. ExcludeDependencies
This rule excludes dependencies from all resolvable configurations.
3.9.3. Configuration
enforce {
rule(enforcer.rules.ExcludeDependencies) { r ->
r.enabled
r.enforcerLevel
r.message
r.phases
r.exclude()
}
}
3.9.4. Methods
exclude(String str)
exclude(Map<String, String> map)
Adds an dependency pattern for exclusion. Wildcards can be specified using the * character.
Accepted format for str
is [groupId]:[artifactId]:[version]:[classifier]
.
Accepted keys for map
are groupId
, artifactId
, version
, classifier
.
3.9.5. Example
Given the following configuration found in settings.gradle
buildscript {
repositories {
gradlePluginPortal()
}
dependencies {
classpath 'org.kordamp.gradle:enforcer-gradle-plugin:0.14.0'
}
}
apply plugin: 'org.kordamp.gradle.enforcer'
enforce {
rule(enforcer.rules.DependencyConvergence)
}
And a simple project
plugins {
id 'java-library'
}
repositories {
mavenCentral()
}
dependencies {
api 'org.slf4j:slf4j-jdk14:1.6.1'
api 'org.slf4j:slf4j-nop:1.6.0'
}
The build will fail with the following message
FAILURE: Build failed with an exception. * What went wrong: Could not resolve all dependencies for configuration ':compileClasspath'. > Conflict(s) found for the following module(s): - org.slf4j:slf4j-api between versions 1.6.1 and 1.6.0 Run with: --scan or :dependencyInsight --configuration compileClasspath --dependency org.slf4j:slf4j-api to get more insight on how to solve the conflict.
We can force an exclusion for org.slf4j:slf4j-api:1.6.0
buildscript {
repositories {
gradlePluginPortal()
}
dependencies {
classpath 'org.kordamp.gradle:enforcer-gradle-plugin:0.14.0'
}
}
apply plugin: 'org.kordamp.gradle.enforcer'
enforce {
rule(enforcer.rules.DependencyConvergence)
rule(enforcer.rules.ExcludeDependencies) { r ->
r.exclude('org.slf4j:slf4j-api:1.6.0')
}
}
3.10. ForceDependencies
This rule forces dependency versions for all resolvable configurations.
3.10.3. Configuration
enforce {
rule(enforcer.rules.ForceDependencies) { r ->
r.enabled
r.enforcerLevel
r.message
r.phases
r.dependencies
}
}
3.10.4. Properties
Name | Type | Default | Required | Description |
---|---|---|---|---|
dependencies |
ListProperty<Object> |
|
A list of dependencies to be forced. Accepted formats are the same when declaring dependencies in a configuration. |
3.10.5. Example
Given the following configuration found in settings.gradle
buildscript {
repositories {
gradlePluginPortal()
}
dependencies {
classpath 'org.kordamp.gradle:enforcer-gradle-plugin:0.14.0'
}
}
apply plugin: 'org.kordamp.gradle.enforcer'
enforce {
rule(enforcer.rules.DependencyConvergence)
}
And a simple project
plugins {
id 'java-library'
}
repositories {
mavenCentral()
}
dependencies {
api 'org.slf4j:slf4j-jdk14:1.6.1'
api 'org.slf4j:slf4j-nop:1.6.0'
}
The build will fail with the following message
FAILURE: Build failed with an exception. * What went wrong: Could not resolve all dependencies for configuration ':compileClasspath'. > Conflict(s) found for the following module(s): - org.slf4j:slf4j-api between versions 1.6.1 and 1.6.0 Run with: --scan or :dependencyInsight --configuration compileClasspath --dependency org.slf4j:slf4j-api to get more insight on how to solve the conflict.
We can force the version of org.slf4j:slf4j-api
to be 1.6.1
buildscript {
repositories {
gradlePluginPortal()
}
dependencies {
classpath 'org.kordamp.gradle:enforcer-gradle-plugin:0.14.0'
}
}
apply plugin: 'org.kordamp.gradle.enforcer'
enforce {
rule(enforcer.rules.DependencyConvergence)
rule(enforcer.rules.ForceDependencies) { r ->
r.dependencies.add('org.slf4j:slf4j-api:1.6.1')
}
}
Then running the build to verify that the version has been forced
$ gradle dependencies --configuration=compileClasspath > Task :dependencies ------------------------------------------------------------ Root project ------------------------------------------------------------ compileClasspath - Compile classpath for source set 'main'. +--- org.slf4j:slf4j-jdk14:1.6.1 | \--- org.slf4j:slf4j-api:1.6.1 \--- org.slf4j:slf4j-nop:1.6.0 \--- org.slf4j:slf4j-api:1.6.0 -> 1.6.1 (*) - dependencies omitted (listed previously)
3.11. RequireEnvironmentVariable
This rule checks that a specified environment variable is set.
This rule is repeatable. You may define multiple instances of this rule. |
3.11.3. Configuration
enforce {
rule(enforcer.rules.RequireEnvironmentVariable) { r ->
r.enabled
r.enforcerLevel
r.message
r.phases
r.variableName
r.regex
r.regexMessage
r.displayValue
}
}
3.11.4. Properties
Name | Type | Default | Required | Description |
---|---|---|---|---|
variableName |
Property<String> |
The name of the environment variable to be checked for. |
||
regex |
Property<String> |
A regular expression used to check the value of the variable. |
||
regexMessage |
Property<String> |
An optional message to the user if the regex check fails. |
||
displayValue |
Property<Boolean> |
|
Displays the value to the user if the regex check fails. |
|
after |
Property<Boolean> |
|
Whether to check during the |
3.12. RequireEncoding
Checks file encodings to see if they match the given encoding.
3.12.3. Configuration
enforce {
rule(enforcer.rules.RequireEncoding) { r ->
r.enabled
r.enforcerLevel
r.message
r.phases
r.encoding
r.includes
r.excludes
r.useDefaultExcludes
r.failFast
r.acceptAsciiSubset
}
}
3.12.4. Properties
Name | Type | Default | Required | Description |
---|---|---|---|---|
encoding |
Property<String> |
|
The file encoding to use. |
|
includes |
ListProperty<String> |
|
List of globs to include. |
|
excludes |
ListProperty<String> |
|
List of globs to exclude. |
|
useDefaultExcludes |
Property<Boolean> |
|
Enables SCM files exclusions. |
|
failFast |
Property<Boolean> |
|
Should the rule fail after the first error or should the errors be aggregated. |
|
acceptAsciiSubset |
Property<Boolean> |
|
Should the rule accept US-ASCII as an subset of UTF-8 and ISO-8859-1. |
Default exclusions include the following patterns
// Miscellaneous typical temporary files
'**/*~', '**/#*#', '**/.#*', '**/%*%', '**/._*'
// CVS
'**/CVS', '**/CVS/**', '**/.cvsignore'
// RCS
'**/RCS', '**/RCS/**'
// SCCS
'**/SCCS', '**/SCCS/**'
// Visual SourceSafe
'**/vssver.scc'
// MKS
'**/project.pj'
// Subversion
'**/.svn', '**/.svn/**'
// Arch
'**/.arch-ids', '**/.arch-ids/**'
//Bazaar
'**/.bzr', '**/.bzr/**'
//SurroundSCM
'**/.MySCMServerInfo'
// Mac
'**/.DS_Store'
// Serena Dimensions Version 10
'**/.metadata', '**/.metadata/**'
// Mercurial
'**/.hg', '**/.hg/**'
// git
'**/.git', '**/.gitignore', '**/.gitattributes', '**/.git/**'
// BitKeeper
'**/BitKeeper', '**/BitKeeper/**', '**/ChangeSet', '**/ChangeSet/**'
// darcs
'**/_darcs', '**/_darcs/**', '**/.darcsrepo', '**/.darcsrepo/**', '**/-darcs-backup*', '**/.darcs-temp-mail'
3.13. RequireFileChecksum
This rule checks that the specified file has a given checksum.
3.13.1. Allowed Phases
-
BEFORE_BUILD
-
BEFORE_PROJECTS
-
BEFORE_PROJECT
-
AFTER_PROJECT
-
AFTER_PROJECTS
-
AFTER_BUILD
3.14. RequireFilesDontExist
This rule checks that the specified list of files do not exist.
3.14.1. Allowed Phases
-
BEFORE_BUILD
-
BEFORE_PROJECTS
-
BEFORE_PROJECT
-
AFTER_PROJECT
-
AFTER_PROJECTS
-
AFTER_BUILD
3.14.3. Configuration
enforce {
rule(enforcer.rules.RequireFilesDontExist) { r ->
r.enabled
r.enforcerLevel
r.message
r.phases
r.files
r.includePatterns
r.excludePatterns
r.allowNulls
r.file()
r.include()
r.exclude()
}
}
3.14.4. Properties
Name | Type | Default | Required | Description |
---|---|---|---|---|
allowNulls |
Property<Boolean> |
|
If null files should be allowed. If allowed, they will be treated as if they do not exist. |
|
files |
Property<String> |
A list of files to be checked. |
||
includePatterns |
ListProperty<String> |
|
List of filename patterns to include. |
|
excludePatterns |
ListProperty<String> |
|
List of filename patterns to exclude. |
3.14.5. Methods
file(String str)
file(File file)
Adds a file to the list of files to be checked. Path may be relative or absolute.
include(String str)
Adds a patterns to the list of inclusion patterns to be checked. Path may be relative or absolute.
exclude(String str)
Adds a patterns to the list of exclusion patterns to be checked. Path may be relative or absolute.
3.14.6. Example
Given the following project structure
.
├── build.gradle
├── gradle
│  └── wrapper
│  ├── gradle-wrapper.jar
│  └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── secrets.txt
└── settings.gradle
And the following enforcer configuration
buildscript {
repositories {
gradlePluginPortal()
}
dependencies {
classpath 'org.kordamp.gradle:enforcer-gradle-plugin:0.14.0'
}
}
apply plugin: 'org.kordamp.gradle.enforcer'
enforce {
rule(enforcer.rules.RequireFilesDontExist) { r ->
r.file('secrets.txt')
}
}
Running the build results in an error
* What went wrong: [BEFORE_BUILD] A Enforcer rule has failed > Enforcer rule 'enforcer.rules.RequireFilesDontExist' was triggered. Some files should not exist: /Users/joe/projects/sample/secrets.txt
3.15. RequireFilesExist
This rule checks that the specified list of files exist.
3.15.1. Allowed Phases
-
BEFORE_BUILD
-
BEFORE_PROJECTS
-
BEFORE_PROJECT
-
AFTER_PROJECT
-
AFTER_PROJECTS
-
AFTER_BUILD
3.15.3. Configuration
enforce {
rule(enforcer.rules.RequireFilesExist) { r ->
r.enabled
r.enforcerLevel
r.message
r.phases
r.files
r.includePatterns
r.excludePatterns
r.allowNulls
r.file()
r.include()
r.exclude()
}
}
3.15.4. Properties
Name | Type | Default | Required | Description |
---|---|---|---|---|
allowNulls |
Property<Boolean> |
|
If null files should be allowed. If allowed, they will be treated as if they do exist. |
|
files |
Property<String> |
A list of files to be checked. |
||
includePatterns |
ListProperty<String> |
|
List of filename patterns to include. |
|
excludePatterns |
ListProperty<String> |
|
List of filename patterns to exclude. |
3.15.5. Methods
file(String str)
file(File file)
Adds a file to the list of files to be checked. Path may be relative or absolute.
include(String str)
Adds a patterns to the list of inclusion patterns to be checked. Path may be relative or absolute.
exclude(String str)
Adds a patterns to the list of exclusion patterns to be checked. Path may be relative or absolute.
3.15.6. Example
Given the following project structure
.
├── build.gradle
├── gradle
│  └── wrapper
│  ├── gradle-wrapper.jar
│  └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
And the following enforcer configuration
buildscript {
repositories {
gradlePluginPortal()
}
dependencies {
classpath 'org.kordamp.gradle:enforcer-gradle-plugin:0.14.0'
}
}
apply plugin: 'org.kordamp.gradle.enforcer'
enforce {
rule(enforcer.rules.RequireFilesExist) { r ->
r.file('gradle.properties')
}
}
Running the build results in an error
* What went wrong: [BEFORE_BUILD] A Enforcer rule has failed > Enforcer rule 'enforcer.rules.RequireFilesExist' was triggered. Some required files are missing: /Users/joe/projects/sample/gradle.properties
3.16. RequireFilesSize
This rule checks that the specified list of files exist and are within the specified size range.
3.16.1. Allowed Phases
-
BEFORE_BUILD
-
BEFORE_PROJECTS
-
BEFORE_PROJECT
-
AFTER_PROJECT
-
AFTER_PROJECTS
-
AFTER_BUILD
3.16.3. Configuration
enforce {
rule(enforcer.rules.RequireFilesSize) { r ->
r.enabled
r.enforcerLevel
r.message
r.phases
r.files
r.includePatterns
r.excludePatterns
r.maxsize
r.minsize
r.allowNulls
r.file()
r.include()
r.exclude()
}
}
3.16.4. Properties
Name | Type | Default | Required | Description |
---|---|---|---|---|
allowNulls |
Property<Boolean> |
|
If null files should be allowed. If allowed, they will be treated as if they do exist. |
|
files |
Property<String> |
A list of files to be checked. |
||
includePatterns |
ListProperty<String> |
|
List of filename patterns to include. |
|
excludePatterns |
ListProperty<String> |
|
List of filename patterns to exclude. |
|
maxsize |
Property<Long> |
|
Maximum size in bytes for this file. |
|
minsize |
Property<Long> |
|
Minimum size in bytes for this file. |
3.16.5. Methods
file(String str)
file(File file)
Adds a file to the list of files to be checked. Path may be relative or absolute.
include(String str)
Adds a patterns to the list of inclusion patterns to be checked. Path may be relative or absolute.
exclude(String str)
Adds a patterns to the list of exclusion patterns to be checked. Path may be relative or absolute.
3.17. RequireGradleProperty
This rule checks that a specified Gradle property is set.
This rule is repeatable. You may define multiple instances of this rule. |
3.17.3. Configuration
enforce {
rule(enforcer.rules.RequireGradleProperty) { r ->
r.enabled
r.enforcerLevel
r.message
r.phases
r.property
r.regex
r.regexMessage
r.displayValue
r.after
}
}
3.17.4. Properties
Name | Type | Default | Required | Description |
---|---|---|---|---|
property |
Property<String> |
The name of the Gradle property to be checked for. |
||
regex |
Property<String> |
A regular expression used to check the value of the property. |
||
regexMessage |
Property<String> |
An optional message to the user if the regex check fails. |
||
displayValue |
Property<Boolean> |
|
Displays the value to the user if the regex check fails. |
|
after |
Property<Boolean> |
|
Whether to check during the |
3.18. RequireGradleVersion
This rule enforces certain Gradle versions. The rule uses the version range syntax to define allowed versions.
3.19. RequireJavaVendor
This rule enforces that the Java vendor is allowed.
3.19.3. Configuration
enforce {
rule(enforcer.rules.RequireJavaVendor) { r ->
r.enabled
r.enforcerLevel
r.message
r.phases
r.excludes
r.includes
}
}
3.19.4. Properties
Name | Type | Default | Required | Description |
---|---|---|---|---|
excludes |
ListProperty<String> |
|
Specify the banned vendors. This should be an exact match of the System Property |
|
includes |
ListProperty<String> |
|
Specify the allowed vendor names. This should be an exact match of the System Property |
3.20. RequireJavaVersion
This rule enforces certain Java versions. The rule uses the version range syntax to define allowed versions.
The JDK version is retrieved and the following processing occurs before being checked:
-
Drop all non-numeric characters preceeding the first number. (build 1.5.0_07-b03 becomes 1.5.0_07-b03)
-
Replace all '_' and '-' with '.' (1.5.0_07-b03 becomes 1.5.0.07.b03)
-
Remove all non digit characters "[^0-9] and convert each section using Integer.parseInt() (1.5.0_07-b03 becomes 1.5.0.7.3)
-
Split the string on '.' and take the first 3 sections, separated by '.' and add '-' followed by the fourth section (1.5.0.7.3 becomes 1.5.0-7)
3.21. RequireOS
This rule can enforce certain values about the Operating System and processor architecture. Detects the same values as the os-maven-plugin.
3.21.3. Configuration
enforce {
rule(enforcer.rules.RequireOS) { r ->
r.enabled
r.enforcerLevel
r.message
r.phases
r.arch
r.name
r.version
r.release
r.classifier
r.classifierWithLikes
r.failOnUnknownOS
}
}
3.21.4. Properties
Name | Type | Default | Required | Description |
---|---|---|---|---|
arch |
Property<String> |
The expected OS architecture. |
||
name |
Property<String> |
The expected OS name. |
||
version |
Property<String> |
The expected OS version. |
||
release |
Property<String> |
The expected OS release (Linux). |
||
classifier |
Property<String> |
The expected OS classifier (Linux). |
||
classifierWithLikes |
ListProperty<String> |
|
Additional classifiers |
|
failOnUnknownOS |
Property<Boolean> |
|
Fails the build if an unsupported OS is detected. |
3.21.5. Example
The following configuration only works when the build is run on a Windows OS
enforce {
rule(enforcer.rules.RequireOS) { r ->
r.name = 'windows'
}
}
Running the build on a Mac results in a failed build
$ gradle help FAILURE: Build failed with an exception. * What went wrong: [BEFORE_BUILD] A Enforcer rule has failed > Enforcer rule 'enforcer.rules.RequireOS' was triggered. OS Name: osx Arch: x86_64 Version: 10.14 Classifier: osx-x86_64 is not allowed by Name=windows
3.22. RequireReleaseDeps
This rule checks that no snapshots are included.
This rule will resolve configurations eagerly, once the target project or projects have been evaluated. |
3.22.3. Configuration
enforce {
rule(enforcer.rules.RequireReleaseDeps) { r ->
r.enabled
r.enforcerLevel
r.message
r.phases
r.configurations
r.excludes
r.includes
r.onlyWhenRelease
r.exclude()
r.include()
}
}
3.22.4. Properties
Name | Type | Default | Required | Description |
---|---|---|---|---|
configurations |
ListProperty<String> |
|
Only verify dependencies within these configurations. Unresolvable configurations will be ignored. This rule applies |
|
excludes |
ListProperty<String> |
|
A list of artifacts to ban. The format is |
|
includes |
ListProperty<String> |
|
A list of artifacts to include. These are exceptions to the excludes. It is meant to allow wide exclusion rules with |
|
onlyWhenRelease |
Property<Boolean> |
|
Allows this rule to execute only when this project is a release. |
Artifact pattern examples:
-
org.apache.maven
-
org.apache.maven:badArtifact
-
org.apache.maven:artifact:badVersion
-
org.apache.maven:*:1.2 (exclude version 1.2 and above, equivalent to [1.2,) )
-
org.apache.maven:*:[1.2] (explicit exclude of version 1.2)
-
org.apache.maven:*:*:test
-
org.apache.*:maven-*:*
3.22.5. Methods
exclude(String str)
Add a dependency pattern to be excluded.
include(String str)
Add a dependency pattern to be included.
3.22.6. Example
enforce {
rule(enforcer.rules.RequireReleaseDeps) { r ->
// search only on compile and runtime classpaths
r.configurations.addAll(['compileClasspath', 'runtimeClasspath'])
// ignore all dependencies under the following package/artifacts
r.exclude('org.apache.maven')
r.exclude('org.apache.maven:badArtifact')
r.exclude('*:badArtifact')
}
}
3.23. RequireSystemProperty
This rule checks that a specified System property is set.
This rule is repeatable. You may define multiple instances of this rule. |
3.23.3. Configuration
enforce {
rule(enforcer.rules.RequireSystemProperty) { r ->
r.enabled
r.enforcerLevel
r.message
r.phases
r.property
r.regex
r.regexMessage
r.displayValue
r.after
}
}
3.23.4. Properties
Name | Type | Default | Required | Description |
---|---|---|---|---|
property |
Property<String> |
The name of the System property to be checked for. |
||
regex |
Property<String> |
A regular expression used to check the value of the property. |
||
regexMessage |
Property<String> |
An optional message to the user if the regex check fails. |
||
displayValue |
Property<Boolean> |
|
Displays the value to the user if the regex check fails. |
|
after |
Property<Boolean> |
|
Whether to check during the |
3.24. RequireTextFileChecksum
This rule checks that the specified text file to match the specified checksum.
This rule differs from RequireFileChecksum in that it will normalize line separators to a given value.
3.24.1. Allowed Phases
-
BEFORE_BUILD
-
BEFORE_PROJECTS
-
BEFORE_PROJECT
-
AFTER_PROJECT
-
AFTER_PROJECTS
-
AFTER_BUILD
3.24.3. Configuration
enforce {
rule(enforcer.rules.RequireTextFileChecksum) { r ->
r.enabled
r.enforcerLevel
r.message
r.phases
r.file
r.checksum
r.type
r.encoding
r.lineSeparator
}
}
3.24.4. Properties
Name | Type | Default | Required | Description |
---|---|---|---|---|
file |
Property<File> |
The file to be checked. |
||
checksum |
Property<String> |
The expected checksum |
||
type |
Property<String> |
Type of hashing algorithm used to calculate the checksum. May be one of ['md5', 'sha1', 'sha256', 'sha384', 'sha512']. |
||
encoding |
Property<String> |
|
The file encoding to use. |
|
lineSeparator |
Property<String> |
|
The line separator to use. Valid values are [ |
3.25. RequireUrl
This rule checks the given URL is present and optionally matches against a regex.
This rule is repeatable. You may define multiple instances of this rule. |
4. Kordamp Rules
The following rules require the target project to have applied the
org.kordamp.gradle.base plugin.
|
All rules share the following properties
Name | Type | Default | Required | Description |
---|---|---|---|---|
enabled |
Property<Boolean> |
|
Enables or disables the rule. Can be overridden using a |
|
enforcerLevel |
Property<EnforcerLevel> |
<unset> |
Fails the build if set to |
The following icons indicate the required state of a property: required optional conditionally required |
4.1. RequireKordampProperty
This rule checks properties found in project.config
DSL extension.
This rule is repeatable. You may define multiple instances of this rule. |
4.1.3. Configuration
enforce {
rule(enforcer.rules.kordamp.RequireRoles) { r ->
r.enabled
r.enforcerLevel
r.message
r.phases
r.targets
r.property
r.regex
r.regexMessage
r.displayValue
}
}
4.1.4. Properties
Name | Type | Default | Required | Description |
---|---|---|---|---|
targets |
ListProperty<String> |
|
List of project paths to include. |
|
property |
Property<String> |
The name of the Gradle property to be checked for. |
||
regex |
Property<String> |
A regular expression used to check the value of the property. |
||
regexMessage |
Property<String> |
An optional message to the user if the regex check fails. |
||
displayValue |
Property<Boolean> |
|
Displays the value to the user if the regex check fails. |
4.2. RequireRoles
This rule checks there are roles covered by people found in project.config.info.people
.
Say you want to enforce a policy that in every project there is at least one person representing a specific role, e.g. at least one person has the role "lead engineer".
4.2.3. Configuration
enforce {
rule(enforcer.rules.kordamp.RequireRoles) { r ->
r.enabled
r.enforcerLevel
r.message
r.phases
r.requiredRoles
r.validRoles
r.required()
r.valid()
}
}
4.2.4. Properties
Name | Type | Default | Required | Description |
---|---|---|---|---|
requiredRoles |
ListProperty<String> |
|
List of roles which must be represented by at least one person. |
|
validRoles |
ListProperty<String> |
|
List of roles which are additionally allowed. requiredRoles are always valid, so the union of |
5. Authoring
5.1. Create a project
First create a basic java-library
project if you don’t have one already. Choose your preferred
JVM language to implement your rules.
apply plugin: 'groovy'
apply plugin: 'java-library'
group = 'com.acme'
version = '1.2.3'
repositories {
mavenCentral()
}
dependencies {
api 'org.kordamp.gradle:enforcer-api:0.14.0'
implementation gradleApi()
}
apply plugin: 'java-library'
group = 'com.acme'
version = '1.2.3'
repositories {
mavenCentral()
}
dependencies {
api 'org.kordamp.gradle:enforcer-api:0.14.0'
implementation gradleApi()
}
5.2. Create a Rule class
Create your rule class. The rule must implement the EnforcerRule interface. You may rely on service injection as described at Developing Custom Gradle Types. It’s suggested to use the AbstractEnforcerRule as starting point.
If the rule succeeds, it should just simply return. If the rule fails, it should throw an EnforcerRuleException with a descriptive message telling the user why the rule failed.
package com.acme.enforcer.rules
import groovy.transform.CompileStatic
import org.gradle.api.model.ObjectFactory
import org.kordamp.gradle.plugin.enforcer.api.EnforcerContext
import org.kordamp.gradle.plugin.enforcer.api.EnforcerPhase
import org.kordamp.gradle.plugin.enforcer.api.AbstractEnforcerRule
import org.kordamp.gradle.plugin.enforcer.api.EnforcerRuleException
@CompileStatic
class MyCustomRule extends AbstractEnforcerRule {
MyCustomRule(ObjectFactory objects) {
super(objects)
}
@Override
protected void doValidate(EnforcerContext context) throws EnforcerRuleException {
// noop
}
@Override
protected void doExecute(EnforcerContext context) throws EnforcerRuleException {
if (context.enforcerPhase == EnforcerPhase.AFTER_BUILD) {
println "Everything went OK!"
}
}
}
package com.acme.enforcer.rules;
import org.gradle.api.model.ObjectFactory;
import org.kordamp.gradle.plugin.enforcer.api.AbstractEnforcerRule;
import org.kordamp.gradle.plugin.enforcer.api.EnforcerContext;
import org.kordamp.gradle.plugin.enforcer.api.EnforcerPhase;
import org.kordamp.gradle.plugin.enforcer.api.EnforcerRuleException;
public class MyCustomRule extends AbstractEnforcerRule {
public MyCustomRule(ObjectFactory objects) {
super(objects);
}
@Override
protected void doValidate(EnforcerContext context) throws EnforcerRuleException {
// noop
}
@Override
protected void doExecute(EnforcerContext context) throws EnforcerRuleException {
if (context.getEnforcerPhase().equals(EnforcerPhase.AFTER_BUILD)) {
System.out.println("Everything went OK!");
}
}
}
5.4. Configure the Enforcer plugin
On the consuming project, select which mode you want: build or project
build
buildscript {
repositories {
gradlePluginPortal()
// add the repository where the rule artifact is located
}
dependencies {
classpath 'org.kordamp.gradle:enforcer-gradle-plugin:0.14.0'
classpath 'com.acme:my-enforcer-rules:1.2.3'
}
}
apply plugin: 'org.kordamp.gradle.enforcer'
project
buildscript {
repositories {
gradlePluginPortal()
// add the repository where the rule artifact is located
}
dependencies {
classpath 'org.kordamp.gradle:enforcer-gradle-plugin:0.14.0'
classpath 'com.acme:my-enforcer-rules:1.2.3'
}
}
apply plugin: 'org.kordamp.gradle.project-enforcer'
Or alternatively
buildscript {
repositories {
// add the repository where the rule artifact is located
}
dependencies {
classpath 'com.acme:my-enforcer-rules:1.2.3'
}
}
plugins {
id 'org.kordamp.gradle.project-enforcer' version '0.14.0'
}