You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by sj...@apache.org on 2023/01/10 22:36:58 UTC

[maven-enforcer] branch MENFORCER-458-checksum created (now d442047)

This is an automated email from the ASF dual-hosted git repository.

sjaranowski pushed a change to branch MENFORCER-458-checksum
in repository https://gitbox.apache.org/repos/asf/maven-enforcer.git


      at d442047  [MENFORCER-458] Move Require*Checksum to new API

This branch includes the following new commits:

     new d442047  [MENFORCER-458] Move Require*Checksum to new API

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[maven-enforcer] 01/01: [MENFORCER-458] Move Require*Checksum to new API

Posted by sj...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

sjaranowski pushed a commit to branch MENFORCER-458-checksum
in repository https://gitbox.apache.org/repos/asf/maven-enforcer.git

commit d442047e7fda2d62a42a4ccc2f324951556d1adc
Author: Slawomir Jaranowski <s....@gmail.com>
AuthorDate: Tue Jan 10 22:21:02 2023 +0100

    [MENFORCER-458] Move Require*Checksum to new API
---
 .../NormalizeLineSeparatorReader.java              |  6 +-
 .../rules/checksum}/RequireFileChecksum.java       | 66 ++++++++++++------
 .../rules/checksum}/RequireTextFileChecksum.java   | 69 ++++++++++++-------
 .../src/site/apt/requireFileChecksum.apt.vm        | 20 +++---
 .../src/site/apt/requireTextFileChecksum.apt.vm    | 24 +++----
 .../TestNormalizeLineSeparatorReader.java          | 14 ++--
 .../rules/checksum}/TestRequireFileChecksum.java   | 64 ++++++++---------
 .../checksum}/TestRequireTextFileChecksum.java     | 58 +++++++++++-----
 .../projects/require-file-checksum/verify.groovy   | 26 +++++++
 .../it/projects/require-textfile-checksum/LICENSE  | 16 +++++
 .../it/projects/require-textfile-checksum/pom.xml  | 80 ++++++++++++++++++++++
 .../require-textfile-checksum/verify.groovy        | 26 +++++++
 12 files changed, 344 insertions(+), 125 deletions(-)

diff --git a/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/utils/NormalizeLineSeparatorReader.java b/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/checksum/NormalizeLineSeparatorReader.java
similarity index 96%
rename from enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/utils/NormalizeLineSeparatorReader.java
rename to enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/checksum/NormalizeLineSeparatorReader.java
index ef7ef25..172261a 100644
--- a/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/utils/NormalizeLineSeparatorReader.java
+++ b/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/checksum/NormalizeLineSeparatorReader.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.maven.enforcer.rules.utils;
+package org.apache.maven.enforcer.rules.checksum;
 
 import java.io.FilterReader;
 import java.io.IOException;
@@ -25,7 +25,7 @@ import java.io.Reader;
 /**
  * Converts Unix line separators to Windows ones and vice-versa.
  */
-public class NormalizeLineSeparatorReader extends FilterReader {
+class NormalizeLineSeparatorReader extends FilterReader {
 
     private static final int EOL = -1;
 
@@ -84,7 +84,7 @@ public class NormalizeLineSeparatorReader extends FilterReader {
 
     Character previousCharacter;
 
-    public NormalizeLineSeparatorReader(Reader reader, LineSeparator lineSeparator) {
+    NormalizeLineSeparatorReader(Reader reader, LineSeparator lineSeparator) {
         super(reader);
         this.lineSeparator = lineSeparator;
         bufferedCharacter = null;
diff --git a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/RequireFileChecksum.java b/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/checksum/RequireFileChecksum.java
similarity index 67%
rename from enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/RequireFileChecksum.java
rename to enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/checksum/RequireFileChecksum.java
index 80003ba..84b3753 100644
--- a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/RequireFileChecksum.java
+++ b/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/checksum/RequireFileChecksum.java
@@ -16,7 +16,9 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.maven.plugins.enforcer;
+package org.apache.maven.enforcer.rules.checksum;
+
+import javax.inject.Named;
 
 import java.io.File;
 import java.io.IOException;
@@ -24,8 +26,9 @@ import java.io.InputStream;
 import java.nio.file.Files;
 
 import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.maven.enforcer.rule.api.EnforcerRuleError;
 import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
-import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper;
+import org.apache.maven.enforcer.rules.AbstractStandardEnforcerRule;
 
 /**
  * Rule to validate a binary file to match the specified checksum.
@@ -34,9 +37,10 @@ import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper;
  * @author Lyubomyr Shaydariv
  * @see RequireTextFileChecksum
  */
-public class RequireFileChecksum extends AbstractNonCacheableEnforcerRule {
+@Named("requireFileChecksum")
+public class RequireFileChecksum extends AbstractStandardEnforcerRule {
 
-    protected File file;
+    private File file;
 
     private String checksum;
 
@@ -45,17 +49,17 @@ public class RequireFileChecksum extends AbstractNonCacheableEnforcerRule {
     private String nonexistentFileMessage;
 
     @Override
-    public void execute(EnforcerRuleHelper helper) throws EnforcerRuleException {
+    public void execute() throws EnforcerRuleException {
         if (this.file == null) {
-            throw new EnforcerRuleException("Input file unspecified");
+            throw new EnforcerRuleError("Input file unspecified");
         }
 
         if (this.type == null) {
-            throw new EnforcerRuleException("Hash type unspecified");
+            throw new EnforcerRuleError("Hash type unspecified");
         }
 
         if (this.checksum == null) {
-            throw new EnforcerRuleException("Checksum unspecified");
+            throw new EnforcerRuleError("Checksum unspecified");
         }
 
         if (!this.file.exists()) {
@@ -67,12 +71,11 @@ public class RequireFileChecksum extends AbstractNonCacheableEnforcerRule {
         }
 
         if (this.file.isDirectory()) {
-            throw new EnforcerRuleException(
-                    "Cannot calculate the checksum of directory: " + this.file.getAbsolutePath());
+            throw new EnforcerRuleError("Cannot calculate the checksum of directory: " + this.file.getAbsolutePath());
         }
 
         if (!this.file.canRead()) {
-            throw new EnforcerRuleException("Cannot read file: " + this.file.getAbsolutePath());
+            throw new EnforcerRuleError("Cannot read file: " + this.file.getAbsolutePath());
         }
 
         String checksum = calculateChecksum();
@@ -96,6 +99,10 @@ public class RequireFileChecksum extends AbstractNonCacheableEnforcerRule {
         this.file = file;
     }
 
+    public File getFile() {
+        return file;
+    }
+
     /**
      * The expected checksum value.
      *
@@ -105,6 +112,10 @@ public class RequireFileChecksum extends AbstractNonCacheableEnforcerRule {
         this.checksum = checksum;
     }
 
+    public String getChecksum() {
+        return checksum;
+    }
+
     /**
      * The checksum algorithm to use. Possible values: "md5", "sha1", "sha256", "sha384", "sha512".
      *
@@ -114,6 +125,10 @@ public class RequireFileChecksum extends AbstractNonCacheableEnforcerRule {
         this.type = type;
     }
 
+    public String getType() {
+        return type;
+    }
+
     /**
      * The friendly message to use when the file does not exist.
      *
@@ -123,29 +138,40 @@ public class RequireFileChecksum extends AbstractNonCacheableEnforcerRule {
         this.nonexistentFileMessage = nonexistentFileMessage;
     }
 
+    public String getNonexistentFileMessage() {
+        return nonexistentFileMessage;
+    }
+
     protected String calculateChecksum() throws EnforcerRuleException {
         try (InputStream inputStream = Files.newInputStream(this.file.toPath())) {
             return calculateChecksum(inputStream);
         } catch (IOException e) {
-            throw new EnforcerRuleException("Unable to calculate checksum", e);
+            throw new EnforcerRuleError("Unable to calculate checksum", e);
         }
     }
 
     protected String calculateChecksum(InputStream inputStream) throws IOException, EnforcerRuleException {
-        String checksum;
+        String result;
         if ("md5".equals(this.type)) {
-            checksum = DigestUtils.md5Hex(inputStream);
+            result = DigestUtils.md5Hex(inputStream);
         } else if ("sha1".equals(this.type)) {
-            checksum = DigestUtils.sha1Hex(inputStream);
+            result = DigestUtils.sha1Hex(inputStream);
         } else if ("sha256".equals(this.type)) {
-            checksum = DigestUtils.sha256Hex(inputStream);
+            result = DigestUtils.sha256Hex(inputStream);
         } else if ("sha384".equals(this.type)) {
-            checksum = DigestUtils.sha384Hex(inputStream);
+            result = DigestUtils.sha384Hex(inputStream);
         } else if ("sha512".equals(this.type)) {
-            checksum = DigestUtils.sha512Hex(inputStream);
+            result = DigestUtils.sha512Hex(inputStream);
         } else {
-            throw new EnforcerRuleException("Unsupported hash type: " + this.type);
+            throw new EnforcerRuleError("Unsupported hash type: " + this.type);
         }
-        return checksum;
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return String.format(
+                "RequireFileChecksum[file=%s, checksum=%s, type=%s, nonexistentFileMessage=%s, level=%s]",
+                file, checksum, type, nonexistentFileMessage, getLevel());
     }
 }
diff --git a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/RequireTextFileChecksum.java b/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/checksum/RequireTextFileChecksum.java
similarity index 53%
rename from enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/RequireTextFileChecksum.java
rename to enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/checksum/RequireTextFileChecksum.java
index 17dfcd2..8eadcdf 100644
--- a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/RequireTextFileChecksum.java
+++ b/enforcer-rules/src/main/java/org/apache/maven/enforcer/rules/checksum/RequireTextFileChecksum.java
@@ -16,21 +16,24 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.maven.plugins.enforcer;
+package org.apache.maven.enforcer.rules.checksum;
+
+import javax.inject.Inject;
+import javax.inject.Named;
 
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.Reader;
 import java.nio.charset.Charset;
 import java.nio.file.Files;
+import java.util.Objects;
 
 import org.apache.commons.io.input.ReaderInputStream;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.maven.enforcer.rule.api.EnforcerRuleError;
 import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
-import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper;
-import org.apache.maven.enforcer.rules.utils.NormalizeLineSeparatorReader;
-import org.apache.maven.enforcer.rules.utils.NormalizeLineSeparatorReader.LineSeparator;
-import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
+import org.apache.maven.enforcer.rules.checksum.NormalizeLineSeparatorReader.LineSeparator;
+import org.apache.maven.project.MavenProject;
 
 /**
  * Rule to validate a text file to match the specified checksum.
@@ -38,10 +41,19 @@ import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluatio
  * @author Konrad Windszus
  * @see RequireFileChecksum
  */
+@Named("requireTextFileChecksum")
 public class RequireTextFileChecksum extends RequireFileChecksum {
+
     private NormalizeLineSeparatorReader.LineSeparator normalizeLineSeparatorTo = LineSeparator.UNIX;
 
-    Charset encoding;
+    private Charset encoding;
+
+    private final MavenProject project;
+
+    @Inject
+    public RequireTextFileChecksum(MavenProject project) {
+        this.project = Objects.requireNonNull(project);
+    }
 
     public void setNormalizeLineSeparatorTo(NormalizeLineSeparatorReader.LineSeparator normalizeLineSeparatorTo) {
         this.normalizeLineSeparatorTo = normalizeLineSeparatorTo;
@@ -51,38 +63,47 @@ public class RequireTextFileChecksum extends RequireFileChecksum {
         this.encoding = Charset.forName(encoding);
     }
 
+    public Charset getEncoding() {
+        return encoding;
+    }
+
     @Override
-    public void execute(EnforcerRuleHelper helper) throws EnforcerRuleException {
+    public void execute() throws EnforcerRuleException {
         // set defaults
         if (encoding == null) {
             // https://maven.apache.org/plugins/maven-resources-plugin/examples/encoding.html
-            try {
-                String encoding = (String) helper.evaluate("${project.build.sourceEncoding}");
-                if (StringUtils.isBlank(encoding)) {
-                    encoding = System.getProperty("file.encoding");
-                    helper.getLog()
-                            .warn("File encoding has not been set, using platform encoding " + encoding
-                                    + ". Build is platform dependent!");
-                }
-                this.encoding = Charset.forName(encoding);
-            } catch (ExpressionEvaluationException e) {
-                throw new EnforcerRuleException(
-                        "Unable to retrieve the project's build source encoding "
-                                + "(${project.build.sourceEncoding}): ",
-                        e);
+            String projectEncoding = project.getProperties().getProperty("project.build.sourceEncoding", null);
+            if (StringUtils.isBlank(projectEncoding)) {
+                projectEncoding = System.getProperty("file.encoding");
+                getLog().warn("File encoding has not been set, using platform encoding " + projectEncoding
+                        + ". Build is platform dependent! - https://maven.apache.org/general.html#encoding-warning");
             }
+            encoding = Charset.forName(projectEncoding);
         }
-        super.execute(helper);
+        super.execute();
     }
 
     @Override
     protected String calculateChecksum() throws EnforcerRuleException {
         try (Reader reader = new NormalizeLineSeparatorReader(
-                        Files.newBufferedReader(file.toPath(), encoding), normalizeLineSeparatorTo);
+                        Files.newBufferedReader(getFile().toPath(), encoding), normalizeLineSeparatorTo);
                 InputStream inputStream = new ReaderInputStream(reader, encoding)) {
             return super.calculateChecksum(inputStream);
         } catch (IOException e) {
-            throw new EnforcerRuleException("Unable to calculate checksum (with normalized line separators)", e);
+            throw new EnforcerRuleError("Unable to calculate checksum (with normalized line separators)", e);
         }
     }
+
+    @Override
+    public String toString() {
+        return String.format(
+                "RequireFileChecksum[file=%s, checksum=%s, type=%s, encoding=%s, normalizeLineSeparatorTo=%s, nonexistentFileMessage=%s, level=%s]",
+                getFile(),
+                getChecksum(),
+                getType(),
+                encoding,
+                normalizeLineSeparatorTo,
+                getNonexistentFileMessage(),
+                getLevel());
+    }
 }
diff --git a/enforcer-rules/src/site/apt/requireFileChecksum.apt.vm b/enforcer-rules/src/site/apt/requireFileChecksum.apt.vm
index 425f0e6..de4bd14 100644
--- a/enforcer-rules/src/site/apt/requireFileChecksum.apt.vm
+++ b/enforcer-rules/src/site/apt/requireFileChecksum.apt.vm
@@ -31,15 +31,15 @@ Require Files Checksum
 
    The following parameters are supported by this rule:
 
-   * message - an optional message to the user if the rule fails. If not set a default message will be used.
+   * <<message>> - an optional message to the user if the rule fails. If not set a default message will be used.
 
-   * nonexistentFileMessage - an optional message to the user if the file is missing. If not set a default message will be used.
+   * <<nonexistentFileMessage>> - an optional message to the user if the file is missing. If not set a default message will be used.
 
-   * file - A file to check.
+   * <<file>> - A file to check.
 
-   * checksum - Expected file checksum.
+   * <<checksum>> - Expected file checksum.
 
-   * type - Type of hashing algorithm to calculate the checksum. May be one of "md5", "sha1", "sha256", "sha384", or "sha512".
+   * <<type>> - Type of hashing algorithm to calculate the checksum. May be one of "md5", "sha1", "sha256", "sha384", or "sha512".
 
    []
 
@@ -64,27 +64,27 @@ Require Files Checksum
             <configuration>
               <rules>
                 <requireFileChecksum>
-                  <file>${project.build.outputDirectory}/foo.txt</file>
+                  <file>\${project.build.outputDirectory}/foo.txt</file>
                   <checksum>d41d8cd98f00b204e9800998ecf8427e</checksum>
                   <type>md5</type>
                 </requireFileChecksum>
                 <requireFileChecksum>
-                  <file>${project.build.outputDirectory}/bar.txt</file>
+                  <file>\${project.build.outputDirectory}/bar.txt</file>
                   <checksum>da39a3ee5e6b4b0d3255bfef95601890afd80709</checksum>
                   <type>sha1</type>
                 </requireFileChecksum>
                 <requireFileChecksum>
-                  <file>${project.build.outputDirectory}/baz.txt</file>
+                  <file>\${project.build.outputDirectory}/baz.txt</file>
                   <checksum>e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855</checksum>
                   <type>sha256</type>
                 </requireFileChecksum>
                 <requireFileChecksum>
-                  <file>${project.build.outputDirectory}/qux.txt</file>
+                  <file>\${project.build.outputDirectory}/qux.txt</file>
                   <checksum>38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b</checksum>
                   <type>sha384</type>
                 </requireFileChecksum>
                 <requireFileChecksum>
-                  <file>${project.build.outputDirectory}/quux.txt</file>
+                  <file>\${project.build.outputDirectory}/quux.txt</file>
                   <checksum>cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e</checksum>
                   <type>sha512</type>
                 </requireFileChecksum>
diff --git a/enforcer-rules/src/site/apt/requireTextFileChecksum.apt.vm b/enforcer-rules/src/site/apt/requireTextFileChecksum.apt.vm
index c058f29..f210146 100644
--- a/enforcer-rules/src/site/apt/requireTextFileChecksum.apt.vm
+++ b/enforcer-rules/src/site/apt/requireTextFileChecksum.apt.vm
@@ -32,19 +32,19 @@ Require Text Files Checksum
 
    The following parameters are supported by this rule:
 
-   * message - an optional message to the user if the rule fails. If not set a default message will be used.
+   * <<message>> - an optional message to the user if the rule fails. If not set a default message will be used.
 
-   * nonexistentFileMessage - an optional message to the user if the file is missing. If not set a default message will be used.
+   * <<nonexistentFileMessage>> - an optional message to the user if the file is missing. If not set a default message will be used.
 
-   * file - A file to check.
+   * <<file>> - A file to check.
 
-   * checksum - Expected file checksum.
+   * <<checksum>> - Expected file checksum.
 
-   * type - Type of hashing algorithm to calculate the checksum. May be one of "md5", "sha1", "sha256", "sha384", or "sha512".
+   * <<type>> - Type of hashing algorithm to calculate the checksum. May be one of "md5", "sha1", "sha256", "sha384", or "sha512".
 
-   * normalizeLineSeparatorTo - optionally specifies to which line separators to normalize prior to checksum calculation. Either "WINDOWS" or "UNIX". By default "UNIX".
+   * <<normalizeLineSeparatorTo>> - optionally specifies to which line separators to normalize prior to checksum calculation. Either "WINDOWS" or "UNIX". By default "UNIX".
 
-   * encoding - the character encoding used by the file. One of the {{{https://docs.oracle.com/javase/7/docs/api/java/nio/charset/Charset.html#standard}Default Java Charset}} names. By default set to <<<$\{project.build.sourceEncoding\}>>>
+   * <<encoding>> - the character encoding used by the file. One of the {{{https://docs.oracle.com/javase/8/docs/api/java/nio/charset/Charset.html#standard}Default Java Charset}} names. By default set to <<<$\{project.build.sourceEncoding\}>>>
 
    []
 
@@ -69,29 +69,29 @@ Require Text Files Checksum
             <configuration>
               <rules>
                 <requireTextFileChecksum>
-                  <file>${project.build.outputDirectory}/foo.txt</file>
+                  <file>\${project.build.outputDirectory}/foo.txt</file>
                   <checksum>d41d8cd98f00b204e9800998ecf8427e</checksum>
                   <type>md5</type>
                 </requireTextFileChecksum>
                 <requireTextFileChecksum>
-                  <file>${project.build.outputDirectory}/bar.txt</file>
+                  <file>\${project.build.outputDirectory}/bar.txt</file>
                   <checksum>da39a3ee5e6b4b0d3255bfef95601890afd80709</checksum>
                   <type>sha1</type>
                   <encoding>UTF-8</encoding>
                 </requireTextFileChecksum>
                 <requireTextFileChecksum>
-                  <file>${project.build.outputDirectory}/baz.txt</file>
+                  <file>\${project.build.outputDirectory}/baz.txt</file>
                   <checksum>e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855</checksum>
                   <type>sha256</type>
                   <normalizeLineSeparatorTo>WINDOWS</normalizeLineSeparatorTo>
                 </requireTextFileChecksum>
                 <requireTextFileChecksum>
-                  <file>${project.build.outputDirectory}/qux.txt</file>
+                  <file>\${project.build.outputDirectory}/qux.txt</file>
                   <checksum>38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b</checksum>
                   <type>sha384</type>
                 </requireTextFileChecksum>
                 <requireTextFileChecksum>
-                  <file>${project.build.outputDirectory}/quux.txt</file>
+                  <file>\${project.build.outputDirectory}/quux.txt</file>
                   <checksum>cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e</checksum>
                   <type>sha512</type>
                 </requireTextFileChecksum>
diff --git a/enforcer-rules/src/test/java/org/apache/maven/enforcer/rules/utils/TestNormalizeLineSeparatorReader.java b/enforcer-rules/src/test/java/org/apache/maven/enforcer/rules/checksum/TestNormalizeLineSeparatorReader.java
similarity index 84%
rename from enforcer-rules/src/test/java/org/apache/maven/enforcer/rules/utils/TestNormalizeLineSeparatorReader.java
rename to enforcer-rules/src/test/java/org/apache/maven/enforcer/rules/checksum/TestNormalizeLineSeparatorReader.java
index 1ebfd0a..6346cb9 100644
--- a/enforcer-rules/src/test/java/org/apache/maven/enforcer/rules/utils/TestNormalizeLineSeparatorReader.java
+++ b/enforcer-rules/src/test/java/org/apache/maven/enforcer/rules/checksum/TestNormalizeLineSeparatorReader.java
@@ -16,25 +16,25 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.maven.enforcer.rules.utils;
+package org.apache.maven.enforcer.rules.checksum;
 
 import java.io.IOException;
 import java.io.Reader;
 import java.io.StringReader;
 
 import org.apache.commons.io.IOUtils;
-import org.apache.maven.enforcer.rules.utils.NormalizeLineSeparatorReader.LineSeparator;
+import org.apache.maven.enforcer.rules.checksum.NormalizeLineSeparatorReader.LineSeparator;
 import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
-public class TestNormalizeLineSeparatorReader {
+class TestNormalizeLineSeparatorReader {
     private static final String UNIX_MULTILINE_STRING = "line1\nline2\n\n";
 
     private static final String WINDOWS_MULTILINE_STRING = "line1\r\nline2\r\n\r\n";
 
     @Test
-    public void testUnixToWindows() throws IOException {
+    void testUnixToWindows() throws IOException {
         try (Reader reader =
                 new NormalizeLineSeparatorReader(new StringReader(UNIX_MULTILINE_STRING), LineSeparator.WINDOWS)) {
             assertEquals(WINDOWS_MULTILINE_STRING, IOUtils.toString(reader));
@@ -42,7 +42,7 @@ public class TestNormalizeLineSeparatorReader {
     }
 
     @Test
-    public void testUnixToUnix() throws IOException {
+    void testUnixToUnix() throws IOException {
         try (Reader reader =
                 new NormalizeLineSeparatorReader(new StringReader(UNIX_MULTILINE_STRING), LineSeparator.UNIX)) {
             assertEquals(UNIX_MULTILINE_STRING, IOUtils.toString(reader));
@@ -50,7 +50,7 @@ public class TestNormalizeLineSeparatorReader {
     }
 
     @Test
-    public void testWindowsToUnix() throws IOException {
+    void testWindowsToUnix() throws IOException {
         try (Reader reader =
                 new NormalizeLineSeparatorReader(new StringReader(WINDOWS_MULTILINE_STRING), LineSeparator.UNIX)) {
             assertEquals(UNIX_MULTILINE_STRING, IOUtils.toString(reader));
@@ -58,7 +58,7 @@ public class TestNormalizeLineSeparatorReader {
     }
 
     @Test
-    public void testWindowsToWindows() throws IOException {
+    void testWindowsToWindows() throws IOException {
         try (Reader reader =
                 new NormalizeLineSeparatorReader(new StringReader(WINDOWS_MULTILINE_STRING), LineSeparator.WINDOWS)) {
             assertEquals(WINDOWS_MULTILINE_STRING, IOUtils.toString(reader));
diff --git a/enforcer-rules/src/test/java/org/apache/maven/plugins/enforcer/TestRequireFileChecksum.java b/enforcer-rules/src/test/java/org/apache/maven/enforcer/rules/checksum/TestRequireFileChecksum.java
similarity index 77%
rename from enforcer-rules/src/test/java/org/apache/maven/plugins/enforcer/TestRequireFileChecksum.java
rename to enforcer-rules/src/test/java/org/apache/maven/enforcer/rules/checksum/TestRequireFileChecksum.java
index aa0504e..c913420 100644
--- a/enforcer-rules/src/test/java/org/apache/maven/plugins/enforcer/TestRequireFileChecksum.java
+++ b/enforcer-rules/src/test/java/org/apache/maven/enforcer/rules/checksum/TestRequireFileChecksum.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.maven.plugins.enforcer;
+package org.apache.maven.enforcer.rules.checksum;
 
 import java.io.File;
 import java.io.IOException;
@@ -34,7 +34,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
  *
  * @author Lyubomyr Shaydariv
  */
-public class TestRequireFileChecksum {
+class TestRequireFileChecksum {
 
     private final RequireFileChecksum rule = new RequireFileChecksum();
 
@@ -42,7 +42,7 @@ public class TestRequireFileChecksum {
     public File temporaryFolder;
 
     @Test
-    public void testFileChecksumMd5() throws IOException, EnforcerRuleException {
+    void testFileChecksumMd5() throws IOException, EnforcerRuleException {
         File f = File.createTempFile("junit", null, temporaryFolder);
         FileUtils.fileWrite(f, "message");
 
@@ -50,11 +50,11 @@ public class TestRequireFileChecksum {
         rule.setChecksum("78e731027d8fd50ed642340b7c9a63b3");
         rule.setType("md5");
 
-        rule.execute(EnforcerTestUtils.getHelper());
+        rule.execute();
     }
 
     @Test
-    public void testFileChecksumMd5UpperCase() throws IOException, EnforcerRuleException {
+    void testFileChecksumMd5UpperCase() throws IOException, EnforcerRuleException {
         File f = File.createTempFile("junit", null, temporaryFolder);
         FileUtils.fileWrite(f, "message");
 
@@ -62,24 +62,24 @@ public class TestRequireFileChecksum {
         rule.setChecksum("78E731027D8FD50ED642340B7C9A63B3");
         rule.setType("md5");
 
-        rule.execute(EnforcerTestUtils.getHelper());
+        rule.execute();
     }
 
     @Test
-    public void testFileChecksumMd5GivenFileDoesNotExistFailure() {
+    void testFileChecksumMd5GivenFileDoesNotExistFailure() {
         File f = new File("nonExistent");
         Throwable exception = assertThrows(EnforcerRuleException.class, () -> {
             rule.setFile(f);
             rule.setChecksum("78e731027d8fd50ed642340b7c9a63b3");
             rule.setType("md5");
 
-            rule.execute(EnforcerTestUtils.getHelper());
+            rule.execute();
         });
         assertTrue(exception.getMessage().contains("File does not exist: " + f.getAbsolutePath()));
     }
 
     @Test
-    public void testFileChecksumMd5GivenFileDoesNotExistFailureWithMessage() {
+    void testFileChecksumMd5GivenFileDoesNotExistFailureWithMessage() {
         File f = new File("nonExistent");
         String configuredMessage = "testMessageFileDoesNotExist";
         Throwable exception = assertThrows(EnforcerRuleException.class, () -> {
@@ -88,13 +88,13 @@ public class TestRequireFileChecksum {
             rule.setType("md5");
             rule.setNonexistentFileMessage(configuredMessage);
 
-            rule.execute(EnforcerTestUtils.getHelper());
+            rule.execute();
         });
         assertTrue(exception.getMessage().contains(configuredMessage));
     }
 
     @Test
-    public void testFileChecksumMd5GivenFileIsNotReadableFailure() throws IOException {
+    void testFileChecksumMd5GivenFileIsNotReadableFailure() throws IOException {
         File t = File.createTempFile("junit", null, temporaryFolder);
         File f = new File(t.getAbsolutePath()) {
             private static final long serialVersionUID = 6987790643999338089L;
@@ -109,64 +109,64 @@ public class TestRequireFileChecksum {
             rule.setChecksum("78e731027d8fd50ed642340b7c9a63b3");
             rule.setType("md5");
 
-            rule.execute(EnforcerTestUtils.getHelper());
+            rule.execute();
         });
         assertTrue(exception.getMessage().contains("Cannot read file: " + f.getAbsolutePath()));
     }
 
     @Test
-    public void testFileChecksumMd5GivenFileIsADirectoryFailure() {
+    void testFileChecksumMd5GivenFileIsADirectoryFailure() {
         File f = temporaryFolder;
         Throwable exception = assertThrows(EnforcerRuleException.class, () -> {
             rule.setFile(f);
             rule.setChecksum("78e731027d8fd50ed642340b7c9a63b3");
             rule.setType("md5");
 
-            rule.execute(EnforcerTestUtils.getHelper());
+            rule.execute();
         });
         assertTrue(
                 exception.getMessage().contains("Cannot calculate the checksum of directory: " + f.getAbsolutePath()));
     }
 
     @Test
-    public void testFileChecksumMd5NoFileSpecifiedFailure() {
+    void testFileChecksumMd5NoFileSpecifiedFailure() {
         Throwable exception = assertThrows(EnforcerRuleException.class, () -> {
             rule.setChecksum("78e731027d8fd50ed642340b7c9a63b3");
             rule.setType("md5");
 
-            rule.execute(EnforcerTestUtils.getHelper());
+            rule.execute();
         });
         assertTrue(exception.getMessage().contains("Input file unspecified"));
     }
 
     @Test
-    public void testFileChecksumMd5NoChecksumSpecifiedFailure() {
+    void testFileChecksumMd5NoChecksumSpecifiedFailure() {
         Throwable exception = assertThrows(EnforcerRuleException.class, () -> {
             File f = File.createTempFile("junit", null, temporaryFolder);
 
             rule.setFile(f);
             rule.setType("md5");
 
-            rule.execute(EnforcerTestUtils.getHelper());
+            rule.execute();
         });
         assertTrue(exception.getMessage().contains("Checksum unspecified"));
     }
 
     @Test
-    public void testFileChecksumMd5NoTypeSpecifiedFailure() {
+    void testFileChecksumMd5NoTypeSpecifiedFailure() {
         Throwable exception = assertThrows(EnforcerRuleException.class, () -> {
             File f = File.createTempFile("junit", null, temporaryFolder);
 
             rule.setFile(f);
             rule.setChecksum("78e731027d8fd50ed642340b7c9a63b3");
 
-            rule.execute(EnforcerTestUtils.getHelper());
+            rule.execute();
         });
         assertTrue(exception.getMessage().contains("Hash type unspecified"));
     }
 
     @Test
-    public void testFileChecksumMd5ChecksumMismatchFailure() throws IOException {
+    void testFileChecksumMd5ChecksumMismatchFailure() throws IOException {
         File f = File.createTempFile("junit", null, temporaryFolder);
         Throwable exception = assertThrows(EnforcerRuleException.class, () -> {
             FileUtils.fileWrite(f, "message");
@@ -175,7 +175,7 @@ public class TestRequireFileChecksum {
             rule.setChecksum("ffeeddccbbaa99887766554433221100");
             rule.setType("md5");
 
-            rule.execute(EnforcerTestUtils.getHelper());
+            rule.execute();
         });
         assertTrue(exception
                 .getMessage()
@@ -184,7 +184,7 @@ public class TestRequireFileChecksum {
     }
 
     @Test
-    public void testFileChecksumMd5ChecksumMismatchFailureWithMessage() {
+    void testFileChecksumMd5ChecksumMismatchFailureWithMessage() {
         String configuredMessage = "testMessage";
         Throwable exception = assertThrows(EnforcerRuleException.class, () -> {
             File f = File.createTempFile("junit", null, temporaryFolder);
@@ -195,13 +195,13 @@ public class TestRequireFileChecksum {
             rule.setType("md5");
             rule.setMessage(configuredMessage);
 
-            rule.execute(EnforcerTestUtils.getHelper());
+            rule.execute();
         });
         assertTrue(exception.getMessage().contains(configuredMessage));
     }
 
     @Test
-    public void testFileChecksumSha1() throws IOException, EnforcerRuleException {
+    void testFileChecksumSha1() throws IOException, EnforcerRuleException {
         File f = File.createTempFile("junit", null, temporaryFolder);
         FileUtils.fileWrite(f, "message");
 
@@ -209,11 +209,11 @@ public class TestRequireFileChecksum {
         rule.setChecksum("6f9b9af3cd6e8b8a73c2cdced37fe9f59226e27d");
         rule.setType("sha1");
 
-        rule.execute(EnforcerTestUtils.getHelper());
+        rule.execute();
     }
 
     @Test
-    public void testFileChecksumSha256() throws IOException, EnforcerRuleException {
+    void testFileChecksumSha256() throws IOException, EnforcerRuleException {
         File f = File.createTempFile("junit", null, temporaryFolder);
         FileUtils.fileWrite(f, "message");
 
@@ -221,11 +221,11 @@ public class TestRequireFileChecksum {
         rule.setChecksum("ab530a13e45914982b79f9b7e3fba994cfd1f3fb22f71cea1afbf02b460c6d1d");
         rule.setType("sha256");
 
-        rule.execute(EnforcerTestUtils.getHelper());
+        rule.execute();
     }
 
     @Test
-    public void testFileChecksumSha384() throws IOException, EnforcerRuleException {
+    void testFileChecksumSha384() throws IOException, EnforcerRuleException {
         File f = File.createTempFile("junit", null, temporaryFolder);
         FileUtils.fileWrite(f, "message");
 
@@ -234,11 +234,11 @@ public class TestRequireFileChecksum {
                 "353eb7516a27ef92e96d1a319712d84b902eaa828819e53a8b09af7028103a9978ba8feb6161e33c3619c5da4c4666a5");
         rule.setType("sha384");
 
-        rule.execute(EnforcerTestUtils.getHelper());
+        rule.execute();
     }
 
     @Test
-    public void testFileChecksumSha512() throws IOException, EnforcerRuleException {
+    void testFileChecksumSha512() throws IOException, EnforcerRuleException {
         File f = File.createTempFile("junit", null, temporaryFolder);
         FileUtils.fileWrite(f, "message");
 
@@ -247,6 +247,6 @@ public class TestRequireFileChecksum {
                 "f8daf57a3347cc4d6b9d575b31fe6077e2cb487f60a96233c08cb479dbf31538cc915ec6d48bdbaa96ddc1a16db4f4f96f37276cfcb3510b8246241770d5952c");
         rule.setType("sha512");
 
-        rule.execute(EnforcerTestUtils.getHelper());
+        rule.execute();
     }
 }
diff --git a/enforcer-rules/src/test/java/org/apache/maven/plugins/enforcer/TestRequireTextFileChecksum.java b/enforcer-rules/src/test/java/org/apache/maven/enforcer/rules/checksum/TestRequireTextFileChecksum.java
similarity index 66%
rename from enforcer-rules/src/test/java/org/apache/maven/plugins/enforcer/TestRequireTextFileChecksum.java
rename to enforcer-rules/src/test/java/org/apache/maven/enforcer/rules/checksum/TestRequireTextFileChecksum.java
index 4d7fb16..72ea162 100644
--- a/enforcer-rules/src/test/java/org/apache/maven/plugins/enforcer/TestRequireTextFileChecksum.java
+++ b/enforcer-rules/src/test/java/org/apache/maven/enforcer/rules/checksum/TestRequireTextFileChecksum.java
@@ -16,32 +16,55 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.maven.plugins.enforcer;
+package org.apache.maven.enforcer.rules.checksum;
 
 import java.io.File;
 import java.io.IOException;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
+import java.util.Properties;
 
+import org.apache.maven.enforcer.rule.api.EnforcerLogger;
 import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
-import org.apache.maven.enforcer.rules.utils.NormalizeLineSeparatorReader.LineSeparator;
+import org.apache.maven.enforcer.rules.checksum.NormalizeLineSeparatorReader.LineSeparator;
+import org.apache.maven.project.MavenProject;
 import org.codehaus.plexus.util.FileUtils;
 import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
 import org.junit.jupiter.api.io.TempDir;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.mockito.Mockito.when;
 
 /**
  * Test the "RequireTextFileChecksum" rule
  */
-public class TestRequireTextFileChecksum {
+@ExtendWith(MockitoExtension.class)
+class TestRequireTextFileChecksum {
+
+    @Mock
+    private MavenProject project;
+
+    @Mock
+    private EnforcerLogger log;
 
-    private final RequireTextFileChecksum rule = new RequireTextFileChecksum();
+    @InjectMocks
+    private RequireTextFileChecksum rule;
 
     @TempDir
-    public File temporaryFolder;
+    private File temporaryFolder;
+
+    @BeforeEach
+    void setup() {
+        rule.setLog(log);
+    }
 
     @Test
-    public void testFileChecksumMd5NormalizedFromUnixToWindows() throws IOException, EnforcerRuleException {
+    void testFileChecksumMd5NormalizedFromUnixToWindows() throws IOException, EnforcerRuleException {
         File f = File.createTempFile("junit", null, temporaryFolder);
         FileUtils.fileWrite(f, "line1\nline2\n");
 
@@ -51,11 +74,11 @@ public class TestRequireTextFileChecksum {
         rule.setNormalizeLineSeparatorTo(LineSeparator.WINDOWS);
         rule.setEncoding(StandardCharsets.US_ASCII.name());
 
-        rule.execute(EnforcerTestUtils.getHelper());
+        rule.execute();
     }
 
     @Test
-    public void testFileChecksumMd5NormalizedFromWindowsToWindows() throws IOException, EnforcerRuleException {
+    void testFileChecksumMd5NormalizedFromWindowsToWindows() throws IOException, EnforcerRuleException {
         File f = File.createTempFile("junit", null, temporaryFolder);
         FileUtils.fileWrite(f, "line1\r\nline2\r\n");
 
@@ -65,11 +88,11 @@ public class TestRequireTextFileChecksum {
         rule.setNormalizeLineSeparatorTo(LineSeparator.WINDOWS);
         rule.setEncoding(StandardCharsets.US_ASCII.name());
 
-        rule.execute(EnforcerTestUtils.getHelper());
+        rule.execute();
     }
 
     @Test
-    public void testFileChecksumMd5NormalizedFromWindowsToUnix() throws IOException, EnforcerRuleException {
+    void testFileChecksumMd5NormalizedFromWindowsToUnix() throws IOException, EnforcerRuleException {
         File f = File.createTempFile("junit", null, temporaryFolder);
         FileUtils.fileWrite(f, "line1\r\nline2\r\n");
 
@@ -79,11 +102,11 @@ public class TestRequireTextFileChecksum {
         rule.setNormalizeLineSeparatorTo(LineSeparator.UNIX);
         rule.setEncoding(StandardCharsets.US_ASCII.name());
 
-        rule.execute(EnforcerTestUtils.getHelper());
+        rule.execute();
     }
 
     @Test
-    public void testFileChecksumMd5NormalizedFromUnixToUnix() throws IOException, EnforcerRuleException {
+    void testFileChecksumMd5NormalizedFromUnixToUnix() throws IOException, EnforcerRuleException {
         File f = File.createTempFile("junit", null, temporaryFolder);
         FileUtils.fileWrite(f, "line1\nline2\n");
 
@@ -93,22 +116,23 @@ public class TestRequireTextFileChecksum {
         rule.setNormalizeLineSeparatorTo(LineSeparator.UNIX);
         rule.setEncoding(StandardCharsets.US_ASCII.name());
 
-        rule.execute(EnforcerTestUtils.getHelper());
+        rule.execute();
     }
 
     @Test
-    public void testFileChecksumMd5NormalizedWithMissingFileCharsetParameter()
-            throws IOException, EnforcerRuleException {
+    void testFileChecksumMd5NormalizedWithMissingFileCharsetParameter() throws IOException, EnforcerRuleException {
         File f = File.createTempFile("junit", null, temporaryFolder);
         FileUtils.fileWrite(f, "line1\nline2\n");
 
+        when(project.getProperties()).thenReturn(new Properties());
+
         rule.setFile(f);
         rule.setChecksum("4fcc82a88ee38e0aa16c17f512c685c9");
         rule.setType("md5");
         rule.setNormalizeLineSeparatorTo(LineSeparator.UNIX);
 
-        rule.execute(EnforcerTestUtils.getHelper());
+        rule.execute();
         // name is not unique therefore compare generated charset
-        Assertions.assertEquals(Charset.forName(System.getProperty("file.encoding")), rule.encoding);
+        Assertions.assertEquals(Charset.forName(System.getProperty("file.encoding")), rule.getEncoding());
     }
 }
diff --git a/maven-enforcer-plugin/src/it/projects/require-file-checksum/verify.groovy b/maven-enforcer-plugin/src/it/projects/require-file-checksum/verify.groovy
new file mode 100644
index 0000000..7fc215d
--- /dev/null
+++ b/maven-enforcer-plugin/src/it/projects/require-file-checksum/verify.groovy
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+def buildLog = new File(basedir, 'build.log').text
+
+// rule executed
+assert buildLog.contains('[INFO] Rule 0: org.apache.maven.enforcer.rules.checksum.RequireFileChecksum executed')
+assert buildLog.contains('[INFO] Rule 1: org.apache.maven.enforcer.rules.checksum.RequireFileChecksum executed')
+assert buildLog.contains('[INFO] Rule 2: org.apache.maven.enforcer.rules.checksum.RequireFileChecksum executed')
+assert buildLog.contains('[INFO] Rule 3: org.apache.maven.enforcer.rules.checksum.RequireFileChecksum executed')
+assert buildLog.contains('[INFO] Rule 4: org.apache.maven.enforcer.rules.checksum.RequireFileChecksum executed')
diff --git a/maven-enforcer-plugin/src/it/projects/require-textfile-checksum/LICENSE b/maven-enforcer-plugin/src/it/projects/require-textfile-checksum/LICENSE
new file mode 100644
index 0000000..a6301e0
--- /dev/null
+++ b/maven-enforcer-plugin/src/it/projects/require-textfile-checksum/LICENSE
@@ -0,0 +1,16 @@
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
diff --git a/maven-enforcer-plugin/src/it/projects/require-textfile-checksum/pom.xml b/maven-enforcer-plugin/src/it/projects/require-textfile-checksum/pom.xml
new file mode 100644
index 0000000..1fe5c61
--- /dev/null
+++ b/maven-enforcer-plugin/src/it/projects/require-textfile-checksum/pom.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.apache.maven.its.enforcer</groupId>
+  <artifactId>test</artifactId>
+  <version>1.0</version>
+  <url>https://issues.apache.org/jira/browse/MENFORCER-361</url>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-enforcer-plugin</artifactId>
+        <version>@project.version@</version>
+        <executions>
+          <execution>
+            <id>test</id>
+            <goals>
+              <goal>enforce</goal>
+            </goals>
+            <configuration>
+              <rules>
+                <requireTextFileChecksum>
+                  <file>${project.basedir}/LICENSE</file>
+                  <type>md5</type>
+                  <checksum>7c5b65d44e8123e70d24d9eef17e9fa2</checksum>
+                </requireTextFileChecksum>
+                <requireTextFileChecksum>
+                  <file>${project.basedir}/LICENSE</file>
+                  <type>sha1</type>
+                  <checksum>278661cbaf6a1bcbd34e3877b6de0e8bd7097846</checksum>
+                </requireTextFileChecksum>
+                <requireTextFileChecksum>
+                  <file>${project.basedir}/LICENSE</file>
+                  <type>sha256</type>
+                  <checksum>61b825d68516541151e5ce0145e54765c48cd5802b886aee8fb8cf1953f02d10</checksum>
+                </requireTextFileChecksum>
+                <requireTextFileChecksum>
+                  <file>${project.basedir}/LICENSE</file>
+                  <type>sha384</type>
+                  <checksum>6f9e6b81487911c5a339c541016a459acaf8312e430ccabe5c10cb2ddf9a307f4595c78555f911377f4fb853ffe87046</checksum>
+                </requireTextFileChecksum>
+                <requireTextFileChecksum>
+                  <file>${project.basedir}/LICENSE</file>
+                  <type>sha512</type>
+                  <checksum>c51c3cf07c87af78dd7af4407ae3993ea1051d8a7c260cf34bbaa41c468dcd3b62d2be3d9a09807a8595d0065e2d75d1bf9ffc8276d567a983ff057f6b51b0cc</checksum>
+                </requireTextFileChecksum>
+              </rules>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/maven-enforcer-plugin/src/it/projects/require-textfile-checksum/verify.groovy b/maven-enforcer-plugin/src/it/projects/require-textfile-checksum/verify.groovy
new file mode 100644
index 0000000..b74bdfe
--- /dev/null
+++ b/maven-enforcer-plugin/src/it/projects/require-textfile-checksum/verify.groovy
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+def buildLog = new File(basedir, 'build.log').text
+
+// rule executed
+assert buildLog.contains('[INFO] Rule 0: org.apache.maven.enforcer.rules.checksum.RequireTextFileChecksum executed')
+assert buildLog.contains('[INFO] Rule 1: org.apache.maven.enforcer.rules.checksum.RequireTextFileChecksum executed')
+assert buildLog.contains('[INFO] Rule 2: org.apache.maven.enforcer.rules.checksum.RequireTextFileChecksum executed')
+assert buildLog.contains('[INFO] Rule 3: org.apache.maven.enforcer.rules.checksum.RequireTextFileChecksum executed')
+assert buildLog.contains('[INFO] Rule 4: org.apache.maven.enforcer.rules.checksum.RequireTextFileChecksum executed')