Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MENFORCER-335] Update dependencyConvergence.apt.vm #347

Merged
merged 9 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ private String buildConvergenceErrorMsg(List<DependencyNode> nodeList) {
builder.append(System.lineSeparator())
.append("Dependency convergence error for ")
.append(nodeList.get(0).getArtifact().toString())
.append(" paths to dependency are:")
.append(". Paths to dependency are:")
.append(System.lineSeparator());
if (nodeList.size() > 0) {
builder.append(buildTreeString(nodeList.get(0)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ private String buildErrorMessage(List<DependencyNode> conflict) {
.append(System.lineSeparator())
.append("Require upper bound dependencies error for ")
.append(getFullArtifactName(conflict.get(0), false))
.append(" paths to dependency are:")
.append(". Paths to dependency are:")
.append(System.lineSeparator());
if (conflict.size() > 0) {
errorMessage.append(buildTreeString(conflict.get(0)));
Expand Down
82 changes: 51 additions & 31 deletions enforcer-rules/src/site/apt/dependencyConvergence.apt.vm
Original file line number Diff line number Diff line change
Expand Up @@ -24,65 +24,85 @@

Dependency Convergence

This rule requires that dependency version numbers converge. If a project has two dependencies, A and B, both depending on the same artifact, C, this rule will fail the build if A depends on a different version of C than the version of C depended on by B.
This rule requires that dependency versions are the same everywhere in the tree.
If a project has two dependencies, A and B, both depending on the same
artifact, C, this rule will fail the build if A depends on one
version of C and B depends on a different version of C.

Here is a concrete example.

This will cause a build to fail.
A project containing these two dependencies does not converge
because org.jdom:jdom:1.1.3 depennds on Jaxen 1.1.3 and
org.org.jenkins-ci.main:jenkins-core:2.492 depends on Jaxen 2.0.0:

+-----------------------------------------------------------------------------------

<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>1.6.1</version>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.6.0</version>
<groupId>org.org.jenkins-ci.main</groupId>
<artifactId>jenkins-core</artifactId>
<version>2.492</groupId>
</dependency>
</dependencies>
+-----------------------------------------------------------------------------------

With this being logged during compilation
This is not obvious from the dependencies themselves. However, if the dependencyConvergence
rule is activated in the project, this message will be logged during compilation:

+-----------------------------------------------------------------------------------
Dependency convergence error for org.slf4j:slf4j-api1.6.1 paths to dependency are:

[ERROR]
Dependency convergence error for org.slf4j:slf4j-api:1.6.1 paths to dependency are:
Dependency convergence error for jaxen:jaxen. Paths to dependency are:
+-org.myorg:my-project:1.0.0-SNAPSHOT
+-org.slf4j:slf4j-jdk14:1.6.1
+-org.slf4j:slf4j-api:1.6.1
+-org.jdom:jdom:1.1.3
+-jaxen:jaxen:1.1.3
and
+-org.myorg:my-project:1.0.0-SNAPSHOT
+-org.slf4j:slf4j-nop:1.6.0
+-org.slf4j:slf4j-api:1.6.0
+-org.org.jenkins-ci.main:jenkins-core:2.492
+-jaxen:jaxen:2.0.0
+-----------------------------------------------------------------------------------

And this will succeed:
However, if you exclude JDOM's dependency on Jaxen in your own pom, then only
one version of Jaxen is added to the classpath and the rule
passes:

+-----------------------------------------------------------------------------------
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.6.0</version>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.1.3</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.org.jenkins-ci.main</groupId>
<artifactId>jenkins-core</artifactId>
<version>2.492</groupId>
</dependency>
+-----------------------------------------------------------------------------------

You can also use the dependencyManagement element or a "bill of materials" (BOM)
to uniquely specify a single version for all transitive dependencies with the
same group ID, artifact ID, and classifier. For example, this dependencyManagement
element pins the project's Jaxen version to 2.0.0, regardless of which versions
may appear in transitive dependencies:

+-----------------------------------------------------------------------------------
<dependencyManagement>
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>2.0.0</groupId>
</dependency>
</dependencyManagement>
+-----------------------------------------------------------------------------------

Here is how a project should be set up to use this rule:

Expand Down Expand Up @@ -119,8 +139,8 @@ and

* Timestamped Version

By default the non-unique versions are matched, which means the <<<X.Y-SNAPSHOT>>> instead of the timestamped versions.
If you want to use the unique versions of the dependencies, you can set its property to <<<true>>>.
By default, the non-unique versions are matched, which means the <<<X.Y-SNAPSHOT>>> instead of the timestamped versions.
If you want to use the unique versions of the dependencies, set the uniqueVersions property to <<<true>>>:

+---------------------------------------------
<dependencyConvergence>
Expand All @@ -145,7 +165,7 @@ and
[]

The format for artifacts is groupId[:artifactId][:version][:type][:scope][:classifier] where artifactId, version,
type, scope and classifier are optional. Wildcards may be used to replace an entire section or just parts of a
type, scope, and classifier are optional. Wildcards may replace an entire section or just parts of a
section. This rule uses the {{{./versionRanges.html}Enforcer version range syntax}} to define allowed versions.

+---------------------------------------------
Expand Down
12 changes: 6 additions & 6 deletions enforcer-rules/src/site/apt/requireUpperBoundDeps.apt.vm
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@
-----

This rule requires that the version for each dependency resolved during a build is equal
to or higher than all transitive dependency declarations. The version of each dependency
to or higher than highest version found in the transitive dependencies. The version of each dependency
resolved during the build will normally be the version specified in the POM or the
version with the least transitive steps (the "nearest" definition). For more
information about Maven dependency resolution, see
{{{http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html}the Maven site}}.
{{{https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html}Introduction to the Dependency Mechanism}}.

The following parameters are supported by this rule:

Expand Down Expand Up @@ -59,15 +59,15 @@
</dependencies>
-----------------------------------------------------------------------------------

Because the project will run logback-classic 0.9.9 with slf4j-api 1.4.0
and slf4j-api 1.4.0 is probably not forwards compatible with slf4j-api 1.5.0.
Here the build fails because slf4j-api 1.4.0 is added to the classpath,
but logback-classic depends on the higher 1.5.0 version of slf4j-api.

This is the log message:

-----------------------------------------------------------------------------------

Failed while enforcing RequireUpperBoundDeps. The error(s) are [
RequireUpperBoundDeps error for org.slf4j:slf4j-api:1.4.0 paths to dependency are:
RequireUpperBoundDeps error for org.slf4j:slf4j-api:1.4.0. Paths to dependency are:
+-test:TestParent:1.0-SNAPSHOT
+-org.slf4j:slf4j-api:1.4.0
and
Expand All @@ -78,7 +78,7 @@ and

-----------------------------------------------------------------------------------

And this will succeed:
This will succeed because the highest version, 1.6.0, is selected:

-----------------------------------------------------------------------------------
<dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
def buildLog = new File( basedir, 'build.log' ).text

assert buildLog.contains( '[ERROR] Rule 0: org.apache.maven.enforcer.rules.dependency.DependencyConvergence failed with message' )
assert buildLog.contains( 'Dependency convergence error for org.slf4j:slf4j-api:jar:1.6.2 paths to dependency are:' )
assert buildLog.contains( 'Dependency convergence error for org.slf4j:slf4j-api:jar:1.6.2. Paths to dependency are:' )
assert buildLog.contains( '+-org.slf4j:slf4j-api:jar:1.6.2:compile' )
assert buildLog.contains( '+-org.slf4j:slf4j-api:jar:1.6.1:provided' )
assert !buildLog.contains( 'org.slf4j:slf4j-api:jar:1.6.0' )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ File buildLog = new File( basedir, 'build.log' )
assert buildLog.text.contains( 'Rule 0: org.apache.maven.enforcer.rules.dependency.RequireUpperBoundDeps failed with message:' )

def message = 'Failed while enforcing RequireUpperBoundDeps. The error(s) are [' + LS+
'Require upper bound dependencies error for org.apache.maven.plugins.enforcer.its:menforcer146-x:1.1 paths to dependency are:' + LS+
'Require upper bound dependencies error for org.apache.maven.plugins.enforcer.its:menforcer146-x:1.1. Paths to dependency are:' + LS+
'+-org.apache.maven.enforcer.its:menforcer146-a:1.0-SNAPSHOT' + LS+
' +-org.apache.maven.plugins.enforcer.its:menforcer146-b:1.0' + LS+
' +-org.apache.maven.plugins.enforcer.its:menforcer146-x:1.1 (managed) <-- org.apache.maven.plugins.enforcer.its:menforcer146-x:2.1' + LS+
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ def buildLog = new File( basedir, 'build.log' ).text

assert buildLog.contains( 'Rule 0: org.apache.maven.enforcer.rules.dependency.RequireUpperBoundDeps failed with message:' )

assert buildLog.contains('[ERROR] Require upper bound dependencies error for org.apache.maven.plugins.enforcer.its:menforcer128_api:1.4.0 [provided] paths to dependency are:')
assert buildLog.contains('[ERROR] Require upper bound dependencies error for org.apache.maven.plugins.enforcer.its:menforcer128_api:1.4.0 [provided]. Paths to dependency are:')

assert !buildLog.contains('[ERROR] Require upper bound dependencies error for org.apache.maven.plugins.enforcer.its:menforcer138_utils:1.0.4')
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@
*/
File buildLog = new File( basedir, 'build.log' )
assert buildLog.text.contains( 'Rule 0: org.apache.maven.enforcer.rules.dependency.RequireUpperBoundDeps failed with message:' )
assert buildLog.text.contains( 'Require upper bound dependencies error for org.apache.maven.plugins.enforcer.its:menforcer134_model:1.0-20130423.042904-7222 paths to dependency are:' )
assert buildLog.text.contains( 'Require upper bound dependencies error for org.apache.maven.plugins.enforcer.its:menforcer134_model:1.0-20130423.042904-7222. Paths to dependency are:' )
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ File buildLog = new File( basedir, 'build.log' )

assert buildLog.text.contains( 'Rule 0: org.apache.maven.enforcer.rules.dependency.RequireUpperBoundDeps failed with message:' )
def message =
'Require upper bound dependencies error for org.apache.maven.plugins.enforcer.its:menforcer128_api:1.4.0 paths to dependency are:'+LS+
'Require upper bound dependencies error for org.apache.maven.plugins.enforcer.its:menforcer128_api:1.4.0. Paths to dependency are:'+LS+
'+-org.apache.maven.plugins.enforcer.its:menforcer128:1.0-SNAPSHOT'+LS+
' +-org.apache.maven.plugins.enforcer.its:menforcer128_api:1.4.0'+LS+
'and'+LS+
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ File buildLog = new File( basedir, 'build.log' )

assert buildLog.text.contains( 'Rule 0: org.apache.maven.enforcer.rules.dependency.RequireUpperBoundDeps failed with message:' )
def message =
'Require upper bound dependencies error for org.apache.maven.plugins.enforcer.its:menforcer128_api:1.4.0 [runtime] paths to dependency are:'+LS+
'Require upper bound dependencies error for org.apache.maven.plugins.enforcer.its:menforcer128_api:1.4.0 [runtime]. Paths to dependency are:'+LS+
'+-org.apache.maven.plugins.enforcer.its:menforcer313:1.0-SNAPSHOT'+LS+
' +-org.apache.maven.plugins.enforcer.its:menforcer128_api:1.4.0 [runtime]'+LS+
'and'+LS+
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ File buildLog = new File( basedir, 'build.log' )

assert buildLog.text.contains( 'Rule 0: org.apache.maven.enforcer.rules.dependency.RequireUpperBoundDeps failed with message:' )
def message =
'Require upper bound dependencies error for org.apache.maven.plugins.enforcer.its:menforcer128_api:1.4.0 paths to dependency are:'+LS+
'Require upper bound dependencies error for org.apache.maven.plugins.enforcer.its:menforcer128_api:1.4.0. Paths to dependency are:'+LS+
'+-org.apache.maven.plugins.enforcer.its:menforcer128:1.0-SNAPSHOT'+LS+
' +-org.apache.maven.plugins.enforcer.its:menforcer128_api:1.4.0'+LS+
'and'+LS+
Expand Down
Loading