You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by pk...@apache.org on 2024/09/17 13:54:57 UTC

(logging-parent) branch main updated: Replace BeanShell with Groovy (#241)

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

pkarwasz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/logging-parent.git


The following commit(s) were added to refs/heads/main by this push:
     new 96f21d8  Replace BeanShell with Groovy (#241)
96f21d8 is described below

commit 96f21d861d93559f64c15c0ce0c8938d24ffc20a
Author: Piotr P. Karwasz <pi...@github.copernik.eu>
AuthorDate: Tue Sep 17 15:54:51 2024 +0200

    Replace BeanShell with Groovy (#241)
    
    * Replace BeanShell with Groovy
    
    This replaces the BeanShell script used to create source and binary
    distribution with a Groovy script.
    The main motivations for the change are:
    
    - While the [BeanShell project](https://github.com/beanshell/beanshell) is
      still active, the `2.x` branch has no releases in Maven Central since
      2015. The `3.x` branch has only snapshots.
    
      [Apache Groovy](https://groovy-lang.org/) on the other hand is a very
      active project.
    
    - The [`beanshell-maven-plugin`](https://github.com/genthaler/beanshell-maven-plugin) seems dormant since 2017 or
      does not have enough users to report bugs against it.
    
      The [`gmaven-plugin`](https://github.com/groovy/GMavenPlus) on the
      other hand is relatively active and supported by the Apache Groovy
      team.
    
      Closes #196.
---
 pom.xml                                           | 292 ++++++++++++----------
 src/changelog/.11.x.x/196_beanshell_to_groovy.xml |   8 +
 2 files changed, 166 insertions(+), 134 deletions(-)

diff --git a/pom.xml b/pom.xml
index d9643c6..c049df4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -218,7 +218,6 @@
 
     <!-- plugin versions -->
     <asciidoctor-maven-plugin.version>3.0.0</asciidoctor-maven-plugin.version>
-    <beanshell-maven-plugin.version>1.4</beanshell-maven-plugin.version>
     <bnd-maven-plugin.version>7.0.0</bnd-maven-plugin.version>
     <bnd-baseline-maven-plugin.version>7.0.0</bnd-baseline-maven-plugin.version>
     <build-helper-maven-plugin.version>3.6.0</build-helper-maven-plugin.version>
@@ -227,6 +226,7 @@
     <exec-maven-plugin.version>3.3.0</exec-maven-plugin.version>
     <flatten-maven-plugin.version>1.6.0</flatten-maven-plugin.version>
     <frontend-maven-plugin.version>1.15.0</frontend-maven-plugin.version>
+    <gmavenplus-plugin.version>3.0.2</gmavenplus-plugin.version>
     <jacoco-maven-plugin.version>0.8.12</jacoco-maven-plugin.version>
     <log4j-changelog-maven-plugin.version>0.9.0</log4j-changelog-maven-plugin.version>
     <maven-artifact-plugin.version>3.5.1</maven-artifact-plugin.version>
@@ -244,6 +244,7 @@
     <!-- `findsecbugs-plugin:1.13.0` contains a bug blocking Log4j compilation: https://github.com/find-sec-bugs/find-sec-bugs/pull/728
          Hence, pinning the `1.12.0` instead. -->
     <findsecbugs-plugin.version>1.13.0</findsecbugs-plugin.version>
+    <groovy.version>4.0.22</groovy.version>
 
     <!-- site-specific versions -->
     <!-- We use a separate property than `project.version` to refer to the most recent _published_ version of the project.
@@ -298,6 +299,7 @@
         <artifactId>org.osgi.annotation.versioning</artifactId>
         <version>${osgi.annotation.versioning.version}</version>
       </dependency>
+
     </dependencies>
   </dependencyManagement>
 
@@ -314,12 +316,6 @@
           <version>${asciidoctor-maven-plugin.version}</version>
         </plugin>
 
-        <plugin>
-          <groupId>com.github.genthaler</groupId>
-          <artifactId>beanshell-maven-plugin</artifactId>
-          <version>${beanshell-maven-plugin.version}</version>
-        </plugin>
-
         <plugin>
           <groupId>biz.aQute.bnd</groupId>
           <artifactId>bnd-baseline-maven-plugin</artifactId>
@@ -364,6 +360,26 @@
           <version>${flatten-maven-plugin.version}</version>
         </plugin>
 
+        <plugin>
+          <groupId>org.codehaus.gmavenplus</groupId>
+          <artifactId>gmavenplus-plugin</artifactId>
+          <version>${gmavenplus-plugin.version}</version>
+          <dependencies>
+            <dependency>
+              <groupId>org.apache.groovy</groupId>
+              <artifactId>groovy</artifactId>
+              <version>${groovy.version}</version>
+              <scope>runtime</scope>
+            </dependency>
+            <dependency>
+              <groupId>org.apache.groovy</groupId>
+              <artifactId>groovy-ant</artifactId>
+              <version>${groovy.version}</version>
+              <scope>runtime</scope>
+            </dependency>
+          </dependencies>
+        </plugin>
+
         <plugin>
           <groupId>org.jacoco</groupId>
           <artifactId>jacoco-maven-plugin</artifactId>
@@ -1107,7 +1123,7 @@
 
       <build>
 
-        <defaultGoal>enforcer:enforce@enforce-distribution-arguments bsh:run@create-distribution</defaultGoal>
+        <defaultGoal>enforcer:enforce@enforce-distribution-arguments gplus:execute@create-distribution</defaultGoal>
 
         <plugins>
 
@@ -1126,7 +1142,7 @@
                   <rules>
                     <requireProperty>
                       <property>attachmentFilepathPattern</property>
-                      <message>You must set an `attachmentFilepathPattern` property for the regex pattern matched against the full filepath for determining attachments to be included in the distribution!</message>
+                      <message>You must set an `attachmentFilepathPattern` property for the regex pattern matched against the filepath relative to the main project directory for determining attachments to be included in the distribution!</message>
                     </requireProperty>
                     <requireProperty>
                       <property>attachmentCount</property>
@@ -1141,8 +1157,8 @@
 
           <!-- Create the distribution ZIP -->
           <plugin>
-            <groupId>com.github.genthaler</groupId>
-            <artifactId>beanshell-maven-plugin</artifactId>
+            <groupId>org.codehaus.gmavenplus</groupId>
+            <artifactId>gmavenplus-plugin</artifactId>
             <dependencies>
               <dependency>
                 <groupId>org.eclipse.jgit</groupId>
@@ -1154,131 +1170,139 @@
               <execution>
                 <id>create-distribution</id>
                 <goals>
-                  <goal>run</goal>
+                  <goal>execute</goal>
                 </goals>
                 <configuration>
-                  <script><![CDATA[import java.io.*;
-                    import java.nio.file.*;
-                    import java.util.*;
-                    import java.util.function.*;
-                    import java.util.stream.*;
-                    import java.util.zip.*;
-
-                    import org.eclipse.jgit.dircache.*;
-                    import org.eclipse.jgit.lib.Repository;
-                    import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
-
-                    String outputTimestamp = project.getProperties().getProperty("project.build.outputTimestamp");
-                    long timestampMillis = java.time.Instant.parse(outputTimestamp).toEpochMilli();
-                    zip(String zipFileName, Map pathByFile) {
-                        OutputStream outputStream = new FileOutputStream(zipFileName);
-                        ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
-                        try {
-                            for (String file : pathByFile.keySet()) {
-                                Path path = pathByFile.get(file);
-                                // Skip directories, which is tracked by Git only when it is a symlink
-                                if (Files.isDirectory(path, /* required for BSH method resolution: */ new LinkOption[0])) {
-                                    continue;
-                                }
-                                try {
-                                    ZipEntry zipEntry = new ZipEntry(file);
-                                    zipEntry.setTime(timestampMillis);
-                                    zipOutputStream.putNextEntry(zipEntry);
-                                    zipOutputStream.write(Files.readAllBytes(path));
-                                    zipOutputStream.closeEntry();
-                                } catch (Exception error) {
-                                    String message = String.format(
-                                        "failed processing file `%s` at path `%s`",
-                                        new Object[]{file, path});
-                                    throw new RuntimeException(message, error);
-                                }
-                            }
-                        } catch (Exception error) {
-                            String message = String.format("failed creating ZIP archive `%s`", new Object[]{zipFileName});
-                            Exception extendedError = new RuntimeException(message, error);
-                            // Supplement diagnostics
-                            extendedError.printStackTrace(System.err);
-                            throw extendedError;
-                        } finally {
-                            zipOutputStream.close();
-                        }
-                    }
-
-                    // Find Git-tracked files
-                    SortedMap pathByFile = new TreeMap();
-                    Repository repo = new FileRepositoryBuilder().readEnvironment().findGitDir().build();
-                    DirCache repoCache = repo.readDirCache();
-                    String repoDirectoryParent = repo.getDirectory().getParent();
-                    for (int repoCacheEntryIndex = 0; repoCacheEntryIndex < repoCache.getEntryCount(); repoCacheEntryIndex++) {
-                        DirCacheEntry repoCacheEntry = repoCache.getEntry(repoCacheEntryIndex);
-                        String repoCacheEntryPath = repoCacheEntry.getPathString();
-                        pathByFile.put(repoCacheEntryPath, new File(repoDirectoryParent, repoCacheEntryPath).toPath());
-                    }
-
-                    // Create the source distribution using Git-tracked files
-                    zip("target/src.zip", pathByFile);
-                    System.out.format("Generated the source distribution (`src.zip`) containing %d files.%n", new Object[]{pathByFile.size()});
-
-                    // Short-circuit if there is no binary distribution expected
-                    if (${attachmentCount} == 0) {
-                        return;
-                    }
-
-                    // Find auxiliary files that will go into the binary distribution
-                    SortedMap pathByFile = new TreeMap();
-                    pathByFile.put("RELEASE-NOTES.adoc", new File("${project.build.directory}/generated-site/antora/modules/ROOT/pages/_release-notes/${project.version}.adoc").toPath());
-                    pathByFile.put("README.adoc", new File("README.adoc").toPath());
-                    pathByFile.put("NOTICE.txt", new File("NOTICE.txt").toPath());
-                    pathByFile.put("LICENSE.txt", new File("LICENSE.txt").toPath());
-
-                    // Find attachments that will go into the binary distribution
-                    Path projectDir = Paths.get("${maven.multiModuleProjectDirectory}", new String[0]);
-                    String attachmentFilepathPattern = "${attachmentFilepathPattern}";
-                    System.out.format("Locating attachments matching the provided pattern: `%s`%n", new Object[] {attachmentFilepathPattern});
-                    SortedMap attachmentPathByFile = new TreeMap();
-                    Stream paths = Files.walk(new File(repoDirectoryParent).toPath(), 32, /* required for BSH method resolution: */ new FileVisitOption[0]);
-                    try {
-                        paths.forEach(new Consumer() {
-                            public void accept(Path path) {
-                                if (Files.isRegularFile(path, /* required for BSH method resolution: */ new LinkOption[0])) {
-                                    String relativePath = projectDir.relativize(path).toString();
-                                    if (relativePath.matches(attachmentFilepathPattern)) {
-                                        attachmentPathByFile.put(path.getFileName().toString(), path);
-                                    }
-                                }
-                            }
-                        });
-                    } catch (Exception error) {
-                        // Supplement diagnostics
-                        error.printStackTrace(System.err);
-                        throw error;
-                    } finally {
-                        paths.close();
-                    }
-
-                    // Check if no attachments were found
-                    if (${attachmentCount} != attachmentPathByFile.size()) {
-                        System.err.println("Attachments:");
-                        int[] i = {0};
-                        attachmentPathByFile.values().forEach(new Consumer() {
-                            public void accept(Path path) {
-                                System.err.format("  [%2d] %s%n", new Object[]{++i[0], path});
-                            }
-                        });
-                        System.err.format(
-                                "Error: Was expecting %d attachments, found %d!%n",
-                                new Object[]{${attachmentCount}, attachmentPathByFile.size()});
-                        System.err.println("Tip: Have you already executed the Maven `package` goal?");
-                        System.exit(1);
-                    }
-
-                    // Create the binary distribution
-                    pathByFile.putAll(attachmentPathByFile);
-                    zip("target/bin.zip", pathByFile);
-                    System.out.format("Generated the binary distribution (`bin.zip`) containing following %d files:%n", new Object[] {pathByFile.size()});
-                    for (String file : pathByFile.keySet()) {
-                        System.out.println("-> " + file);
-                    }]]></script>
+                  <!-- List of all the parameters used by the script -->
+                  <properties>
+                    <!-- Output directory for the archives -->
+                    <outputDirectory>${project.build.directory}</outputDirectory>
+                    <!-- Timestamp for the archived file entries -->
+                    <outputTimestamp>${project.build.outputTimestamp}</outputTimestamp>
+                    <!-- Number of attachments expected to be found -->
+                    <attachmentCountString>${attachmentCount}</attachmentCountString>
+                    <!--
+                      ~ Regex pattern for the binary files to include.
+                      ~ The filepath of each file, relative to the main project directory, is matched against this pattern.
+                      -->
+                    <attachmentFilepathPatternString>${attachmentFilepathPattern}</attachmentFilepathPatternString>
+                    <!-- Path of the release notes -->
+                    <releaseNotes>${project.build.directory}/generated-site/antora/modules/ROOT/pages/_release-notes/${project.version}.adoc</releaseNotes>
+                  </properties>
+                  <scripts>
+                    <script><![CDATA[import java.io.*;
+                      import java.nio.file.*;
+                      import java.util.*;
+                      import java.util.function.*;
+                      import java.util.regex.*;
+                      import java.util.stream.*;
+                      import java.util.zip.*;
+                      import java.time.Instant;
+
+                      import org.eclipse.jgit.dircache.*;
+                      import org.eclipse.jgit.lib.Repository;
+                      import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
+
+                      long timestampMillis = Instant.parse(outputTimestamp).toEpochMilli()
+                      // These are ensured by the `enforcer` rule
+                      int attachmentCount = attachmentCountString.toInteger()
+                      Pattern attachmentFilepathPattern = Pattern.compile(attachmentFilepathPatternString)
+
+                      def zip = { String zipFileName, Map<String, Path> pathByFile ->
+                          try (OutputStream outputStream = new FileOutputStream(zipFileName)
+                              ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream)) {
+                              pathByFile.each {
+                                  // Skip directories, which is tracked by Git only when it is a symlink
+                                  if (!Files.isDirectory(it.value)) {
+                                      try {
+                                          log.debug("adding file `" + it.key + "` at path `" + it.value + "`")
+                                          ZipEntry zipEntry = new ZipEntry(it.key)
+                                          zipEntry.setTime(timestampMillis)
+                                          zipOutputStream.putNextEntry(zipEntry)
+                                          zipOutputStream.write(Files.readAllBytes(it.value))
+                                          zipOutputStream.closeEntry()
+                                      } catch (Exception error) {
+                                          // The exception is printed by the catch below, no need to attach it here
+                                          log.error("failed processing file `" + it.key + "` at path `" + it.value + "`")
+                                          throw error
+                                      }
+                                  }
+
+                              }
+                          } catch (Exception error) {
+                              log.error("failed creating ZIP archive `" + zipFileName + "`", error)
+                              throw error
+                          }
+                      }
+
+                      // Find Git-tracked files
+                      SortedMap pathByFile = new TreeMap()
+                      Repository repo = new FileRepositoryBuilder().readEnvironment().findGitDir().build()
+                      DirCache repoCache = repo.readDirCache()
+                      Path projectDir = repo.getDirectory().toPath().getParent()
+                      for (int repoCacheEntryIndex = 0; repoCacheEntryIndex < repoCache.getEntryCount(); repoCacheEntryIndex++) {
+                          DirCacheEntry repoCacheEntry = repoCache.getEntry(repoCacheEntryIndex)
+                          String repoCacheEntryPath = repoCacheEntry.getPathString()
+                          pathByFile.put(repoCacheEntryPath, projectDir.resolve(repoCacheEntryPath))
+                      }
+
+                      // Create the source distribution using Git-tracked files
+                      zip(outputDirectory + "/src.zip", pathByFile)
+                      log.info("Generated the source distribution (`src.zip`) containing " + pathByFile.size() + " files.")
+
+                      // Short-circuit if there is no binary distribution expected
+                      if (attachmentCount == 0) {
+                          return
+                      }
+
+                      // Find auxiliary files that will go into the binary distribution
+                      pathByFile = new TreeMap()
+                      pathByFile.put("RELEASE-NOTES.adoc", projectDir.resolve(releaseNotes))
+                      pathByFile.put("README.adoc", projectDir.resolve("README.adoc"))
+                      pathByFile.put("NOTICE.txt", projectDir.resolve("NOTICE.txt"))
+                      pathByFile.put("LICENSE.txt", projectDir.resolve("LICENSE.txt"))
+
+                      // Find attachments that will go into the binary distribution
+                      log.info("Locating attachments matching the provided pattern: " + attachmentFilepathPattern)
+                      SortedMap attachmentPathByFile = new TreeMap()
+                      Stream paths = Files.walk(projectDir, 32)
+                      try {
+                          paths.forEach { path ->
+                              if (Files.isRegularFile(path)) {
+                                  String relativePath = projectDir.relativize(path).toString()
+                                  if (attachmentFilepathPattern.matcher(relativePath).matches()) {
+                                      attachmentPathByFile.put(path.getFileName().toString(), path)
+                                  }
+                              }
+                          }
+                      } catch (Exception error) {
+                          // Supplement diagnostics
+                          log.error(error)
+                          throw error
+                      } finally {
+                          paths.close()
+                      }
+
+                      StringBuilder attachments = new StringBuilder()
+                      attachmentPathByFile.eachWithIndex { entry, index ->
+                          attachments.append("\n\t[" + (index + 1) + "] " + entry.value);
+                      }
+                      // Check if no attachments were found
+                      if (attachmentCount != attachmentPathByFile.size()) {
+                          log.error("Attachments found:" + attachments)
+                          String errorMsg = "Error: Was expecting " + attachmentCount + " attachments, found " + attachmentPathByFile.size() + "!"
+                          log.error(errorMsg)
+                          log.error("Tip: Have you already executed the Maven `package` goal?")
+                          throw new RuntimeException(errorMsg)
+                      }
+
+                      // Create the binary distribution
+                      pathByFile.putAll(attachmentPathByFile)
+                      zip(outputDirectory + "/bin.zip", pathByFile)
+                      log.info("Generated the binary distribution (`bin.zip`) containing the following " +
+                          (pathByFile.size() - 4) + " binary files:" + attachments)
+]]></script>
+                  </scripts>
                 </configuration>
               </execution>
             </executions>
diff --git a/src/changelog/.11.x.x/196_beanshell_to_groovy.xml b/src/changelog/.11.x.x/196_beanshell_to_groovy.xml
new file mode 100644
index 0000000..403df22
--- /dev/null
+++ b/src/changelog/.11.x.x/196_beanshell_to_groovy.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns="https://logging.apache.org/xml/ns"
+       xsi:schemaLocation="https://logging.apache.org/xml/ns https://logging.apache.org/xml/ns/log4j-changelog-0.xsd"
+       type="changed">
+  <issue id="196" link="https://github.com/apache/logging-parent/issues/196"/>
+  <description format="asciidoc">Switch the distribution script from BeanShell to Groovy.</description>
+</entry>