MDEP-76: added exclusion checking
git-svn-id: https://svn.apache.org/repos/asf/maven/plugins/trunk@522140 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/maven/plugin/dependency/AnalyzeDepMgt.java b/src/main/java/org/apache/maven/plugin/dependency/AnalyzeDepMgt.java
index 5ba707d..e8d169e 100644
--- a/src/main/java/org/apache/maven/plugin/dependency/AnalyzeDepMgt.java
+++ b/src/main/java/org/apache/maven/plugin/dependency/AnalyzeDepMgt.java
@@ -19,7 +19,9 @@
* under the License.
*/
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -42,7 +44,9 @@
* to 2.0.6, it was possible to inherit versions that didn't match your
* dependencyManagement. See <a
* href="http://jira.codehaus.org/browse/MNG-1577">MNG-1577</a> for more info.
- * This mojo is also usefull for just detecting projects that override the dependencyManagement directly. Set ignoreDirect to false to detect these otherwise normal conditions.
+ * This mojo is also usefull for just detecting projects that override the
+ * dependencyManagement directly. Set ignoreDirect to false to detect these
+ * otherwise normal conditions.
*
* @author <a href="mailto:brianefox@gmail.com">Brian Fox</a>
* @version $Id: AnalyzeMojo.java 519377 2007-03-17 17:37:26Z brianf $
@@ -78,7 +82,6 @@
*/
private boolean ignoreDirect = true;
-
// Mojo methods -----------------------------------------------------------
/*
@@ -102,16 +105,20 @@
}
}
- // private methods --------------------------------------------------------
-
+ /**
+ * Does the work of checking the DependencyManagement Section.
+ * @return true if errors are found.
+ * @throws MojoExecutionException
+ */
private boolean checkDependencyManagement()
throws MojoExecutionException
{
- boolean foundMismatch = false;
+ boolean foundError = false;
getLog().info( "Found Resolved Dependency / DependencyManagement mismatches:" );
List depMgtDependencies = null;
+
DependencyManagement depMgt = project.getDependencyManagement();
if ( depMgt != null )
{
@@ -121,15 +128,20 @@
if ( depMgtDependencies != null && !depMgtDependencies.isEmpty() )
{
// put all the dependencies from depMgt into a map for quick lookup
- Map map = new HashMap();
+ Map depMgtMap = new HashMap();
+ Map exclusions = new HashMap();
Iterator iter = depMgtDependencies.iterator();
while ( iter.hasNext() )
{
- Dependency dependency = (Dependency) iter.next();
- map.put( dependency.getManagementKey(), dependency );
+ Dependency depMgtDependency = (Dependency) iter.next();
+ depMgtMap.put( depMgtDependency.getManagementKey(), depMgtDependency );
+
+ // now put all the exclusions into a map for quick lookup
+ exclusions.putAll( addExclusions( depMgtDependency.getExclusions() ) );
}
- Set allDependencies = project.getArtifacts();
+ // get dependencies for the project (including transitive)
+ Set allDependencyArtifacts = new HashSet( project.getArtifacts() );
// don't warn if a dependency that is directly listed overrides
// depMgt. That's ok.
@@ -137,25 +149,29 @@
{
getLog().info( "\tIgnoring Direct Dependencies." );
Set directDependencies = project.getDependencyArtifacts();
- allDependencies.removeAll( directDependencies );
+ allDependencyArtifacts.removeAll( directDependencies );
}
- iter = allDependencies.iterator();
- while ( iter.hasNext() )
+ // log exclusion errors
+ List exclusionErrors = getExclusionErrors( exclusions, allDependencyArtifacts );
+ Iterator exclusionIter = exclusionErrors.iterator();
+ while ( exclusionIter.hasNext() )
{
- Artifact dependencyArtifact = (Artifact) iter.next();
- Dependency depFromDepMgt = (Dependency) map.get( getArtifactManagementKey( dependencyArtifact ) );
- if ( depFromDepMgt != null )
- {
- ArtifactVersion artifactVersion = new DefaultArtifactVersion( dependencyArtifact.getVersion() );
+ Artifact exclusion = (Artifact) iter.next();
+ getLog().info(
+ getArtifactManagementKey( exclusion ) + " was excluded in DepMgt, but version "
+ + exclusion.getVersion() + " has been found in the dependency tree." );
+ foundError = true;
+ }
- if ( !dependencyArtifact.isSnapshot() && !depFromDepMgt.getVersion().equals( dependencyArtifact.getVersion() ) )
-
- {
- logMismatch( dependencyArtifact, depFromDepMgt );
- foundMismatch = true;
- }
- }
+ // find and log version mismatches
+ Map mismatch = getMismatch( depMgtMap, allDependencyArtifacts );
+ Iterator mismatchIter = mismatch.keySet().iterator();
+ while ( mismatchIter.hasNext() )
+ {
+ Artifact resolvedArtifact = (Artifact) mismatchIter.next();
+ Dependency depMgtDependency = (Dependency) mismatch.get( resolvedArtifact );
+ logMismatch( resolvedArtifact, depMgtDependency );
}
}
else
@@ -163,20 +179,118 @@
getLog().info( " Nothing in DepMgt." );
}
- if ( !foundMismatch )
+ if ( !foundError )
{
getLog().info( " None" );
}
- return foundMismatch;
+ return foundError;
}
- private void logMismatch( Artifact dependencyArtifact, Dependency dependencyFromDepMgt )
+ /**
+ * Returns a map of the exclusions using the Dependency ManagementKey as the
+ * keyset.
+ *
+ * @param exclusionList
+ * to be added to the map.
+ * @return a map of the exclusions using the Dependency ManagementKey as the
+ * keyset.
+ */
+ public Map addExclusions( List exclusionList )
+ {
+ Map exclusions = new HashMap();
+ if ( exclusionList != null )
+ {
+ Iterator exclusionIter = exclusionList.iterator();
+ while ( exclusionIter.hasNext() )
+ {
+ Dependency exclusion = (Dependency) exclusionIter.next();
+ exclusions.put( exclusion.getManagementKey(), exclusion );
+ }
+ }
+ return exclusions;
+ }
+
+ /**
+ * Returns a List of the artifacts that should have been excluded, but where
+ * found in the dependency tree.
+ *
+ * @param exclusions
+ * a map of the DependencyManagement exclusions, with the
+ * ManagementKey as the key and Dependency as the value.
+ * @param allDependencyArtifacts
+ * resolved artifacts to be compared.
+ * @return list of artifacts that should have been excluded.
+ */
+ public List getExclusionErrors( Map exclusions, Set allDependencyArtifacts )
+ {
+ List list = new ArrayList();
+
+ Iterator iter = allDependencyArtifacts.iterator();
+ while ( iter.hasNext() )
+ {
+ Artifact artifact = (Artifact) iter.next();
+ if ( exclusions.containsKey( getArtifactManagementKey( artifact ) ) )
+ {
+ list.add( artifact );
+ }
+ }
+
+ return list;
+ }
+
+ /**
+ * Calculate the mismatches between the DependencyManagement and resolved
+ * artifacts
+ *
+ * @param depMgtMap
+ * contains the Dependency.GetManagementKey as the keyset for
+ * quick lookup.
+ * @param allDependencyArtifacts
+ * contains the set of all artifacts to compare.
+ * @return a map containing the resolved artifact as the key and the listed
+ * dependency as the value.
+ */
+ public Map getMismatch( Map depMgtMap, Set allDependencyArtifacts )
+ {
+ Map mismatchMap = new HashMap();
+
+ Iterator iter = allDependencyArtifacts.iterator();
+ while ( iter.hasNext() )
+ {
+ Artifact dependencyArtifact = (Artifact) iter.next();
+ Dependency depFromDepMgt = (Dependency) depMgtMap.get( getArtifactManagementKey( dependencyArtifact ) );
+ if ( depFromDepMgt != null )
+ {
+ ArtifactVersion artifactVersion = new DefaultArtifactVersion( dependencyArtifact.getVersion() );
+
+ if ( !dependencyArtifact.isSnapshot()
+ && !depFromDepMgt.getVersion().equals( dependencyArtifact.getVersion() ) )
+ {
+ mismatchMap.put( dependencyArtifact, depFromDepMgt );
+ }
+ }
+ }
+ return mismatchMap;
+ }
+
+ /**
+ * This function displays the log to the screen showing the versions and
+ * information about the artifacts that don't match.
+ *
+ * @param dependencyArtifact
+ * the artifact that was resolved.
+ * @param dependencyFromDepMgt
+ * the dependency listed in the DependencyManagement section.
+ * @throws MojoExecutionException
+ */
+ public void logMismatch( Artifact dependencyArtifact, Dependency dependencyFromDepMgt )
throws MojoExecutionException
{
if ( dependencyArtifact == null || dependencyFromDepMgt == null )
{
- throw new MojoExecutionException( "Invalid params: Artifact:" + dependencyArtifact + " Dependency:" + dependencyFromDepMgt );
+ throw new MojoExecutionException( "Invalid params: Artifact:" + dependencyArtifact + " Dependency:"
+ + dependencyFromDepMgt );
}
getLog().info( "\tDependency: " + dependencyFromDepMgt.getManagementKey() );
@@ -184,10 +298,18 @@
getLog().info( "\t\tResolved: " + dependencyArtifact.getVersion() );
}
- private String getArtifactManagementKey( Artifact artifact )
+ /**
+ * This function returns a string comparable with
+ * Dependency.GetManagementKey.
+ *
+ * @param artifact
+ * to gen the key for
+ * @return a string in the form: groupId:ArtifactId:Type[:Classifier]
+ */
+ public String getArtifactManagementKey( Artifact artifact )
{
return artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" + artifact.getType()
- + ( !StringUtils.isEmpty( artifact.getClassifier() ) ? ":" + artifact.getClassifier() : "" );
+ + (( artifact.getClassifier() !=null ) ? ":" + artifact.getClassifier() : "" );
}
/**
diff --git a/src/site/apt/usage.apt b/src/site/apt/usage.apt
index be832a9..b197488 100644
--- a/src/site/apt/usage.apt
+++ b/src/site/apt/usage.apt
@@ -578,6 +578,8 @@
This mojo is also usefull for just detecting projects that override the dependencyManagement directly. Set ignoreDirect to false to detect these otherwise normal conditions.
+ NOTE: In 2.0-alpha-3, the Labels shown in the output are reversed. This is corrected in 2.0-alpha-4: See MDEP-78.
+
This mojo can be executed from the command line:
+---+
diff --git a/src/test/java/org/apache/maven/plugin/dependency/TestAnalyzeDepMgt.java b/src/test/java/org/apache/maven/plugin/dependency/TestAnalyzeDepMgt.java
new file mode 100644
index 0000000..0aac518
--- /dev/null
+++ b/src/test/java/org/apache/maven/plugin/dependency/TestAnalyzeDepMgt.java
@@ -0,0 +1,186 @@
+package org.apache.maven.plugin.dependency;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.dependency.testUtils.ArtifactStubFactory;
+import org.apache.maven.plugin.dependency.testUtils.stubs.DependencyProjectStub;
+import org.apache.maven.project.MavenProject;
+
+/*
+ * 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.
+ */
+
+
+public class TestAnalyzeDepMgt
+ extends TestCase
+{
+
+ AnalyzeDepMgt mojo;
+ ArtifactStubFactory stubFactory;
+ Dependency exclusion;
+ Artifact exclusionArtifact;
+
+ protected void setUp()
+ throws Exception
+ {
+
+ stubFactory = new ArtifactStubFactory( new File(""), false );
+
+ Set allArtifacts = stubFactory.getMixedArtifacts();
+ Set directArtifacts = stubFactory.getClassifiedArtifacts();
+
+ exclusionArtifact = stubFactory.getReleaseArtifact();
+ exclusion = new Dependency();
+ exclusion.setArtifactId( exclusionArtifact.getArtifactId() );
+ exclusion.setGroupId( exclusionArtifact.getGroupId() );
+ exclusion.setType( exclusionArtifact.getType() );
+ exclusion.setClassifier( "" );
+ exclusion.setVersion( "3.0" );
+
+ mojo = new AnalyzeDepMgt();
+ MavenProject project = new DependencyProjectStub();
+ project.setArtifacts( allArtifacts );
+ project.setDependencyArtifacts( directArtifacts );
+
+ mojo.setProject( project );
+
+ }
+
+ public void testGetManagementKey() throws IOException
+ {
+ Dependency dep = new Dependency();
+ dep.setArtifactId( "artifact" );
+ dep.setClassifier( "class" );
+ dep.setGroupId( "group" );
+ dep.setType( "type" );
+
+ //version isn't used in the key, it can be different
+ dep.setVersion( "1.1" );
+
+ Artifact artifact = stubFactory.createArtifact( "group", "artifact", "1.0",Artifact.SCOPE_COMPILE,"type","class" );
+
+ //basic case ok
+ assertEquals( dep.getManagementKey(), mojo.getArtifactManagementKey( artifact ) );
+
+ //now change each one and make sure it fails, then set it back and make sure it's ok before
+ //testing the next one
+ dep.setType( "t" );
+ assertFalse ( dep.getManagementKey().equals(mojo.getArtifactManagementKey( artifact ) ));
+
+ dep.setType( "type" );
+ assertEquals( dep.getManagementKey(), mojo.getArtifactManagementKey( artifact ) );
+
+ dep.setArtifactId( "a" );
+ assertFalse ( dep.getManagementKey().equals(mojo.getArtifactManagementKey( artifact ) ));
+
+ dep.setArtifactId( "artifact" );
+ assertEquals( dep.getManagementKey(), mojo.getArtifactManagementKey( artifact ) );
+
+ dep.setClassifier( "c" );
+ assertFalse ( dep.getManagementKey().equals(mojo.getArtifactManagementKey( artifact ) ));
+
+ dep.setClassifier( "class" );
+ assertEquals( dep.getManagementKey(), mojo.getArtifactManagementKey( artifact ) );
+
+ dep.setGroupId( "g" );
+ assertFalse ( dep.getManagementKey().equals(mojo.getArtifactManagementKey( artifact ) ));
+
+ dep.setGroupId( "group" );
+ dep.setClassifier( null );
+ artifact = stubFactory.createArtifact( "group", "artifact", "1.0",Artifact.SCOPE_COMPILE,"type",null );
+ assertEquals( dep.getManagementKey(), mojo.getArtifactManagementKey( artifact ) );
+
+ dep.setClassifier( "" );
+ artifact = stubFactory.createArtifact( "group", "artifact", "1.0",Artifact.SCOPE_COMPILE,"type","" );
+ assertEquals( dep.getManagementKey(), mojo.getArtifactManagementKey( artifact ) );
+ }
+
+ public void testAddExclusions()
+ {
+ Dependency dep = new Dependency();
+ dep.setArtifactId( "artifact" );
+ dep.setClassifier( "class" );
+ dep.setGroupId( "group" );
+ dep.setType( "type" );
+
+ assertEquals( 0, mojo.addExclusions( null ).size() );
+
+ ArrayList list = new ArrayList();
+ assertEquals( 0, mojo.addExclusions( null ).size() );
+
+ list.add( dep );
+ Map map = mojo.addExclusions( list );
+
+ assertTrue(map.containsKey( dep.getManagementKey() ));
+ assertSame( dep, map.get( dep.getManagementKey() ) );
+ }
+
+ public void testGetExclusionErrors()
+ {
+ ArrayList list = new ArrayList();
+ list.add( exclusion );
+
+ //already tested this method so I can trust it.
+ Map map = mojo.addExclusions( list );
+
+ List l = mojo.getExclusionErrors( map, mojo.getProject().getArtifacts() );
+
+ assertEquals( 1, l.size() );
+
+ assertEquals( exclusion.getManagementKey(), mojo.getArtifactManagementKey( (Artifact) l.get( 0 ) ));
+ }
+
+ public void testGetMismatch() throws IOException
+ {
+ Map depMgtMap = new HashMap();
+
+ depMgtMap.put( exclusion.getManagementKey(), exclusion );
+
+ Map results = mojo.getMismatch( depMgtMap, mojo.getProject().getArtifacts() );
+
+ assertEquals( 1, results.size() );
+ //the release artifact is used to create the exclusion
+ assertTrue( results.containsKey( stubFactory.getReleaseArtifact()));
+ assertSame( exclusion,results.get( stubFactory.getReleaseArtifact()));
+ }
+
+ public void testMojo()
+ {
+ try
+ {
+ mojo.execute();
+ }
+ catch ( Exception e )
+ {
+ fail("Caught Unexpected Exception:"+e.getLocalizedMessage());
+ }
+ }
+}