Author: brianf Date: Sat Mar 24 18:40:11 2007 New Revision: 522140 URL: http://svn.apache.org/viewvc?view=rev&rev=522140 Log: MDEP-76: added exclusion checking
Added: maven/plugins/trunk/maven-dependency-plugin/src/test/java/org/apache/maven/plugin/dependency/TestAnalyzeDepMgt.java Modified: maven/plugins/trunk/maven-dependency-plugin/src/main/java/org/apache/maven/plugin/dependency/AnalyzeDepMgt.java maven/plugins/trunk/maven-dependency-plugin/src/site/apt/usage.apt Modified: maven/plugins/trunk/maven-dependency-plugin/src/main/java/org/apache/maven/plugin/dependency/AnalyzeDepMgt.java URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-dependency-plugin/src/main/java/org/apache/maven/plugin/dependency/AnalyzeDepMgt.java?view=diff&rev=522140&r1=522139&r2=522140 ============================================================================== --- maven/plugins/trunk/maven-dependency-plugin/src/main/java/org/apache/maven/plugin/dependency/AnalyzeDepMgt.java (original) +++ maven/plugins/trunk/maven-dependency-plugin/src/main/java/org/apache/maven/plugin/dependency/AnalyzeDepMgt.java Sat Mar 24 18:40:11 2007 @@ -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:[EMAIL PROTECTED]">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() ); - - if ( !dependencyArtifact.isSnapshot() && !depFromDepMgt.getVersion().equals( 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; + } - { - 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; + } + + /** + * 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; } - private void logMismatch( Artifact dependencyArtifact, Dependency dependencyFromDepMgt ) + /** + * 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() : "" ); } /** Modified: maven/plugins/trunk/maven-dependency-plugin/src/site/apt/usage.apt URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-dependency-plugin/src/site/apt/usage.apt?view=diff&rev=522140&r1=522139&r2=522140 ============================================================================== --- maven/plugins/trunk/maven-dependency-plugin/src/site/apt/usage.apt (original) +++ maven/plugins/trunk/maven-dependency-plugin/src/site/apt/usage.apt Sat Mar 24 18:40:11 2007 @@ -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: +---+ Added: maven/plugins/trunk/maven-dependency-plugin/src/test/java/org/apache/maven/plugin/dependency/TestAnalyzeDepMgt.java URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-dependency-plugin/src/test/java/org/apache/maven/plugin/dependency/TestAnalyzeDepMgt.java?view=auto&rev=522140 ============================================================================== --- maven/plugins/trunk/maven-dependency-plugin/src/test/java/org/apache/maven/plugin/dependency/TestAnalyzeDepMgt.java (added) +++ maven/plugins/trunk/maven-dependency-plugin/src/test/java/org/apache/maven/plugin/dependency/TestAnalyzeDepMgt.java Sat Mar 24 18:40:11 2007 @@ -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()); + } + } +}