You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by mb...@apache.org on 2021/11/17 17:11:00 UTC

[asterixdb] branch master updated: [NO ISSUE][HYR][LIC] Configurable multiple LICENSE/NOTICE handling

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

mblow pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/asterixdb.git


The following commit(s) were added to refs/heads/master by this push:
     new 46e830f  [NO ISSUE][HYR][LIC] Configurable multiple LICENSE/NOTICE handling
46e830f is described below

commit 46e830fddbefd652f6242a6c786e436edfc35e5a
Author: Michael Blow <mb...@apache.org>
AuthorDate: Tue Nov 16 21:51:24 2021 -0500

    [NO ISSUE][HYR][LIC] Configurable multiple LICENSE/NOTICE handling
    
    - += license.onMultipleEmbedded[License|Notice] flag, with gav:[concat|first] values
    - 'concat' takes the contents of all LICENSE/NOTICE files, and concatenates them
      with delimiters indicating the source of each content
    - 'first' selects the first match encountered in the 'jar'
    
    The default behavior without flag is 'concat', with a WARNING emitted
    
    Change-Id: I0cd5a008f71f80ac99eaf29f1e286eb222640480
    Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/14104
    Reviewed-by: Michael Blow <mb...@apache.org>
    Reviewed-by: Hussain Towaileb <hu...@gmail.com>
    Integration-Tests: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Tested-by: Michael Blow <mb...@apache.org>
---
 .../hyracks/maven/license/GenerateFileMojo.java    | 102 +++++++++++++++++----
 .../apache/hyracks/maven/license/ProjectFlag.java  |   4 +
 2 files changed, 88 insertions(+), 18 deletions(-)

diff --git a/hyracks-fullstack/hyracks/hyracks-maven-plugins/license-automation-plugin/src/main/java/org/apache/hyracks/maven/license/GenerateFileMojo.java b/hyracks-fullstack/hyracks/hyracks-maven-plugins/license-automation-plugin/src/main/java/org/apache/hyracks/maven/license/GenerateFileMojo.java
index 6bc92b8..347c19a 100644
--- a/hyracks-fullstack/hyracks/hyracks-maven-plugins/license-automation-plugin/src/main/java/org/apache/hyracks/maven/license/GenerateFileMojo.java
+++ b/hyracks-fullstack/hyracks/hyracks-maven-plugins/license-automation-plugin/src/main/java/org/apache/hyracks/maven/license/GenerateFileMojo.java
@@ -18,11 +18,15 @@
  */
 package org.apache.hyracks.maven.license;
 
+import static org.apache.hyracks.maven.license.GenerateFileMojo.EmbeddedArtifact.LICENSE;
+import static org.apache.hyracks.maven.license.GenerateFileMojo.EmbeddedArtifact.NOTICE;
 import static org.apache.hyracks.maven.license.ProjectFlag.ALTERNATE_LICENSE_FILE;
 import static org.apache.hyracks.maven.license.ProjectFlag.ALTERNATE_NOTICE_FILE;
 import static org.apache.hyracks.maven.license.ProjectFlag.IGNORE_MISSING_EMBEDDED_LICENSE;
 import static org.apache.hyracks.maven.license.ProjectFlag.IGNORE_MISSING_EMBEDDED_NOTICE;
 import static org.apache.hyracks.maven.license.ProjectFlag.IGNORE_NOTICE_OVERRIDE;
+import static org.apache.hyracks.maven.license.ProjectFlag.ON_MULTIPLE_EMBEDDED_LICENSE;
+import static org.apache.hyracks.maven.license.ProjectFlag.ON_MULTIPLE_EMBEDDED_NOTICE;
 
 import java.io.File;
 import java.io.FileOutputStream;
@@ -334,26 +338,55 @@ public class GenerateFileMojo extends LicenseMojo {
         }
     }
 
+    enum EmbeddedArtifact {
+        NOTICE,
+        LICENSE
+    }
+
     private void resolveNoticeFiles() throws MojoExecutionException, IOException {
-        // TODO(mblow): this will match *any* NOTICE[.(txt|md)] file located within the artifact-
-        // this seems way too liberal
-        resolveArtifactFiles("NOTICE", IGNORE_MISSING_EMBEDDED_NOTICE, ALTERNATE_NOTICE_FILE,
-                entry -> entry.getName().matches("(.*/|^)" + "NOTICE" + "(.(txt|md))?"), Project::setNoticeText,
-                text -> stripFoundationAssertionFromNotices ? FOUNDATION_PATTERN.matcher(text).replaceAll("") : text);
+        resolveArtifactFiles(NOTICE);
     }
 
     private void resolveLicenseFiles() throws MojoExecutionException, IOException {
-        // TODO(mblow): this will match *any* LICENSE[.(txt|md)] file located within the artifact-
-        // this seems way too liberal
-        resolveArtifactFiles("LICENSE", IGNORE_MISSING_EMBEDDED_LICENSE, ALTERNATE_LICENSE_FILE,
-                entry -> entry.getName().matches("(.*/|^)" + "LICENSE" + "(.(txt|md))?"), Project::setLicenseText,
-                UnaryOperator.identity());
+        resolveArtifactFiles(LICENSE);
     }
 
-    private void resolveArtifactFiles(final String name, final ProjectFlag ignoreFlag,
-            final ProjectFlag alternateFilenameFlag, final Predicate<JarEntry> filter,
-            final BiConsumer<Project, String> consumer, final UnaryOperator<String> contentTransformer)
-            throws MojoExecutionException, IOException {
+    private void resolveArtifactFiles(final EmbeddedArtifact artifact) throws MojoExecutionException, IOException {
+        final String name;
+        final ProjectFlag ignoreFlag;
+        final ProjectFlag alternateFilenameFlag;
+        final ProjectFlag onMultipleFlag;
+        final Predicate<JarEntry> filter;
+        final BiConsumer<Project, String> consumer;
+        final UnaryOperator<String> contentTransformer;
+
+        switch (artifact) {
+            case NOTICE:
+                name = "NOTICE";
+                ignoreFlag = IGNORE_MISSING_EMBEDDED_NOTICE;
+                alternateFilenameFlag = ALTERNATE_NOTICE_FILE;
+                onMultipleFlag = ON_MULTIPLE_EMBEDDED_NOTICE;
+                // TODO(mblow): this will match *any* NOTICE[.(txt|md)] file located within the artifact-
+                // this seems way too liberal
+                filter = entry -> entry.getName().matches("(.*/|^)" + "NOTICE" + "(.(txt|md))?");
+                consumer = Project::setNoticeText;
+                contentTransformer = UnaryOperator.identity();
+                break;
+            case LICENSE:
+                name = "LICENSE";
+                ignoreFlag = IGNORE_MISSING_EMBEDDED_LICENSE;
+                alternateFilenameFlag = ALTERNATE_LICENSE_FILE;
+                onMultipleFlag = ON_MULTIPLE_EMBEDDED_LICENSE;
+                // TODO(mblow): this will match *any* LICENSE[.(txt|md)] file located within the artifact-
+                // this seems way too liberal
+                filter = entry -> entry.getName().matches("(.*/|^)" + "LICENSE" + "(.(txt|md))?");
+                consumer = Project::setLicenseText;
+                contentTransformer = stripFoundationAssertionFromNotices
+                        ? text -> FOUNDATION_PATTERN.matcher(text).replaceAll("") : UnaryOperator.identity();
+                break;
+            default:
+                throw new IllegalStateException("NYI: " + artifact);
+        }
         for (Project p : getProjects()) {
             File artifactFile = new File(p.getArtifactPath());
             if (!artifactFile.exists()) {
@@ -371,12 +404,45 @@ public class GenerateFileMojo extends LicenseMojo {
                     warnUnlessFlag(p, ignoreFlag, "No " + name + " file found for " + p.gav());
                 } else {
                     if (matches.size() > 1) {
-                        getLog().warn("Multiple " + name + " files found for " + p.gav() + ": " + matches.keySet()
-                                + "; taking first");
+                        // TODO(mblow): duplicate elimination on matches content
+                        warnUnlessFlag(p, onMultipleFlag,
+                                "Multiple " + name + " files found for " + p.gav() + ": " + matches.keySet() + "!");
+                        String onMultiple = (String) getProjectFlag(p.gav(), onMultipleFlag);
+                        if (onMultiple == null) {
+                            onMultiple = "concat";
+                        }
+                        switch (onMultiple.toLowerCase()) {
+                            case "concat":
+                                getLog().info("...concatenating all " + matches.size() + " matches");
+                                StringBuilder content = new StringBuilder();
+                                for (Map.Entry<String, JarEntry> match : matches.entrySet()) {
+                                    resolveContent(p, jarFile, match.getValue(), contentTransformer, (p1, text) -> {
+                                        content.append("------------ BEGIN <").append(match.getKey())
+                                                .append("> ------------\n");
+                                        content.append(text);
+                                        if (content.charAt(content.length() - 1) != '\n') {
+                                            content.append('\n');
+                                        }
+                                        content.append("------------ END <").append(match.getKey())
+                                                .append("> ------------\n");
+                                    }, name);
+                                }
+                                consumer.accept(p, content.toString());
+                                break;
+                            case "first":
+                                Map.Entry<String, JarEntry> first = matches.entrySet().iterator().next();
+                                getLog().info("...taking first match: " + first.getKey());
+                                resolveContent(p, jarFile, first.getValue(), contentTransformer, consumer, name);
+                                break;
+                            default:
+                                throw new IllegalArgumentException("unknown value for " + onMultipleFlag.propName()
+                                        + ": " + onMultiple.toLowerCase());
+                        }
                     } else {
-                        getLog().info(p.gav() + " has " + name + " file: " + matches.keySet());
+                        Map.Entry<String, JarEntry> match = matches.entrySet().iterator().next();
+                        getLog().info(p.gav() + " has " + name + " file: " + match.getKey());
+                        resolveContent(p, jarFile, match.getValue(), contentTransformer, consumer, name);
                     }
-                    resolveContent(p, jarFile, matches.values().iterator().next(), contentTransformer, consumer, name);
                 }
             }
         }
diff --git a/hyracks-fullstack/hyracks/hyracks-maven-plugins/license-automation-plugin/src/main/java/org/apache/hyracks/maven/license/ProjectFlag.java b/hyracks-fullstack/hyracks/hyracks-maven-plugins/license-automation-plugin/src/main/java/org/apache/hyracks/maven/license/ProjectFlag.java
index dd8fdf7..6fd15a8 100644
--- a/hyracks-fullstack/hyracks/hyracks-maven-plugins/license-automation-plugin/src/main/java/org/apache/hyracks/maven/license/ProjectFlag.java
+++ b/hyracks-fullstack/hyracks/hyracks-maven-plugins/license-automation-plugin/src/main/java/org/apache/hyracks/maven/license/ProjectFlag.java
@@ -33,6 +33,8 @@ enum ProjectFlag {
     IGNORE_MISSING_EMBEDDED_NOTICE,
     IGNORE_LICENSE_OVERRIDE,
     IGNORE_NOTICE_OVERRIDE,
+    ON_MULTIPLE_EMBEDDED_LICENSE,
+    ON_MULTIPLE_EMBEDDED_NOTICE,
     ALTERNATE_LICENSE_FILE,
     ALTERNATE_NOTICE_FILE;
 
@@ -59,6 +61,8 @@ enum ProjectFlag {
                 break;
             case ALTERNATE_LICENSE_FILE:
             case ALTERNATE_NOTICE_FILE:
+            case ON_MULTIPLE_EMBEDDED_NOTICE:
+            case ON_MULTIPLE_EMBEDDED_LICENSE:
                 for (String spec : StringUtils.split(value, ",")) {
                     String[] specSplit = StringUtils.split(spec, ":");
                     if (specSplit.length != 2) {