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 2023/01/27 14:19:38 UTC

[asterixdb] 08/10: [NO ISSUE][LIC] Add ability to exclude specific shadowed artifacts

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

commit fd8cd3051cf97798e8945c800ef787c507e74375
Author: Michael Blow <mb...@apache.org>
AuthorDate: Tue Jan 17 17:33:40 2023 -0500

    [NO ISSUE][LIC] Add ability to exclude specific shadowed artifacts
    
    Change-Id: Iaa63954b8c328862f0e93c9c1f9fc32cc13e822a
    Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/17317
    Reviewed-by: Michael Blow <mb...@apache.org>
    Reviewed-by: Murtadha Hubail <mh...@apache.org>
    Tested-by: Michael Blow <mb...@apache.org>
---
 .../hyracks/maven/license/GenerateFileMojo.java    | 62 ++++++++++++++--------
 .../apache/hyracks/maven/license/LicenseMojo.java  |  6 +++
 .../apache/hyracks/maven/license/ProjectFlag.java  | 39 +++++++++++---
 3 files changed, 78 insertions(+), 29 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 8edc1b212f..297160e479 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
@@ -20,11 +20,13 @@ 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.LicenseUtil.toGav;
 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.IGNORE_SHADOWED_DEPENDENCIES;
 import static org.apache.hyracks.maven.license.ProjectFlag.ON_MULTIPLE_EMBEDDED_LICENSE;
 import static org.apache.hyracks.maven.license.ProjectFlag.ON_MULTIPLE_EMBEDDED_NOTICE;
 
@@ -36,6 +38,7 @@ import java.io.StringWriter;
 import java.io.Writer;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.Enumeration;
 import java.util.HashMap;
@@ -55,8 +58,10 @@ import java.util.function.UnaryOperator;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
 import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.hyracks.maven.license.freemarker.IndentDirective;
@@ -527,39 +532,50 @@ public class GenerateFileMojo extends LicenseMojo {
         Set<MavenProject> projects = new TreeSet<>(Comparator.comparing(MavenProject::getId));
         projects.addAll(dependencyLicenseMap.keySet());
         for (MavenProject p : projects) {
-            boolean finished = false;
             File artifactFile = p.getArtifact().getFile();
             if (!artifactFile.exists()) {
                 throw new MojoExecutionException("Artifact file " + artifactFile + " does not exist!");
             } else if (!artifactFile.getName().endsWith(".jar")) {
                 getLog().info("Skipping unknown artifact file type: " + artifactFile);
-                finished = true;
+                continue;
             }
-            if (!finished) {
-                try (JarFile jarFile = new JarFile(artifactFile)) {
-                    SortedMap<String, JarEntry> matches = gatherMatchingEntries(jarFile,
-                            entry -> entry.getName().matches("(.*/|^)" + "pom\\.properties"));
-                    if (!matches.isEmpty()) {
-                        for (JarEntry entry : matches.values()) {
-                            Properties props = new Properties();
-                            props.load(jarFile.getInputStream(entry));
-                            String groupId = props.getProperty("groupId");
-                            String artifactId = props.getProperty("artifactId");
-                            String version = props.getProperty("version");
-                            String gav = groupId + ":" + artifactId + ":" + version;
-                            if (!dependencyGavMap.containsKey(gav)) {
-                                getLog().info("adding " + gav + " (shadowed from " + p.getId() + ")");
-                                ArtifactHandler handler = new DefaultArtifactHandler("jar");
-                                String[] gavParts = StringUtils.split(gav, ':');
-                                Artifact manualDep = new DefaultArtifact(gavParts[0], gavParts[1], gavParts[2],
-                                        Artifact.SCOPE_COMPILE, "jar", null, handler);
-                                processArtifact(manualDep, dependencyLicenseMap, dependencyGavMap, true);
+            @SuppressWarnings("unchecked")
+            List<String[]> specs = (List<String[]>) getProjectFlags()
+                    .getOrDefault(Pair.of(toGav(p), IGNORE_SHADOWED_DEPENDENCIES), Collections.emptyList());
+            getLog().debug(p + " has " + IGNORE_SHADOWED_DEPENDENCIES.propName() + " set to "
+                    + specs.stream().map(ArrayUtils::toString).collect(Collectors.joining(",")));
+            try (JarFile jarFile = new JarFile(artifactFile)) {
+                SortedMap<String, JarEntry> matches = gatherMatchingEntries(jarFile,
+                        entry -> entry.getName().matches("(.*/|^)" + "pom\\.properties"));
+                if (!matches.isEmpty()) {
+                    jarEntryLoop: for (JarEntry entry : matches.values()) {
+                        Properties props = new Properties();
+                        props.load(jarFile.getInputStream(entry));
+                        String groupId = props.getProperty("groupId");
+                        String artifactId = props.getProperty("artifactId");
+                        String version = props.getProperty("version");
+                        String gav = groupId + ":" + artifactId + ":" + version;
+                        if (!dependencyGavMap.containsKey(gav)) {
+                            for (String[] ignoreSpec : specs) {
+                                if ((ignoreSpec[0].equals(groupId) || ignoreSpec[0].equals("*"))
+                                        && (ignoreSpec[1].equals(artifactId) || ignoreSpec[1].equals("*"))
+                                        && (ignoreSpec[2].equals(version) || ignoreSpec[2].equals("*"))) {
+                                    getLog().info("skipping " + gav + " (shadowed from " + p.getId()
+                                            + "), as it matches " + IGNORE_SHADOWED_DEPENDENCIES.propName());
+                                    continue jarEntryLoop;
+                                }
                             }
+                            getLog().info("adding " + gav + " (shadowed from " + p.getId() + ")");
+                            ArtifactHandler handler = new DefaultArtifactHandler("jar");
+                            String[] gavParts = StringUtils.split(gav, ':');
+                            Artifact manualDep = new DefaultArtifact(gavParts[0], gavParts[1], gavParts[2],
+                                    Artifact.SCOPE_COMPILE, "jar", null, handler);
+                            processArtifact(manualDep, dependencyLicenseMap, dependencyGavMap, true);
                         }
                     }
-                } catch (IOException e) {
-                    throw new MojoExecutionException(e);
                 }
+            } catch (IOException e) {
+                throw new MojoExecutionException(e);
             }
         }
     }
diff --git a/hyracks-fullstack/hyracks/hyracks-maven-plugins/license-automation-plugin/src/main/java/org/apache/hyracks/maven/license/LicenseMojo.java b/hyracks-fullstack/hyracks/hyracks-maven-plugins/license-automation-plugin/src/main/java/org/apache/hyracks/maven/license/LicenseMojo.java
index 73cc69559b..3b5fde693d 100644
--- a/hyracks-fullstack/hyracks/hyracks-maven-plugins/license-automation-plugin/src/main/java/org/apache/hyracks/maven/license/LicenseMojo.java
+++ b/hyracks-fullstack/hyracks/hyracks-maven-plugins/license-automation-plugin/src/main/java/org/apache/hyracks/maven/license/LicenseMojo.java
@@ -407,6 +407,7 @@ public abstract class LicenseMojo extends AbstractMojo {
     protected void gatherProjectDependencies(MavenProject project,
             Map<MavenProject, List<Pair<String, String>>> dependencyLicenseMap,
             Map<String, MavenProject> dependencyGavMap) throws ProjectBuildingException, MojoExecutionException {
+        getLog().debug("+gatherProjectDependencies " + toGav(project));
         final Set<Artifact> dependencyArtifacts = project.getArtifacts();
         if (dependencyArtifacts != null) {
             for (Artifact depArtifact : dependencyArtifacts) {
@@ -440,6 +441,7 @@ public abstract class LicenseMojo extends AbstractMojo {
             Map<String, MavenProject> dependencyGavMap, boolean shadowed) throws ProjectBuildingException {
         if (!excludedScopes.contains(depArtifact.getScope())) {
             MavenProject dep = resolveDependency(depArtifact);
+            getLog().debug("+processArtifact " + toGav(dep));
             if (!depArtifact.isResolved()) {
                 ArtifactResolutionRequest arr = new ArtifactResolutionRequest();
                 arr.setLocalRepository(localRepository);
@@ -476,6 +478,10 @@ public abstract class LicenseMojo extends AbstractMojo {
             } catch (ProjectBuildingException e) {
                 throw new ProjectBuildingException(key, "Error creating dependent artifacts", e);
             }
+            // override the gav in the built dependency with the gavs in depObj
+            depProj.setGroupId(depObj.getGroupId());
+            depProj.setArtifactId(depObj.getArtifactId());
+            depProj.setVersion(depObj.getVersion());
 
             Model supplement = supplementModels
                     .get(SupplementalModelHelper.generateSupplementMapKey(depObj.getGroupId(), depObj.getArtifactId()));
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 d61dde17d3..eb460419e0 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
@@ -20,9 +20,12 @@ package org.apache.hyracks.maven.license;
 
 import static org.apache.hyracks.maven.license.LicenseUtil.toGav;
 
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 import java.util.Properties;
 
+import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.hyracks.util.StringUtil;
@@ -36,13 +39,15 @@ enum ProjectFlag {
     ON_MULTIPLE_EMBEDDED_LICENSE,
     ON_MULTIPLE_EMBEDDED_NOTICE,
     ALTERNATE_LICENSE_FILE,
-    ALTERNATE_NOTICE_FILE;
+    ALTERNATE_NOTICE_FILE,
+    IGNORE_SHADOWED_DEPENDENCIES;
 
     String propName() {
         return "license." + StringUtil.toCamelCase(name());
     }
 
     void visit(MavenProject depObj, Properties properties, LicenseMojo licenseMojo) {
+        licenseMojo.getLog().debug("+" + propName() + ".visit: " + toGav(depObj));
         String value = properties.getProperty(propName());
         if (value == null) {
             return;
@@ -59,12 +64,34 @@ enum ProjectFlag {
                             + " for " + toGav(depObj));
                 }
                 break;
+            case IGNORE_SHADOWED_DEPENDENCIES:
+                // <license.ignoreShadowedDependencies>*:com.couchbase.client:core-io:*</license.ignoreShadowedDependencies>
+                List<String[]> specsList = new ArrayList<>();
+                for (String spec : StringUtils.split(value, ",")) {
+                    boolean found = false;
+                    String[] specSplit = StringUtils.split(spec, ":");
+                    if (specSplit.length != 4) {
+                        throw new IllegalArgumentException(spec);
+                    }
+                    if (specSplit[0].equals(depObj.getVersion()) || specSplit[0].equals("*")) {
+                        specsList.add(ArrayUtils.subarray(specSplit, 1, specSplit.length));
+                        found = true;
+                    }
+                    if (!found) {
+                        licenseMojo.getLog().info(propName() + " defined on versions that *do not* match: "
+                                + specSplit[0] + " for " + toGav(depObj));
+                    }
+                }
+                if (!specsList.isEmpty()) {
+                    licenseMojo.getProjectFlags().put(Pair.of(toGav(depObj), this), specsList);
+                }
+                break;
             case ALTERNATE_LICENSE_FILE:
             case ALTERNATE_NOTICE_FILE:
             case ON_MULTIPLE_EMBEDDED_NOTICE:
             case ON_MULTIPLE_EMBEDDED_LICENSE:
-                boolean found = false;
                 for (String spec : StringUtils.split(value, ",")) {
+                    boolean found = false;
                     String[] specSplit = StringUtils.split(spec, ":");
                     if (specSplit.length != 2) {
                         throw new IllegalArgumentException(spec);
@@ -73,10 +100,10 @@ enum ProjectFlag {
                         licenseMojo.getProjectFlags().put(Pair.of(toGav(depObj), this), specSplit[1]);
                         found = true;
                     }
-                }
-                if (!found) {
-                    licenseMojo.getLog().info(propName() + " defined on versions that *do not* match: " + value
-                            + " for " + toGav(depObj));
+                    if (!found) {
+                        licenseMojo.getLog().info(propName() + " defined on versions that *do not* match: " + value
+                                + " for " + toGav(depObj));
+                    }
                 }
                 break;
             default: