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

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


The following commit(s) were added to refs/heads/master by this push:
     new 6fa66043 [MDEP-776] Warn when multiple dependencies have the same file 
name (#463)
6fa66043 is described below

commit 6fa66043341b83a4e2ae49366c7edc2279c5a044
Author: Elliotte Rusty Harold <elh...@users.noreply.github.com>
AuthorDate: Fri Dec 6 13:34:42 2024 +0000

    [MDEP-776] Warn when multiple dependencies have the same file name (#463)
    
    * Warn when overwriting file
---
 .../invoker.properties                             | 18 +++++
 .../copy-dependencies-with-conflict/pom.xml        | 77 ++++++++++++++++++++++
 .../copy-dependencies-with-conflict/verify.groovy  | 31 +++++++++
 .../dependency/fromConfiguration/ArtifactItem.java | 12 ++--
 .../dependency/fromConfiguration/CopyMojo.java     | 11 ++--
 .../fromDependencies/CopyDependenciesMojo.java     | 48 +++++++++-----
 .../maven/plugins/dependency/utils/CopyUtil.java   |  6 +-
 7 files changed, 174 insertions(+), 29 deletions(-)

diff --git a/src/it/projects/copy-dependencies-with-conflict/invoker.properties 
b/src/it/projects/copy-dependencies-with-conflict/invoker.properties
new file mode 100644
index 00000000..f50e476f
--- /dev/null
+++ b/src/it/projects/copy-dependencies-with-conflict/invoker.properties
@@ -0,0 +1,18 @@
+# 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.
+
+invoker.goals = clean process-sources
diff --git a/src/it/projects/copy-dependencies-with-conflict/pom.xml 
b/src/it/projects/copy-dependencies-with-conflict/pom.xml
new file mode 100644
index 00000000..b7c6cf62
--- /dev/null
+++ b/src/it/projects/copy-dependencies-with-conflict/pom.xml
@@ -0,0 +1,77 @@
+<?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 xmlns="http://maven.apache.org/POM/4.0.0";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.apache.maven.its.dependency</groupId>
+  <artifactId>test</artifactId>
+  <version>1.0-SNAPSHOT</version>
+
+  <name>Test with conflicts</name>
+  <description>
+    Test dependency:copy-dependencies with conflicting artifact IDs
+  </description>
+
+  
+  <dependencies>
+  <!-- need two deps that have same version and artifact ID but different 
group ID -->
+    <dependency>
+      <groupId>org.jdom</groupId>
+      <artifactId>jdom</artifactId>
+      <version>1.1.3</version>
+    </dependency>
+    <dependency>
+      <groupId>org.lucee</groupId>
+      <artifactId>jdom</artifactId>
+      <version>1.1.3</version>
+    </dependency>
+  </dependencies>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <build>
+
+    <defaultGoal>package</defaultGoal>
+
+    <plugins>
+      <plugin>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <version>@project.version@</version>
+        <executions>
+          <execution>
+            <id>test-2</id>
+            <goals>
+              <goal>copy-dependencies</goal>
+            </goals>
+            <configuration>
+              <copyPom>true</copyPom>
+              
<outputDirectory>${project.build.directory}/it/copy-dep-test-2</outputDirectory>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/src/it/projects/copy-dependencies-with-conflict/verify.groovy 
b/src/it/projects/copy-dependencies-with-conflict/verify.groovy
new file mode 100644
index 00000000..b66deb08
--- /dev/null
+++ b/src/it/projects/copy-dependencies-with-conflict/verify.groovy
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+File file = new File( basedir, "build.log" )
+assert file.exists()
+
+String buildLog = file.getText( "UTF-8" )
+assert buildLog.contains( '[WARNING] Overwriting ' )
+assert buildLog.contains( '[DEBUG] Copying artifact 
\'org.jdom:jdom:jar:1.1.3\'' )
+assert buildLog.contains( '[DEBUG] Copying artifact 
\'org.jdom:jdom:pom:1.1.3\'' )
+assert buildLog.contains( '[DEBUG] Copying artifact 
\'org.jdom:jdom:jar:1.1.3\'' )
+assert buildLog.contains( '[DEBUG] Copying artifact 
\'org.lucee:jdom:jar:1.1.3\'' )
+assert buildLog.contains( '[WARNING] Multiple files with the name 
jdom-1.1.3.jar in the dependency tree.' )
+
+return true
diff --git 
a/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/ArtifactItem.java
 
b/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/ArtifactItem.java
index ff9e5b39..b98b4567 100644
--- 
a/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/ArtifactItem.java
+++ 
b/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/ArtifactItem.java
@@ -36,8 +36,7 @@ import 
org.codehaus.plexus.components.io.filemappers.FileMapper;
  */
 public class ArtifactItem implements DependableCoordinate {
     /**
-     * Group Id of Artifact
-     *
+     * Group ID of Artifact
      */
     @Parameter(required = true)
     private String groupId;
@@ -56,7 +55,6 @@ public class ArtifactItem implements DependableCoordinate {
 
     /**
      * Type of Artifact (War,Jar,etc)
-     *
      */
     @Parameter(required = true)
     private String type = "jar";
@@ -90,9 +88,6 @@ public class ArtifactItem implements DependableCoordinate {
     @Parameter
     private String encoding;
 
-    /**
-     *
-     */
     private boolean needsProcessing;
 
     /**
@@ -147,6 +142,7 @@ public class ArtifactItem implements DependableCoordinate {
     /**
      * @return Returns the artifactId.
      */
+    @Override
     public String getArtifactId() {
         return artifactId;
     }
@@ -161,6 +157,7 @@ public class ArtifactItem implements DependableCoordinate {
     /**
      * @return Returns the groupId.
      */
+    @Override
     public String getGroupId() {
         return groupId;
     }
@@ -175,6 +172,7 @@ public class ArtifactItem implements DependableCoordinate {
     /**
      * @return Returns the type.
      */
+    @Override
     public String getType() {
         return type;
     }
@@ -189,6 +187,7 @@ public class ArtifactItem implements DependableCoordinate {
     /**
      * @return Returns the version.
      */
+    @Override
     public String getVersion() {
         return version;
     }
@@ -210,6 +209,7 @@ public class ArtifactItem implements DependableCoordinate {
     /**
      * @return Classifier.
      */
+    @Override
     public String getClassifier() {
         return classifier;
     }
diff --git 
a/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/CopyMojo.java
 
b/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/CopyMojo.java
index a9b9ba88..e9ad6d73 100644
--- 
a/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/CopyMojo.java
+++ 
b/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/CopyMojo.java
@@ -101,11 +101,12 @@ public class CopyMojo extends 
AbstractFromConfigurationMojo {
 
         List<ArtifactItem> theArtifactItems = getProcessedArtifactItems(
                 new ProcessArtifactItemsRequest(stripVersion, prependGroupId, 
useBaseVersion, stripClassifier));
+
         for (ArtifactItem artifactItem : theArtifactItems) {
             if (artifactItem.isNeedsProcessing()) {
                 copyArtifact(artifactItem);
             } else {
-                this.getLog().info(artifactItem + " already exists in " + 
artifactItem.getOutputDirectory());
+                getLog().info(artifactItem + " already exists in " + 
artifactItem.getOutputDirectory());
             }
         }
     }
@@ -113,13 +114,15 @@ public class CopyMojo extends 
AbstractFromConfigurationMojo {
     /**
      * Resolves the artifact from the repository and copies it to the 
specified location.
      *
-     * @param artifactItem containing the information about the Artifact to 
copy.
-     * @throws MojoExecutionException with a message if an error occurs.
+     * @param artifactItem containing the information about the artifact to 
copy
+     * @throws MojoExecutionException with a message if an error occurs
      * @see CopyUtil#copyArtifactFile(Artifact, File)
      */
     protected void copyArtifact(ArtifactItem artifactItem) throws 
MojoExecutionException {
         File destFile = new File(artifactItem.getOutputDirectory(), 
artifactItem.getDestFileName());
-
+        if (destFile.exists()) {
+            getLog().warn("Overwriting " + destFile);
+        }
         try {
             copyUtil.copyArtifactFile(artifactItem.getArtifact(), destFile);
         } catch (IOException e) {
diff --git 
a/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/CopyDependenciesMojo.java
 
b/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/CopyDependenciesMojo.java
index 01e15040..f8b18023 100644
--- 
a/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/CopyDependenciesMojo.java
+++ 
b/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/CopyDependenciesMojo.java
@@ -23,6 +23,8 @@ import javax.inject.Inject;
 import java.io.File;
 import java.io.IOException;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.maven.RepositoryUtils;
@@ -44,7 +46,10 @@ import 
org.eclipse.aether.resolution.ArtifactResolutionException;
 import org.eclipse.aether.util.artifact.SubArtifact;
 
 /**
- * Goal that copies the project dependencies from the repository to a defined 
location.
+ * Goal that copies the files for a project's dependencies from the repository 
to a directory.
+ * The default location to copy to is target/dependencies.
+ * Since all files are copied to the same directory by default, a dependency 
that
+ * has the same file name as another dependency will be overwritten.
  *
  * @author <a href="mailto:bri...@apache.org";>Brian Fox</a>
  * @since 1.0
@@ -95,7 +100,7 @@ public class CopyDependenciesMojo extends 
AbstractFromDependenciesMojo {
     /**
      * Main entry into mojo. Gets the list of dependencies and iterates 
through calling copyArtifact.
      *
-     * @throws MojoExecutionException with a message if an error occurs.
+     * @throws MojoExecutionException with a message if an error occurs
      * @see #getDependencySets(boolean, boolean)
      * @see #copyArtifact(Artifact, boolean, boolean, boolean, boolean)
      */
@@ -105,6 +110,21 @@ public class CopyDependenciesMojo extends 
AbstractFromDependenciesMojo {
         Set<Artifact> artifacts = dss.getResolvedDependencies();
 
         if (!useRepositoryLayout) {
+            Map<String, Integer> copies = new HashMap<>();
+            for (Artifact artifactItem : artifacts) {
+                String destFileName = DependencyUtil.getFormattedFileName(
+                        artifactItem, stripVersion, prependGroupId, 
useBaseVersion, stripClassifier);
+                int numCopies = copies.getOrDefault(destFileName, 0);
+                copies.put(destFileName, numCopies + 1);
+            }
+            for (Map.Entry<String, Integer> entry : copies.entrySet()) {
+                if (entry.getValue() > 1) {
+                    getLog().warn("Multiple files with the name " + 
entry.getKey() + " in the dependency tree.");
+                    getLog().warn(
+                                    "Not all JARs will be available. Consider 
using prependGroupId, useSubDirectoryPerArtifact, or useRepositoryLayout.");
+                }
+            }
+
             for (Artifact artifact : artifacts) {
                 copyArtifact(
                         artifact, isStripVersion(), this.prependGroupId, 
this.useBaseVersion, this.stripClassifier);
@@ -123,19 +143,13 @@ public class CopyDependenciesMojo extends 
AbstractFromDependenciesMojo {
 
         if (isCopyPom() && !useRepositoryLayout) {
             copyPoms(getOutputDirectory(), artifacts, this.stripVersion);
-            copyPoms(getOutputDirectory(), skippedArtifacts, 
this.stripVersion, this.stripClassifier); // Artifacts
-            // that already
-            // exist may
-            // not yet have
-            // poms
+            copyPoms(getOutputDirectory(), skippedArtifacts, 
this.stripVersion, this.stripClassifier);
+            // Artifacts that already exist may not yet have poms
         }
     }
 
     /**
-     * install the artifact and the corresponding pom if copyPoms=true
-     *
-     * @param artifact
-     * @param buildingRequest
+     * Install the artifact and the corresponding pom if copyPoms=true.
      */
     private void installArtifact(Artifact artifact, ProjectBuildingRequest 
buildingRequest) {
         try {
@@ -193,7 +207,7 @@ public class CopyDependenciesMojo extends 
AbstractFromDependenciesMojo {
      * @param artifact representing the object to be copied.
      * @param removeVersion specifies if the version should be removed from 
the file name when copying.
      * @param prependGroupId specifies if the groupId should be prepend to the 
file while copying.
-     * @param theUseBaseVersion specifies if the baseVersion of the artifact 
should be used instead of the version.
+     * @param useBaseVersion specifies if the baseVersion of the artifact 
should be used instead of the version.
      * @param removeClassifier specifies if the classifier should be removed 
from the file name when copying.
      * @throws MojoExecutionException with a message if an error occurs.
      * @see CopyUtil#copyArtifactFile(Artifact, File)
@@ -203,12 +217,12 @@ public class CopyDependenciesMojo extends 
AbstractFromDependenciesMojo {
             Artifact artifact,
             boolean removeVersion,
             boolean prependGroupId,
-            boolean theUseBaseVersion,
+            boolean useBaseVersion,
             boolean removeClassifier)
             throws MojoExecutionException {
 
         String destFileName = DependencyUtil.getFormattedFileName(
-                artifact, removeVersion, prependGroupId, theUseBaseVersion, 
removeClassifier);
+                artifact, removeVersion, prependGroupId, useBaseVersion, 
removeClassifier);
 
         File destDir = DependencyUtil.getFormattedOutputDirectory(
                 useSubDirectoryPerScope,
@@ -220,7 +234,9 @@ public class CopyDependenciesMojo extends 
AbstractFromDependenciesMojo {
                 outputDirectory,
                 artifact);
         File destFile = new File(destDir, destFileName);
-
+        if (destFile.exists()) {
+            getLog().warn("Overwriting " + destFile);
+        }
         try {
             copyUtil.copyArtifactFile(artifact, destFile);
         } catch (IOException e) {
@@ -323,7 +339,7 @@ public class CopyDependenciesMojo extends 
AbstractFromDependenciesMojo {
     }
 
     /**
-     * @param copyPom - true if the pom of each artifact must be copied
+     * @param copyPom true if the pom of each artifact must be copied
      */
     public void setCopyPom(boolean copyPom) {
         this.copyPom = copyPom;
diff --git 
a/src/main/java/org/apache/maven/plugins/dependency/utils/CopyUtil.java 
b/src/main/java/org/apache/maven/plugins/dependency/utils/CopyUtil.java
index b175fb70..f83bb15c 100644
--- a/src/main/java/org/apache/maven/plugins/dependency/utils/CopyUtil.java
+++ b/src/main/java/org/apache/maven/plugins/dependency/utils/CopyUtil.java
@@ -51,9 +51,9 @@ public class CopyUtil {
     }
 
     /**
-     * Copies the artifact (file).
+     * Copies the artifact (file)
      *
-     * @param sourceArtifact represents the artifact (file) to copy
+     * @param sourceArtifact the artifact (file) to copy
      * @param destination file name of destination file
      * @throws IOException if copy has failed
      * @throws MojoExecutionException if artifact file is a directory (which 
has not been packaged yet)
@@ -68,7 +68,7 @@ public class CopyUtil {
                     + "' has not been packaged yet (is a directory). When used 
on reactor artifact, "
                     + "copy should be executed after packaging: see 
MDEP-187.");
         }
-        logger.debug("Copying artifact '{}' ({}) to {}", sourceArtifact, 
sourceArtifact.getFile(), destination);
+        logger.debug("Copying artifact '{}' ({}) to {}", 
sourceArtifact.getId(), sourceArtifact.getFile(), destination);
         FileUtils.copyFile(source, destination);
         buildContext.refresh(destination);
     }

Reply via email to