You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by br...@apache.org on 2007/07/06 04:02:12 UTC

svn commit: r553696 - in /maven/plugins/trunk/maven-enforcer-plugin: ./ src/main/java/org/apache/maven/plugin/enforcer/ src/main/java/org/apache/maven/plugin/enforcer/util/ src/test/java/org/apache/maven/plugin/enforcer/

Author: brianf
Date: Thu Jul  5 19:02:11 2007
New Revision: 553696

URL: http://svn.apache.org/viewvc?view=rev&rev=553696
Log:
MENFORCER-8 - new rule for banning certain dependencies

Added:
    maven/plugins/trunk/maven-enforcer-plugin/src/main/java/org/apache/maven/plugin/enforcer/BannedDependencies.java
    maven/plugins/trunk/maven-enforcer-plugin/src/main/java/org/apache/maven/plugin/enforcer/util/
    maven/plugins/trunk/maven-enforcer-plugin/src/main/java/org/apache/maven/plugin/enforcer/util/EnforcerUtils.java
    maven/plugins/trunk/maven-enforcer-plugin/src/test/java/org/apache/maven/plugin/enforcer/TestBannedDependencies.java
Modified:
    maven/plugins/trunk/maven-enforcer-plugin/pom.xml

Modified: maven/plugins/trunk/maven-enforcer-plugin/pom.xml
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-enforcer-plugin/pom.xml?view=diff&rev=553696&r1=553695&r2=553696
==============================================================================
--- maven/plugins/trunk/maven-enforcer-plugin/pom.xml (original)
+++ maven/plugins/trunk/maven-enforcer-plugin/pom.xml Thu Jul  5 19:02:11 2007
@@ -121,5 +121,11 @@
             <artifactId>bsh</artifactId>
 			<version>2.0b4</version>
         </dependency>
+		<dependency>
+			<groupId>org.apache.maven.shared</groupId>
+			<artifactId>maven-plugin-testing-harness</artifactId>
+			<scope>test</scope>
+			<version>1.1-SNAPSHOT</version>
+		</dependency>
 	</dependencies>
 </project>

Added: maven/plugins/trunk/maven-enforcer-plugin/src/main/java/org/apache/maven/plugin/enforcer/BannedDependencies.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-enforcer-plugin/src/main/java/org/apache/maven/plugin/enforcer/BannedDependencies.java?view=auto&rev=553696
==============================================================================
--- maven/plugins/trunk/maven-enforcer-plugin/src/main/java/org/apache/maven/plugin/enforcer/BannedDependencies.java (added)
+++ maven/plugins/trunk/maven-enforcer-plugin/src/main/java/org/apache/maven/plugin/enforcer/BannedDependencies.java Thu Jul  5 19:02:11 2007
@@ -0,0 +1,261 @@
+package org.apache.maven.plugin.enforcer;
+
+/*
+ * 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.
+ */
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.plugin.enforcer.util.EnforcerUtils;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.shared.enforcer.rule.api.EnforcerRule;
+import org.apache.maven.shared.enforcer.rule.api.EnforcerRuleException;
+import org.apache.maven.shared.enforcer.rule.api.EnforcerRuleHelper;
+import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * This rule checks that lists of dependencies are not
+ * included.
+ * 
+ * @author <a href="mailto:brianf@apache.org">Brian Fox</a>
+ * @version $Id$
+ * 
+ */
+public class BannedDependencies
+    implements EnforcerRule
+{
+
+    /**
+     * Specify the banned dependencies. This can be a list
+     * of artifacts in the format
+     * groupId[:artifactId][:version]
+     * Any of the sections can be a wildcard by using '*' (ie group:*:1.0)
+     * 
+     * @parameter
+     * @required
+     */
+    public ArrayList excludes = null;
+
+    /**
+     * Specify if transitive dependencies should be searched
+     * (default) or only look at direct dependencies
+     * 
+     * @parameter
+     */
+    public boolean searchTransitive = true;
+
+    /**
+     * Specify a friendly message if the rule fails.
+     * 
+     * @parameter
+     */
+    public String message = null;
+
+    /**
+     * Execute the rule.
+     */
+    public void execute( EnforcerRuleHelper helper )
+        throws EnforcerRuleException
+    {
+
+        // get the project
+        MavenProject project = null;
+        try
+        {
+            project = (MavenProject) helper.evaluate( "${project}" );
+        }
+        catch ( ExpressionEvaluationException eee )
+        {
+            throw new EnforcerRuleException( "Unable to retrieve the MavenProject: ", eee );
+        }
+
+        // get the correct list of dependencies
+        Set dependencies = null;
+        if ( searchTransitive )
+        {
+            dependencies = project.getArtifacts();
+        }
+        else
+        {
+            dependencies = project.getDependencyArtifacts();
+        }
+
+        // look for banned dependencies
+        Set foundExcludes = checkDependencies( dependencies, excludes );
+
+        // if any are found, fail the check but list all of
+        // them
+        if ( !foundExcludes.isEmpty() )
+        {
+            if ( message == null )
+            {
+                StringBuffer buf = new StringBuffer();
+                Iterator iter = foundExcludes.iterator();
+                while ( iter.hasNext() )
+                {
+                    buf.append( "Found Banned Dependency: " + ( (Artifact) iter.next() ).getId() + "\n" );
+                }
+                message = buf.toString();
+            }
+            throw new EnforcerRuleException( message );
+        }
+
+    }
+
+    /**
+     * Checks the set of dependencies against the list of
+     * excludes
+     * 
+     * @param dependencies
+     * @return
+     * @throws EnforcerRuleException
+     */
+    protected Set checkDependencies( Set dependencies, List theExcludes )
+        throws EnforcerRuleException
+    {
+        Set foundExcludes = new HashSet();
+
+        Iterator iter = theExcludes.iterator();
+        while ( iter.hasNext() )
+        {
+            String exclude = (String) iter.next();
+
+            String[] subStrings = exclude.split( ":" );
+            subStrings = StringUtils.stripAll(subStrings);
+            
+            Iterator DependencyIter = dependencies.iterator();
+            while ( DependencyIter.hasNext() )
+            {
+                Artifact artifact = (Artifact) DependencyIter.next();
+
+                if ( compareDependency( subStrings, artifact ) )
+                {
+                    foundExcludes.add( artifact );
+                }
+            }
+        }
+        return foundExcludes;
+    }
+
+    /**
+     * Compares the parsed array of substrings against the
+     * artifact
+     * 
+     * @param exclude
+     * @param artifact
+     * @return
+     * @throws EnforcerRuleException
+     */
+    protected boolean compareDependency( String[] exclude, Artifact artifact )
+        throws EnforcerRuleException
+    {
+
+        boolean result = false;
+        if ( exclude.length > 0 )
+        {
+            result = exclude[0].equals( "*" ) || artifact.getGroupId().equals( exclude[0] );
+        }
+
+        if ( result && exclude.length > 1 )
+        {
+            result = exclude[1].equals( "*" ) || artifact.getArtifactId().equals( exclude[1] );
+        }
+
+        if ( result && exclude.length > 2 )
+        {
+            // short circuit if the versions are exactly the
+            // same
+            if ( exclude[2].equals( "*" ) || artifact.getVersion().equals( exclude[2] ) )
+            {
+                result = true;
+            }
+            else
+            {
+                try
+                {
+                    result = EnforcerUtils.containsVersion( VersionRange.createFromVersionSpec( exclude[2] ),
+                                                            new DefaultArtifactVersion( artifact.getVersion() ) );
+                }
+                catch ( InvalidVersionSpecificationException e )
+                {
+                    throw new EnforcerRuleException( "Invalid Version Range: ", e );
+                }
+            }
+        }
+
+        return result;
+
+    }
+
+    /**
+     * @return the excludes
+     */
+    public ArrayList getExcludes()
+    {
+        return this.excludes;
+    }
+
+    /**
+     * @param theExcludes the excludes to set
+     */
+    public void setExcludes( ArrayList theExcludes )
+    {
+        this.excludes = theExcludes;
+    }
+
+    /**
+     * @return the message
+     */
+    public String getMessage()
+    {
+        return this.message;
+    }
+
+    /**
+     * @param theMessage the message to set
+     */
+    public void setMessage( String theMessage )
+    {
+        this.message = theMessage;
+    }
+
+    /**
+     * @return the searchTransitive
+     */
+    public boolean isSearchTransitive()
+    {
+        return this.searchTransitive;
+    }
+
+    /**
+     * @param theSearchTransitive the searchTransitive to set
+     */
+    public void setSearchTransitive( boolean theSearchTransitive )
+    {
+        this.searchTransitive = theSearchTransitive;
+    }
+}

Added: maven/plugins/trunk/maven-enforcer-plugin/src/main/java/org/apache/maven/plugin/enforcer/util/EnforcerUtils.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-enforcer-plugin/src/main/java/org/apache/maven/plugin/enforcer/util/EnforcerUtils.java?view=auto&rev=553696
==============================================================================
--- maven/plugins/trunk/maven-enforcer-plugin/src/main/java/org/apache/maven/plugin/enforcer/util/EnforcerUtils.java (added)
+++ maven/plugins/trunk/maven-enforcer-plugin/src/main/java/org/apache/maven/plugin/enforcer/util/EnforcerUtils.java Thu Jul  5 19:02:11 2007
@@ -0,0 +1,39 @@
+package org.apache.maven.plugin.enforcer.util;
+
+import java.util.Iterator;
+
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.artifact.versioning.Restriction;
+import org.apache.maven.artifact.versioning.VersionRange;
+
+/**
+ * @author <a href="mailto:brianf@apache.org">Brian Fox</a>
+ *
+ */
+public class EnforcerUtils
+{
+    public static synchronized boolean containsVersion( VersionRange allowedRange, ArtifactVersion theVersion )
+    {
+        boolean matched = false;
+        ArtifactVersion recommendedVersion = allowedRange.getRecommendedVersion();
+        if ( recommendedVersion == null )
+        {
+
+            for ( Iterator i = allowedRange.getRestrictions().iterator(); i.hasNext() && !matched; )
+            {
+                Restriction restriction = (Restriction) i.next();
+                if ( restriction.containsVersion( theVersion ) )
+                {
+                    matched = true;
+                }
+            }
+        }
+        else
+        {
+            // only singular versions ever have a recommendedVersion
+            int compareTo = recommendedVersion.compareTo( theVersion );
+            matched = ( compareTo <= 0 );
+        }
+        return matched;
+    }
+}

Added: maven/plugins/trunk/maven-enforcer-plugin/src/test/java/org/apache/maven/plugin/enforcer/TestBannedDependencies.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-enforcer-plugin/src/test/java/org/apache/maven/plugin/enforcer/TestBannedDependencies.java?view=auto&rev=553696
==============================================================================
--- maven/plugins/trunk/maven-enforcer-plugin/src/test/java/org/apache/maven/plugin/enforcer/TestBannedDependencies.java (added)
+++ maven/plugins/trunk/maven-enforcer-plugin/src/test/java/org/apache/maven/plugin/enforcer/TestBannedDependencies.java Thu Jul  5 19:02:11 2007
@@ -0,0 +1,155 @@
+package org.apache.maven.plugin.enforcer;
+
+/*
+ * 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.
+ */
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+import junit.framework.TestCase;
+
+import org.apache.maven.plugin.testing.ArtifactStubFactory;
+import org.apache.maven.shared.enforcer.rule.api.EnforcerRule;
+import org.apache.maven.shared.enforcer.rule.api.EnforcerRuleException;
+import org.apache.maven.shared.enforcer.rule.api.EnforcerRuleHelper;
+
+/**
+ * 
+ * @author <a href="mailto:brianf@apache.org">Brian Fox</a>
+ * 
+ */
+public class TestBannedDependencies
+    extends TestCase
+{
+
+    public void testRule()
+        throws IOException
+    {
+        ArtifactStubFactory factory = new ArtifactStubFactory( null, false );
+        MockProject project = new MockProject();
+        EnforcerRuleHelper helper = EnforcerTestUtils.getHelper( project );
+        project.setArtifacts( factory.getMixedArtifacts() );
+        project.setDependencyArtifacts( factory.getScopedArtifacts() );
+        BannedDependencies rule = new BannedDependencies();
+
+        ArrayList excludes = new ArrayList();
+        rule.setSearchTransitive( false );
+
+        // test whole name
+        excludes.add( "testGroupId:release:1.0" );
+        rule.setExcludes( excludes );
+
+        execute( rule, helper, false );
+
+        // test group:artifact
+        excludes.clear();
+        excludes.add( "testGroupId:release" );
+        execute( rule, helper, false );
+
+        // test group
+        excludes.clear();
+        excludes.add( "testGroupId" );
+        execute( rule, helper, false );
+
+        // now check one that should be found in direct
+        // dependencies
+        excludes.clear();
+        excludes.add( "g:compile:1.0" );
+        execute( rule, helper, true );
+        rule.setSearchTransitive( true );
+
+        // whole name
+        excludes.clear();
+        excludes.add( "testGroupId:release:1.0" );
+        execute( rule, helper, true );
+
+        // group:artifact
+        excludes.clear();
+        excludes.add( "testGroupId:release" );
+        execute( rule, helper, true );
+
+        // group
+        excludes.clear();
+        excludes.add( "testGroupId" );
+        execute( rule, helper, true );
+
+        // now check wildcards
+        excludes.clear();
+        excludes.add( "*:release" );
+        execute( rule, helper, true );
+
+        // now check wildcards
+        excludes.clear();
+        excludes.add( "*:*:1.0" );
+        execute( rule, helper, true );
+
+        // now check wildcards
+        excludes.clear();
+        excludes.add( "*:release:*" );
+        execute( rule, helper, true );
+
+        // now check wildcards
+        excludes.clear();
+        excludes.add( "*:release:1.2" );
+        execute( rule, helper, false );
+        
+        //now check multiple excludes
+        excludes.add( "*:release:*");
+        execute( rule, helper, true );
+        
+        //now check space trimming
+        excludes.clear();
+        excludes.add( "  testGroupId  :  release   :   1.0    " );
+        execute( rule, helper, true );
+        
+        //now check weirdness
+        excludes.clear();
+        excludes.add( ":::" ); //null entry, won't match anything
+        execute( rule, helper, false );
+    }
+
+    /**
+     * Simpler wrapper to execute and deal with the expected
+     * result.
+     * 
+     * @param rule
+     * @param helper
+     * @param shouldFail
+     */
+    private void execute( BannedDependencies rule, EnforcerRuleHelper helper, boolean shouldFail )
+    {
+        try
+        {
+            rule.message = null;
+            rule.execute( helper );
+            if ( shouldFail )
+            {
+                fail( "Exception expected." );
+            }
+        }
+        catch ( EnforcerRuleException e )
+        {
+            if ( !shouldFail )
+            {
+                fail( "No Exception expected:" + e.getLocalizedMessage() );
+            }
+            //helper.getLog().debug(e.getMessage());
+        }
+    }
+}