From d7ba589ea198146a3a5aabd4b202557be1d852cc Mon Sep 17 00:00:00 2001 From: jsenko Date: Fri, 24 Aug 2012 13:34:21 +0200 Subject: [PATCH 01/12] Updated pom.xml --- enforcer-rules/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/enforcer-rules/pom.xml b/enforcer-rules/pom.xml index 565f13d0..6d1fa2f3 100644 --- a/enforcer-rules/pom.xml +++ b/enforcer-rules/pom.xml @@ -87,7 +87,7 @@ org.apache.maven.shared maven-dependency-tree - 1.2 + 2.0 org.codehaus.plexus From 8fdb711023c97b1e7dce0b88505f569ed64b8d72 Mon Sep 17 00:00:00 2001 From: jsenko Date: Fri, 24 Aug 2012 13:35:04 +0200 Subject: [PATCH 02/12] Created ArtifactMatcher --- .../enforcer/utils/ArtifactMatcher.java | 157 ++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ArtifactMatcher.java diff --git a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ArtifactMatcher.java b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ArtifactMatcher.java new file mode 100644 index 00000000..7844d989 --- /dev/null +++ b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ArtifactMatcher.java @@ -0,0 +1,157 @@ +package org.apache.maven.plugins.enforcer.utils; + +import java.util.Collection; +import java.util.LinkedList; + +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.plugins.enforcer.AbstractVersionEnforcer; +import org.apache.maven.plugins.enforcer.BanTransitiveDependencies; + +/** + * This class is used for matching Artifacts against a list of patterns. + * + * @author Jakub Senko + * + * @see BanTransitiveDependencies + */ +public final class ArtifactMatcher +{ + + public static class Pattern + { + private String pattern; + + private String[] parts; + + public Pattern(String pattern) + { + if(pattern == null) throw new NullPointerException("pattern"); + + this.pattern = pattern; + + this.parts = pattern.split(":", 5); + } + + public boolean match(Artifact artifact) + { + if(artifact == null) return false; + + switch(parts.length) + { + case 5: + String scope = artifact.getScope(); + if ( scope == null || scope.equals( "" ) ) + { + scope = "compile"; + } + + if(!"*".equals(parts[4]) && !parts[4].equals(scope)) + return false; + + case 4: + String type = artifact.getType(); + if ( type == null || type.equals( "" ) ) + { + type = "jar"; + } + + if(!"*".equals(parts[3]) && !parts[3].equals(type)) + return false; + + case 3: + if(!"*".equals(parts[2]) && !parts[2].equals(artifact.getVersion())) + { + try + { + if(!AbstractVersionEnforcer.containsVersion( VersionRange.createFromVersionSpec(parts[2]), + new DefaultArtifactVersion( artifact.getBaseVersion() ) )) + { + return false; + } + } + catch(InvalidVersionSpecificationException e) + { + // TODO + return false; + } + } + + case 2: + if(!"*".equals(parts[1]) && !parts[1].equals(artifact.getArtifactId())) + return false; + + case 1: + if(!"*".equals(parts[0]) && !parts[0].equals(artifact.getGroupId())) + return false; + else + return true; + default: + throw new AssertionError(); + } + } + + @Override + public String toString() + { + return pattern; + } + } + + + private Collection patterns = new LinkedList(); + + + private Collection ignorePatterns = new LinkedList(); + + /** + * Construct class by providing patterns as strings. + * Empty strings are ignored. + * + * @throws NullPointerException if any of the arguments is null + */ + public ArtifactMatcher(final Collection patterns, final Collection ignorePatterns) + { + if(patterns == null) throw new NullPointerException("patterns"); + if(ignorePatterns == null) throw new NullPointerException("ignorePatterns"); + + for(String exclude: patterns) + { + if(exclude != null && !"".equals(exclude)) + { + this.patterns.add(new Pattern(exclude)); + } + } + + for(String include: ignorePatterns) + { + if(include != null && !"".equals(include)) + { + this.ignorePatterns.add(new Pattern(include)); + } + } + } + + /** + * Check if artifact matches patterns. + */ + public boolean match(Artifact artifact) + { + for(Pattern pattern: patterns) + { + if(pattern.match(artifact)) + { + for(Pattern ignorePattern: ignorePatterns) + { + if(ignorePattern.match(artifact)) return false; + } + + return true; + } + } + + return false; + } +} From bdc5c66050218a2dcbf8760080055ff2658f3d75 Mon Sep 17 00:00:00 2001 From: jsenko Date: Fri, 24 Aug 2012 13:36:10 +0200 Subject: [PATCH 03/12] Created BanTransitiveDependencies enforcer rule --- .../enforcer/BanTransitiveDependencies.java | 175 ++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java diff --git a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java new file mode 100644 index 00000000..140ff5e8 --- /dev/null +++ b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java @@ -0,0 +1,175 @@ +package org.apache.maven.plugins.enforcer; + +import java.util.Collections; +import java.util.List; + +import org.apache.maven.enforcer.rule.api.EnforcerRule; +import org.apache.maven.enforcer.rule.api.EnforcerRuleException; +import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper; +import org.apache.maven.plugins.enforcer.utils.ArtifactMatcher; +import org.apache.maven.project.MavenProject; +import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder; +import org.apache.maven.shared.dependency.graph.DependencyNode; +import org.apache.maven.shared.dependency.graph.internal.DefaultDependencyGraphBuilder; +import org.codehaus.plexus.component.repository.exception.ComponentLookupException; +import org.codehaus.plexus.logging.console.ConsoleLogger; + +/** + * This rule bans all transitive dependencies. + * There is a configuration option to exclude certain artifacts + * from being checked (similar to BannedDependencies). + * + * @author Jakub Senko + */ +public class BanTransitiveDependencies extends AbstractNonCacheableEnforcerRule implements EnforcerRule +{ + + private EnforcerRuleHelper helper; + + /** + * Specify the dependencies that will be ignored. + * This can be a list of artifacts in the format groupId[:artifactId][:version][:type][:scope]. + * Wildcard '*' can be used to in place of specific section + * (ie group:*:1.0 will match both 'group:artifact:1.0' and 'group:anotherArtifact:1.0')
+ * You can override this patterns by using includes. + * Invalid and empty patterns will be ignored. + */ + private List excludes; + + /** + * Specify the dependencies that will be checked. + * These are exceptions to excludes intended for more convenient and finer settings. + * This can be a list of artifacts in the format groupId[:artifactId][:version][:type][:scope]. + * Wildcard '*' can be used to in place of specific section + * (ie group:*:1.0 will match both 'group:artifact:1.0' and 'group:anotherArtifact:1.0')
+ * Invalid and empty patterns will be ignored. + */ + private List includes; + + /** + * Searches dependency tree recursively for transitive dependencies + * that are not excluded, while generating nice info message + * along the way. + */ + private static boolean searchTree(DependencyNode node, int level, ArtifactMatcher excludes, StringBuilder message) + { + + List children = node.getChildren(); + + /* + * if the node is deeper than direct dependency + * and is empty, it is transitive. + * if its not empty it may contain only excluded dependencies + * and does not have to cause failure + */ + boolean hasTransitiveDependencies = level > 1 && children.size() == 0; + + boolean excluded = false; + + /* + * holds recursive message from children, + * will be appended to current message + * if this node has any transitive descendants + * if message is null, don't generate recursive message. + */ + StringBuilder messageFromChildren = message == null ? null : new StringBuilder(); + + if(excludes.match(node.getArtifact())) + { + // is excluded, we don't care about descendants + excluded = true; + hasTransitiveDependencies = false; + } + else + { + for(DependencyNode childNode: children) + { + /* + * if any of the children has transitive d. + * so does the parent + */ + hasTransitiveDependencies = (searchTree(childNode, level + 1, excludes, messageFromChildren) + || hasTransitiveDependencies); + } + } + + + if((excluded || hasTransitiveDependencies) && message != null) // then generate message + { + for(int i = 0; i < level; i++) message.append(" "); + + message.append(node.getArtifact()); + + if(excluded) + { + message.append(" [excluded]\n"); + } + + if(hasTransitiveDependencies) + { + if(level == 1) message.append(" has transitive dependencies:"); + + message.append("\n").append(messageFromChildren); + } + } + + return hasTransitiveDependencies; + } + + + public void execute(EnforcerRuleHelper helper) throws EnforcerRuleException + { + this.helper = helper; + + if(excludes == null) excludes = Collections.emptyList(); + if(includes == null) includes = Collections.emptyList(); + + final ArtifactMatcher exclusions = new ArtifactMatcher(excludes, includes); + + DependencyNode rootNode = null; + + try + { + MavenProject project = (MavenProject) helper.evaluate("${project}"); + + rootNode = createDependencyGraphBuilder() + .buildDependencyGraph(project, null); + } + catch (Exception e) + { + throw new EnforcerRuleException("Error: Could not construct dependency tree.", e); + } + + if(message == null) + { + StringBuilder generatedMessage = new StringBuilder(); + + if(searchTree(rootNode, 0, exclusions, generatedMessage)) + { + throw new EnforcerRuleException(generatedMessage.toString()); + } + } + else + { + if(searchTree(rootNode, 0, exclusions, null)) + { + throw new EnforcerRuleException(message); + } + } + + } + + private DependencyGraphBuilder createDependencyGraphBuilder() + throws ComponentLookupException + { + DefaultDependencyGraphBuilder builder = (DefaultDependencyGraphBuilder) helper + .getContainer() + .lookup(DependencyGraphBuilder.class.getCanonicalName(), "default"); + + builder.enableLogging(new ConsoleLogger(ConsoleLogger.LEVEL_DISABLED, + "DefaultDependencyGraphBuilder")); + + return builder; + } + +} From b481246a38afa19cd7134aaf9745740a4f9894d5 Mon Sep 17 00:00:00 2001 From: jsenko Date: Mon, 27 Aug 2012 15:48:52 +0200 Subject: [PATCH 04/12] Updated BanTransitiveDependencies --- .../enforcer/BanTransitiveDependencies.java | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java index 140ff5e8..d33bab2b 100644 --- a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java +++ b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java @@ -3,6 +3,7 @@ import java.util.Collections; import java.util.List; +import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; import org.apache.maven.enforcer.rule.api.EnforcerRule; import org.apache.maven.enforcer.rule.api.EnforcerRuleException; import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper; @@ -17,7 +18,7 @@ /** * This rule bans all transitive dependencies. * There is a configuration option to exclude certain artifacts - * from being checked (similar to BannedDependencies). + * from being checked. * * @author Jakub Senko */ @@ -50,8 +51,10 @@ public class BanTransitiveDependencies extends AbstractNonCacheableEnforcerRule * Searches dependency tree recursively for transitive dependencies * that are not excluded, while generating nice info message * along the way. + * @throws InvalidVersionSpecificationException */ private static boolean searchTree(DependencyNode node, int level, ArtifactMatcher excludes, StringBuilder message) + throws InvalidVersionSpecificationException { List children = node.getChildren(); @@ -131,7 +134,6 @@ public void execute(EnforcerRuleHelper helper) throws EnforcerRuleException try { MavenProject project = (MavenProject) helper.evaluate("${project}"); - rootNode = createDependencyGraphBuilder() .buildDependencyGraph(project, null); } @@ -140,21 +142,22 @@ public void execute(EnforcerRuleHelper helper) throws EnforcerRuleException throw new EnforcerRuleException("Error: Could not construct dependency tree.", e); } + StringBuilder generatedMessage = null; if(message == null) { - StringBuilder generatedMessage = new StringBuilder(); - + generatedMessage = new StringBuilder(); + } + + try + { if(searchTree(rootNode, 0, exclusions, generatedMessage)) { - throw new EnforcerRuleException(generatedMessage.toString()); + throw new EnforcerRuleException(message == null ? generatedMessage.toString() : message); } } - else + catch (InvalidVersionSpecificationException e) { - if(searchTree(rootNode, 0, exclusions, null)) - { - throw new EnforcerRuleException(message); - } + throw new EnforcerRuleException("Error: Invalid version range.", e); } } From 2f4767498259134b7bf91054795faff48659ea53 Mon Sep 17 00:00:00 2001 From: jsenko Date: Mon, 27 Aug 2012 15:49:43 +0200 Subject: [PATCH 05/12] Updated ArtifactMatcher --- .../enforcer/utils/ArtifactMatcher.java | 43 ++++++++++--------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ArtifactMatcher.java b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ArtifactMatcher.java index 7844d989..ac95e614 100644 --- a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ArtifactMatcher.java +++ b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ArtifactMatcher.java @@ -29,15 +29,23 @@ public static class Pattern public Pattern(String pattern) { if(pattern == null) throw new NullPointerException("pattern"); - + this.pattern = pattern; - this.parts = pattern.split(":", 5); + parts = pattern.split(":", 6); + + if(parts.length == 6) throw new IllegalArgumentException("Pattern contains too many delimiters."); + + for(String part: parts) + { + if("".equals(part)) + throw new IllegalArgumentException("Pattern or its part is empty."); + } } - public boolean match(Artifact artifact) + public boolean match(Artifact artifact) throws InvalidVersionSpecificationException { - if(artifact == null) return false; + if(artifact == null) throw new NullPointerException("artifact"); switch(parts.length) { @@ -64,17 +72,9 @@ public boolean match(Artifact artifact) case 3: if(!"*".equals(parts[2]) && !parts[2].equals(artifact.getVersion())) { - try - { - if(!AbstractVersionEnforcer.containsVersion( VersionRange.createFromVersionSpec(parts[2]), - new DefaultArtifactVersion( artifact.getBaseVersion() ) )) - { - return false; - } - } - catch(InvalidVersionSpecificationException e) + if(!AbstractVersionEnforcer.containsVersion( VersionRange.createFromVersionSpec(parts[2]), + new DefaultArtifactVersion( artifact.getVersion() ) )) { - // TODO return false; } } @@ -117,27 +117,28 @@ public ArtifactMatcher(final Collection patterns, final Collection Date: Mon, 27 Aug 2012 15:51:20 +0200 Subject: [PATCH 06/12] Created test for ArtifactMatcher --- .../enforcer/utils/TestArtifactMatcher.java | 122 ++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 enforcer-rules/src/test/java/org/apache/maven/plugins/enforcer/utils/TestArtifactMatcher.java diff --git a/enforcer-rules/src/test/java/org/apache/maven/plugins/enforcer/utils/TestArtifactMatcher.java b/enforcer-rules/src/test/java/org/apache/maven/plugins/enforcer/utils/TestArtifactMatcher.java new file mode 100644 index 00000000..5af90b8d --- /dev/null +++ b/enforcer-rules/src/test/java/org/apache/maven/plugins/enforcer/utils/TestArtifactMatcher.java @@ -0,0 +1,122 @@ +package org.apache.maven.plugins.enforcer.utils; + +import java.util.ArrayList; +import java.util.Collection; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.DefaultArtifact; +import org.apache.maven.artifact.handler.ArtifactHandler; +import org.apache.maven.artifact.handler.DefaultArtifactHandler; +import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; +import org.apache.maven.artifact.versioning.VersionRange; + +import org.apache.maven.plugins.enforcer.utils.ArtifactMatcher.Pattern; + +import junit.framework.TestCase; + +public class TestArtifactMatcher extends TestCase +{ + private ArtifactMatcher matcher; + + Collection patterns = new ArrayList(); + + Collection ignorePatterns = new ArrayList(); + + public void testPatternInvalidInput() throws InvalidVersionSpecificationException + { + try + { + new Pattern(null); + fail("NullPointerException expected."); + } + catch(NullPointerException e){} + + try + { + new Pattern("a:b:c:d:e:f"); + fail("IllegalArgumentException expected."); + } + catch(IllegalArgumentException e){} + + try + { + new Pattern("a::"); + fail("IllegalArgumentException expected."); + } + catch(IllegalArgumentException e){} + + try + { + Pattern p = new Pattern("*"); + p.match(null); + fail("NullPointerException expected."); + } + catch(NullPointerException e){} + } + + public void testPattern() throws InvalidVersionSpecificationException + { + executePatternMatch("groupId:artifactId:1.0:jar:compile", "groupId", "artifactId", "1.0", "compile", "jar", true); + + executePatternMatch("groupId:artifactId:1.0:jar:compile", "groupId", "artifactId", "1.0", "", "", true); + + executePatternMatch("groupId:artifactId:1.0", "groupId", "artifactId", "1.0", "", "", true); + + executePatternMatch("groupId:artifactId:1.0", "groupId", "artifactId", "1.1", "", "", true); + + executePatternMatch("groupId:artifactId:[1.0]", "groupId", "artifactId", "1.1", "", "", false); + + executePatternMatch("groupId:*:1.0", "groupId", "artifactId", "1.0", "test", "", true); + + executePatternMatch("*:*:1.0", "groupId", "artifactId", "1.0", "", "", true); + + executePatternMatch("*:artifactId:*", "groupId", "artifactId", "1.0", "", "", true); + + executePatternMatch("*", "groupId", "artifactId", "1.0", "", "", true); + } + + public void testMatch() throws InvalidVersionSpecificationException + { + patterns.add("groupId:artifactId:1.0"); + patterns.add("*:anotherArtifact"); + + ignorePatterns.add("badGroup:*:*:test"); + ignorePatterns.add("*:anotherArtifact:1.1"); + + matcher = new ArtifactMatcher(patterns, ignorePatterns); + + executeMatch(matcher, "groupId", "artifactId", "1.0", "", "", true); + + executeMatch(matcher, "groupId", "anotherArtifact", "1.0", "", "", true); + + executeMatch(matcher, "badGroup", "artifactId", "1.0", "", "test", false); + + executeMatch(matcher, "badGroup", "anotherArtifact", "1.0", "", "", true); + + executeMatch(matcher, "groupId", "anotherArtifact", "1.1", "", "", false); + } + + private void executePatternMatch(final String pattern, final String groupId, final String artifactId, + final String versionRange, final String scope, final String type, boolean expectedResult) + throws InvalidVersionSpecificationException + { + assertEquals(expectedResult, new ArtifactMatcher.Pattern(pattern).match(createMockArtifact(groupId, artifactId, versionRange, scope, type))); + } + + + private void executeMatch(final ArtifactMatcher matcher, final String groupId, final String artifactId, + final String versionRange, final String scope, final String type, final boolean expectedResult) throws InvalidVersionSpecificationException + { + assertEquals(expectedResult, matcher.match(createMockArtifact(groupId, artifactId, versionRange, scope, type))); + } + + + private static Artifact createMockArtifact(final String groupId, final String artifactId, + final String versionRange, final String scope, final String type) + { + ArtifactHandler artifactHandler = new DefaultArtifactHandler(); + + VersionRange version = VersionRange.createFromVersion(versionRange); + return new DefaultArtifact(groupId, artifactId, version, scope, type, "", artifactHandler); + } +} From 93cf4d5cbff42cdbfc67c8b419cc988d9a3127ce Mon Sep 17 00:00:00 2001 From: jsenko Date: Mon, 27 Aug 2012 15:53:35 +0200 Subject: [PATCH 07/12] Added license comment. --- .../enforcer/BanTransitiveDependencies.java | 19 +++++++++++++++++++ .../enforcer/utils/ArtifactMatcher.java | 19 +++++++++++++++++++ .../enforcer/utils/TestArtifactMatcher.java | 19 +++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java index d33bab2b..74d36290 100644 --- a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java +++ b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java @@ -1,5 +1,24 @@ package org.apache.maven.plugins.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.Collections; import java.util.List; diff --git a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ArtifactMatcher.java b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ArtifactMatcher.java index ac95e614..727738cb 100644 --- a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ArtifactMatcher.java +++ b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ArtifactMatcher.java @@ -1,5 +1,24 @@ package org.apache.maven.plugins.enforcer.utils; +/* + * 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.Collection; import java.util.LinkedList; diff --git a/enforcer-rules/src/test/java/org/apache/maven/plugins/enforcer/utils/TestArtifactMatcher.java b/enforcer-rules/src/test/java/org/apache/maven/plugins/enforcer/utils/TestArtifactMatcher.java index 5af90b8d..839b0cc8 100644 --- a/enforcer-rules/src/test/java/org/apache/maven/plugins/enforcer/utils/TestArtifactMatcher.java +++ b/enforcer-rules/src/test/java/org/apache/maven/plugins/enforcer/utils/TestArtifactMatcher.java @@ -1,5 +1,24 @@ package org.apache.maven.plugins.enforcer.utils; +/* + * 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.Collection; From 481e9a0b744dd7e366efc75b3b7a69602c645309 Mon Sep 17 00:00:00 2001 From: jsenko Date: Mon, 27 Aug 2012 16:05:23 +0200 Subject: [PATCH 08/12] Minor whitespace and comment modifications. --- .../enforcer/BanTransitiveDependencies.java | 6 ++++-- .../plugins/enforcer/utils/ArtifactMatcher.java | 14 +++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java index 74d36290..d254e490 100644 --- a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java +++ b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java @@ -52,7 +52,8 @@ public class BanTransitiveDependencies extends AbstractNonCacheableEnforcerRule * Wildcard '*' can be used to in place of specific section * (ie group:*:1.0 will match both 'group:artifact:1.0' and 'group:anotherArtifact:1.0')
* You can override this patterns by using includes. - * Invalid and empty patterns will be ignored. + * Version is a string representing standard maven version range. + * Empty patterns will be ignored. */ private List excludes; @@ -62,7 +63,8 @@ public class BanTransitiveDependencies extends AbstractNonCacheableEnforcerRule * This can be a list of artifacts in the format groupId[:artifactId][:version][:type][:scope]. * Wildcard '*' can be used to in place of specific section * (ie group:*:1.0 will match both 'group:artifact:1.0' and 'group:anotherArtifact:1.0')
- * Invalid and empty patterns will be ignored. + * Version is a string representing standard maven version range. + * Empty patterns will be ignored. */ private List includes; diff --git a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ArtifactMatcher.java b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ArtifactMatcher.java index 727738cb..be254d5b 100644 --- a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ArtifactMatcher.java +++ b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ArtifactMatcher.java @@ -69,21 +69,21 @@ public boolean match(Artifact artifact) throws InvalidVersionSpecificationExcept switch(parts.length) { case 5: - String scope = artifact.getScope(); + String scope = artifact.getScope(); if ( scope == null || scope.equals( "" ) ) { - scope = "compile"; + scope = "compile"; } if(!"*".equals(parts[4]) && !parts[4].equals(scope)) return false; case 4: - String type = artifact.getType(); - if ( type == null || type.equals( "" ) ) - { - type = "jar"; - } + String type = artifact.getType(); + if ( type == null || type.equals( "" ) ) + { + type = "jar"; + } if(!"*".equals(parts[3]) && !parts[3].equals(type)) return false; From ab793396d20003e6b4a71cc1e6ec4bbd3297575c Mon Sep 17 00:00:00 2001 From: Paul Gier Date: Wed, 29 Aug 2012 19:26:33 -0500 Subject: [PATCH 09/12] Update formatting to follow Maven standards --- .../enforcer/BanTransitiveDependencies.java | 303 +++++++++--------- .../enforcer/utils/ArtifactMatcher.java | 282 ++++++++-------- 2 files changed, 296 insertions(+), 289 deletions(-) diff --git a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java index d254e490..df4d7665 100644 --- a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java +++ b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java @@ -35,165 +35,166 @@ import org.codehaus.plexus.logging.console.ConsoleLogger; /** - * This rule bans all transitive dependencies. - * There is a configuration option to exclude certain artifacts - * from being checked. + * This rule bans all transitive dependencies. There is a configuration option to exclude certain artifacts from being + * checked. * * @author Jakub Senko */ -public class BanTransitiveDependencies extends AbstractNonCacheableEnforcerRule implements EnforcerRule +public class BanTransitiveDependencies + extends AbstractNonCacheableEnforcerRule + implements EnforcerRule { - - private EnforcerRuleHelper helper; - + + private EnforcerRuleHelper helper; + /** - * Specify the dependencies that will be ignored. - * This can be a list of artifacts in the format groupId[:artifactId][:version][:type][:scope]. - * Wildcard '*' can be used to in place of specific section - * (ie group:*:1.0 will match both 'group:artifact:1.0' and 'group:anotherArtifact:1.0')
- * You can override this patterns by using includes. - * Version is a string representing standard maven version range. + * Specify the dependencies that will be ignored. This can be a list of artifacts in the format + * groupId[:artifactId][:version][:type][:scope]. Wildcard '*' can be used to in place of specific + * section (ie group:*:1.0 will match both 'group:artifact:1.0' and 'group:anotherArtifact:1.0')
+ * You can override this patterns by using includes. Version is a string representing standard maven version range. * Empty patterns will be ignored. */ - private List excludes; - + private List excludes; + /** - * Specify the dependencies that will be checked. - * These are exceptions to excludes intended for more convenient and finer settings. - * This can be a list of artifacts in the format groupId[:artifactId][:version][:type][:scope]. - * Wildcard '*' can be used to in place of specific section - * (ie group:*:1.0 will match both 'group:artifact:1.0' and 'group:anotherArtifact:1.0')
- * Version is a string representing standard maven version range. - * Empty patterns will be ignored. + * Specify the dependencies that will be checked. These are exceptions to excludes intended for more convenient and + * finer settings. This can be a list of artifacts in the format + * groupId[:artifactId][:version][:type][:scope]. Wildcard '*' can be used to in place of specific + * section (ie group:*:1.0 will match both 'group:artifact:1.0' and 'group:anotherArtifact:1.0')
+ * Version is a string representing standard maven version range. Empty patterns will be ignored. */ - private List includes; - - /** - * Searches dependency tree recursively for transitive dependencies - * that are not excluded, while generating nice info message - * along the way. - * @throws InvalidVersionSpecificationException - */ - private static boolean searchTree(DependencyNode node, int level, ArtifactMatcher excludes, StringBuilder message) - throws InvalidVersionSpecificationException - { - - List children = node.getChildren(); - - /* - * if the node is deeper than direct dependency - * and is empty, it is transitive. - * if its not empty it may contain only excluded dependencies - * and does not have to cause failure - */ - boolean hasTransitiveDependencies = level > 1 && children.size() == 0; - - boolean excluded = false; - - /* - * holds recursive message from children, - * will be appended to current message - * if this node has any transitive descendants - * if message is null, don't generate recursive message. - */ - StringBuilder messageFromChildren = message == null ? null : new StringBuilder(); - - if(excludes.match(node.getArtifact())) - { - // is excluded, we don't care about descendants - excluded = true; - hasTransitiveDependencies = false; - } - else - { - for(DependencyNode childNode: children) - { - /* - * if any of the children has transitive d. - * so does the parent - */ - hasTransitiveDependencies = (searchTree(childNode, level + 1, excludes, messageFromChildren) - || hasTransitiveDependencies); - } - } - - - if((excluded || hasTransitiveDependencies) && message != null) // then generate message - { - for(int i = 0; i < level; i++) message.append(" "); - - message.append(node.getArtifact()); - - if(excluded) - { - message.append(" [excluded]\n"); - } - - if(hasTransitiveDependencies) - { - if(level == 1) message.append(" has transitive dependencies:"); - - message.append("\n").append(messageFromChildren); - } - } - - return hasTransitiveDependencies; - } - - - public void execute(EnforcerRuleHelper helper) throws EnforcerRuleException - { - this.helper = helper; - - if(excludes == null) excludes = Collections.emptyList(); - if(includes == null) includes = Collections.emptyList(); - - final ArtifactMatcher exclusions = new ArtifactMatcher(excludes, includes); - - DependencyNode rootNode = null; - - try - { - MavenProject project = (MavenProject) helper.evaluate("${project}"); - rootNode = createDependencyGraphBuilder() - .buildDependencyGraph(project, null); - } - catch (Exception e) - { - throw new EnforcerRuleException("Error: Could not construct dependency tree.", e); - } - - StringBuilder generatedMessage = null; - if(message == null) - { - generatedMessage = new StringBuilder(); - } - - try - { - if(searchTree(rootNode, 0, exclusions, generatedMessage)) - { - throw new EnforcerRuleException(message == null ? generatedMessage.toString() : message); - } - } - catch (InvalidVersionSpecificationException e) - { - throw new EnforcerRuleException("Error: Invalid version range.", e); - } - - } - - private DependencyGraphBuilder createDependencyGraphBuilder() - throws ComponentLookupException - { - DefaultDependencyGraphBuilder builder = (DefaultDependencyGraphBuilder) helper - .getContainer() - .lookup(DependencyGraphBuilder.class.getCanonicalName(), "default"); - - builder.enableLogging(new ConsoleLogger(ConsoleLogger.LEVEL_DISABLED, - "DefaultDependencyGraphBuilder")); - - return builder; - } + private List includes; + + /** + * Searches dependency tree recursively for transitive dependencies that are not excluded, while generating nice + * info message along the way. + * + * @throws InvalidVersionSpecificationException + */ + private static boolean searchTree( DependencyNode node, int level, ArtifactMatcher excludes, StringBuilder message ) + throws InvalidVersionSpecificationException + { + + List children = node.getChildren(); + + /* + * if the node is deeper than direct dependency and is empty, it is transitive. if its not empty it may contain + * only excluded dependencies and does not have to cause failure + */ + boolean hasTransitiveDependencies = level > 1 && children.size() == 0; + + boolean excluded = false; + + /* + * holds recursive message from children, will be appended to current message if this node has any transitive + * descendants if message is null, don't generate recursive message. + */ + StringBuilder messageFromChildren = message == null ? null : new StringBuilder(); + + if ( excludes.match( node.getArtifact() ) ) + { + // is excluded, we don't care about descendants + excluded = true; + hasTransitiveDependencies = false; + } + else + { + for ( DependencyNode childNode : children ) + { + /* + * if any of the children has transitive d. so does the parent + */ + hasTransitiveDependencies = + ( searchTree( childNode, level + 1, excludes, messageFromChildren ) || hasTransitiveDependencies ); + } + } + + if ( ( excluded || hasTransitiveDependencies ) && message != null ) // then generate message + { + for ( int i = 0; i < level; i++ ) + { + message.append( " " ); + } + + message.append( node.getArtifact() ); + + if ( excluded ) + { + message.append( " [excluded]\n" ); + } + + if ( hasTransitiveDependencies ) + { + if ( level == 1 ) + { + message.append( " has transitive dependencies:" ); + } + + message.append( "\n" ).append( messageFromChildren ); + } + } + + return hasTransitiveDependencies; + } + + public void execute( EnforcerRuleHelper helper ) + throws EnforcerRuleException + { + this.helper = helper; + + if ( excludes == null ) + { + excludes = Collections.emptyList(); + } + if ( includes == null ) + { + includes = Collections.emptyList(); + } + + final ArtifactMatcher exclusions = new ArtifactMatcher( excludes, includes ); + + DependencyNode rootNode = null; + + try + { + MavenProject project = (MavenProject) helper.evaluate( "${project}" ); + rootNode = createDependencyGraphBuilder().buildDependencyGraph( project, null ); + } + catch ( Exception e ) + { + throw new EnforcerRuleException( "Error: Could not construct dependency tree.", e ); + } + + StringBuilder generatedMessage = null; + if ( message == null ) + { + generatedMessage = new StringBuilder(); + } + + try + { + if ( searchTree( rootNode, 0, exclusions, generatedMessage ) ) + { + throw new EnforcerRuleException( message == null ? generatedMessage.toString() : message ); + } + } + catch ( InvalidVersionSpecificationException e ) + { + throw new EnforcerRuleException( "Error: Invalid version range.", e ); + } + + } + + private DependencyGraphBuilder createDependencyGraphBuilder() + throws ComponentLookupException + { + DefaultDependencyGraphBuilder builder = + (DefaultDependencyGraphBuilder) helper.getContainer().lookup( DependencyGraphBuilder.class.getCanonicalName(), + "default" ); + + builder.enableLogging( new ConsoleLogger( ConsoleLogger.LEVEL_DISABLED, "DefaultDependencyGraphBuilder" ) ); + + return builder; + } } diff --git a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ArtifactMatcher.java b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ArtifactMatcher.java index be254d5b..77d5b037 100644 --- a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ArtifactMatcher.java +++ b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/ArtifactMatcher.java @@ -31,147 +31,153 @@ /** * This class is used for matching Artifacts against a list of patterns. - * - * @author Jakub Senko * - * @see BanTransitiveDependencies + * @author Jakub Senko + * @see BanTransitiveDependencies */ public final class ArtifactMatcher { - public static class Pattern - { - private String pattern; - - private String[] parts; - - public Pattern(String pattern) - { - if(pattern == null) throw new NullPointerException("pattern"); - - this.pattern = pattern; - - parts = pattern.split(":", 6); - - if(parts.length == 6) throw new IllegalArgumentException("Pattern contains too many delimiters."); - - for(String part: parts) - { - if("".equals(part)) - throw new IllegalArgumentException("Pattern or its part is empty."); - } - } - - public boolean match(Artifact artifact) throws InvalidVersionSpecificationException - { - if(artifact == null) throw new NullPointerException("artifact"); - - switch(parts.length) - { - case 5: - String scope = artifact.getScope(); - if ( scope == null || scope.equals( "" ) ) - { - scope = "compile"; - } - - if(!"*".equals(parts[4]) && !parts[4].equals(scope)) - return false; - - case 4: - String type = artifact.getType(); - if ( type == null || type.equals( "" ) ) - { - type = "jar"; - } - - if(!"*".equals(parts[3]) && !parts[3].equals(type)) - return false; - - case 3: - if(!"*".equals(parts[2]) && !parts[2].equals(artifact.getVersion())) - { - if(!AbstractVersionEnforcer.containsVersion( VersionRange.createFromVersionSpec(parts[2]), - new DefaultArtifactVersion( artifact.getVersion() ) )) - { - return false; - } - } - - case 2: - if(!"*".equals(parts[1]) && !parts[1].equals(artifact.getArtifactId())) - return false; - - case 1: - if(!"*".equals(parts[0]) && !parts[0].equals(artifact.getGroupId())) - return false; - else - return true; - default: - throw new AssertionError(); - } - } - - @Override - public String toString() - { - return pattern; - } - } - - - private Collection patterns = new LinkedList(); - - - private Collection ignorePatterns = new LinkedList(); - - /** - * Construct class by providing patterns as strings. - * Empty strings are ignored. - * - * @throws NullPointerException if any of the arguments is null - */ - public ArtifactMatcher(final Collection patterns, final Collection ignorePatterns) - { - if(patterns == null) throw new NullPointerException("patterns"); - if(ignorePatterns == null) throw new NullPointerException("ignorePatterns"); - - for(String pattern: patterns) - { - if(pattern != null && !"".equals(pattern)) - { - this.patterns.add(new Pattern(pattern)); - } - } - - for(String ignorePattern: ignorePatterns) - { - if(ignorePattern != null && !"".equals(ignorePattern)) - { - this.ignorePatterns.add(new Pattern(ignorePattern)); - } - } - } - - /** - * Check if artifact matches patterns. - * @throws InvalidVersionSpecificationException - */ - public boolean match(Artifact artifact) throws InvalidVersionSpecificationException - { - for(Pattern pattern: patterns) - { - if(pattern.match(artifact)) - { - for(Pattern ignorePattern: ignorePatterns) - { - if(ignorePattern.match(artifact)) return false; - } - - return true; - } - } - - return false; - } + public static class Pattern + { + private String pattern; + + private String[] parts; + + public Pattern( String pattern ) + { + if ( pattern == null ) + throw new NullPointerException( "pattern" ); + + this.pattern = pattern; + + parts = pattern.split( ":", 6 ); + + if ( parts.length == 6 ) + throw new IllegalArgumentException( "Pattern contains too many delimiters." ); + + for ( String part : parts ) + { + if ( "".equals( part ) ) + throw new IllegalArgumentException( "Pattern or its part is empty." ); + } + } + + public boolean match( Artifact artifact ) + throws InvalidVersionSpecificationException + { + if ( artifact == null ) + throw new NullPointerException( "artifact" ); + + switch ( parts.length ) + { + case 5: + String scope = artifact.getScope(); + if ( scope == null || scope.equals( "" ) ) + { + scope = "compile"; + } + + if ( !"*".equals( parts[4] ) && !parts[4].equals( scope ) ) + return false; + + case 4: + String type = artifact.getType(); + if ( type == null || type.equals( "" ) ) + { + type = "jar"; + } + + if ( !"*".equals( parts[3] ) && !parts[3].equals( type ) ) + return false; + + case 3: + if ( !"*".equals( parts[2] ) && !parts[2].equals( artifact.getVersion() ) ) + { + if ( !AbstractVersionEnforcer.containsVersion( VersionRange.createFromVersionSpec( parts[2] ), + new DefaultArtifactVersion( + artifact.getVersion() ) ) ) + { + return false; + } + } + + case 2: + if ( !"*".equals( parts[1] ) && !parts[1].equals( artifact.getArtifactId() ) ) + return false; + + case 1: + if ( !"*".equals( parts[0] ) && !parts[0].equals( artifact.getGroupId() ) ) + return false; + else + return true; + default: + throw new AssertionError(); + } + } + + @Override + public String toString() + { + return pattern; + } + } + + private Collection patterns = new LinkedList(); + + private Collection ignorePatterns = new LinkedList(); + + /** + * Construct class by providing patterns as strings. Empty strings are ignored. + * + * @throws NullPointerException if any of the arguments is null + */ + public ArtifactMatcher( final Collection patterns, final Collection ignorePatterns ) + { + if ( patterns == null ) + throw new NullPointerException( "patterns" ); + if ( ignorePatterns == null ) + throw new NullPointerException( "ignorePatterns" ); + + for ( String pattern : patterns ) + { + if ( pattern != null && !"".equals( pattern ) ) + { + this.patterns.add( new Pattern( pattern ) ); + } + } + + for ( String ignorePattern : ignorePatterns ) + { + if ( ignorePattern != null && !"".equals( ignorePattern ) ) + { + this.ignorePatterns.add( new Pattern( ignorePattern ) ); + } + } + } + + /** + * Check if artifact matches patterns. + * + * @throws InvalidVersionSpecificationException + */ + public boolean match( Artifact artifact ) + throws InvalidVersionSpecificationException + { + for ( Pattern pattern : patterns ) + { + if ( pattern.match( artifact ) ) + { + for ( Pattern ignorePattern : ignorePatterns ) + { + if ( ignorePattern.match( artifact ) ) + return false; + } + + return true; + } + } + + return false; + } } From b7883dae8d7d5eae5348f025e43ac630669faeb2 Mon Sep 17 00:00:00 2001 From: Paul Gier Date: Wed, 29 Aug 2012 20:27:19 -0500 Subject: [PATCH 10/12] Add basic integration tests for ban-transitive-dependencies --- .../invoker.properties | 1 + .../ban-transitive-dependencies-fail/pom.xml | 71 +++++++++++++++++++ .../it/ban-transitive-dependencies/pom.xml | 70 ++++++++++++++++++ 3 files changed, 142 insertions(+) create mode 100644 maven-enforcer-plugin/src/it/ban-transitive-dependencies-fail/invoker.properties create mode 100644 maven-enforcer-plugin/src/it/ban-transitive-dependencies-fail/pom.xml create mode 100644 maven-enforcer-plugin/src/it/ban-transitive-dependencies/pom.xml diff --git a/maven-enforcer-plugin/src/it/ban-transitive-dependencies-fail/invoker.properties b/maven-enforcer-plugin/src/it/ban-transitive-dependencies-fail/invoker.properties new file mode 100644 index 00000000..c21e972f --- /dev/null +++ b/maven-enforcer-plugin/src/it/ban-transitive-dependencies-fail/invoker.properties @@ -0,0 +1 @@ +invoker.buildResult = failure diff --git a/maven-enforcer-plugin/src/it/ban-transitive-dependencies-fail/pom.xml b/maven-enforcer-plugin/src/it/ban-transitive-dependencies-fail/pom.xml new file mode 100644 index 00000000..d4ea8e8f --- /dev/null +++ b/maven-enforcer-plugin/src/it/ban-transitive-dependencies-fail/pom.xml @@ -0,0 +1,71 @@ + + + + + + 4.0.0 + + org.apache.maven.its.enforcer + ban-transitive-fail-test + 1.0 + + + + + org.apache.maven.plugins + maven-enforcer-plugin + @project.version@ + + + test + + enforce + + + + + + junit:junit + classworlds:classworlds + org.codehaus.plexus:plexus-io + + + + + + + + + + + + + org.codehaus.plexus + plexus-archiver + 2.1.1 + + + org.codehaus.plexus + plexus-utils + 3.0 + + + + diff --git a/maven-enforcer-plugin/src/it/ban-transitive-dependencies/pom.xml b/maven-enforcer-plugin/src/it/ban-transitive-dependencies/pom.xml new file mode 100644 index 00000000..21f7db43 --- /dev/null +++ b/maven-enforcer-plugin/src/it/ban-transitive-dependencies/pom.xml @@ -0,0 +1,70 @@ + + + + + + 4.0.0 + + org.apache.maven.its.enforcer + ban-transitive-test + 1.0 + + + + + org.apache.maven.plugins + maven-enforcer-plugin + @project.version@ + + + test + + enforce + + + + + + org.codehaus.plexus:plexus-container-default + org.codehaus.plexus:plexus-io + + + + + + + + + + + + + org.codehaus.plexus + plexus-archiver + 2.1.1 + + + org.codehaus.plexus + plexus-utils + 3.0 + + + + From ae8a1054dd64a66f16e53ce210cd2d4727faf8d1 Mon Sep 17 00:00:00 2001 From: jsenko Date: Mon, 3 Sep 2012 12:55:59 +0200 Subject: [PATCH 11/12] Fixed minor bug. --- .../maven/plugins/enforcer/BanTransitiveDependencies.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java index df4d7665..58f6b860 100644 --- a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java +++ b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/BanTransitiveDependencies.java @@ -78,10 +78,9 @@ private static boolean searchTree( DependencyNode node, int level, ArtifactMatch List children = node.getChildren(); /* - * if the node is deeper than direct dependency and is empty, it is transitive. if its not empty it may contain - * only excluded dependencies and does not have to cause failure + * if the node is deeper than direct dependency and is empty, it is transitive. */ - boolean hasTransitiveDependencies = level > 1 && children.size() == 0; + boolean hasTransitiveDependencies = level > 1; boolean excluded = false; From 43e536e8c248b1368b7d739bf8fd46c27525736d Mon Sep 17 00:00:00 2001 From: jsenko Date: Mon, 3 Sep 2012 16:10:56 +0200 Subject: [PATCH 12/12] Created site for banTransitiveDependencies rule. --- .../site/apt/banTransitiveDependencies.apt.vm | 89 +++++++++++++++++++ enforcer-rules/src/site/apt/index.apt | 2 + 2 files changed, 91 insertions(+) create mode 100644 enforcer-rules/src/site/apt/banTransitiveDependencies.apt.vm diff --git a/enforcer-rules/src/site/apt/banTransitiveDependencies.apt.vm b/enforcer-rules/src/site/apt/banTransitiveDependencies.apt.vm new file mode 100644 index 00000000..efdacedf --- /dev/null +++ b/enforcer-rules/src/site/apt/banTransitiveDependencies.apt.vm @@ -0,0 +1,89 @@ +~~ 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. + + ------ + Ban Transitive Dependencies + ------ + ------ + August 2012 + ------ + +Ban Transitive Dependencies + + This rule bans all transitive dependencies. + + + The following parameters are supported by this rule: + + * excludes - specify the dependencies that will be ignored.\ + This can be a list of artifacts in the format + groupId[:artifactId[:version[:type[:scope]]]] . + Wildcard '*' can be used to in place of specific section (e.g. group:*:1.0 will match both 'group:artifact:1.0' and 'group:anotherArtifact:1.0') + Version is a string representing standard maven version range. Empty patterns will be ignored. + + * includes - specify the dependencies that will be checked.\ + These are exceptions to excludes intended for more convenient configuration. This can be a list of artifacts in the format + groupId[:artifactId[:version[:type[:scope]]]] as above. + + * message - an optional message to the user if the rule fails. Will replace generated report message. + + [] + + + Sample Plugin Configuration: + ++---+ + + [...] + + + + org.apache.maven.plugins + maven-enforcer-plugin + ${project.version} + + + enforce-banned-dependencies + + enforce + + + + + + + org.apache.maven:ignoredArtifact + *:anotherIgnoredArtifact + + + + org.apache.maven:ignoredArtifact:[1.0] + + + + + + + + + + [...] + ++---+ \ No newline at end of file diff --git a/enforcer-rules/src/site/apt/index.apt b/enforcer-rules/src/site/apt/index.apt index 56aac45a..a3d158f0 100644 --- a/enforcer-rules/src/site/apt/index.apt +++ b/enforcer-rules/src/site/apt/index.apt @@ -32,6 +32,8 @@ Standard Rules * {{{./alwaysFail.html}alwaysFail}} - Always fail... used to test plugin configuration. * {{{./bannedDependencies.html}bannedDependencies}} - enforces that excluded dependencies aren't included. + + * {{{./banTransitiveDependencies.html}banTransitiveDependencies}} - enforces that project doesn't have transitive dependencies. * bannedPlugins - enforces that excluded plugins aren't included.