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/12 19:14:21 UTC

[maven-enforcer] branch master updated: [MENFORCER-458] Move Require*Checksum to new API

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

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


The following commit(s) were added to refs/heads/master by this push:
     new b122ca1  [MENFORCER-458] Move Require*Checksum to new API
b122ca1 is described below

commit b122ca18e0b8870562ce850f0ac151c6ae1b00e9
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')