diff --git a/versions-common/src/main/java/org/codehaus/mojo/versions/utils/DependencyBuilder.java b/versions-common/src/main/java/org/codehaus/mojo/versions/utils/DependencyBuilder.java
index adfb8b1b65..107d1cf38b 100644
--- a/versions-common/src/main/java/org/codehaus/mojo/versions/utils/DependencyBuilder.java
+++ b/versions-common/src/main/java/org/codehaus/mojo/versions/utils/DependencyBuilder.java
@@ -15,26 +15,42 @@
* limitations under the License.
*/
-import java.util.Optional;
+import java.util.HashMap;
+import java.util.Map;
import org.apache.maven.model.Dependency;
-
-import static java.util.Optional.empty;
-import static java.util.Optional.of;
-import static java.util.Optional.ofNullable;
+import org.apache.maven.model.InputLocation;
/**
* Builder class for {@linkplain Dependency}
*/
-@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
public class DependencyBuilder {
- private Optional groupId = empty();
- private Optional artifactId = empty();
- private Optional version = empty();
- private Optional type = empty();
- private Optional classifier = empty();
- private Optional scope = empty();
- private Optional optional = empty();
+ public enum Location {
+ GROUP_ID("groupId"),
+ ARTIFACT_ID("artifactId"),
+ VERSION("version");
+
+ private final String stringValue;
+
+ Location(String stringValue) {
+ this.stringValue = stringValue;
+ }
+
+ @Override
+ public String toString() {
+ return stringValue;
+ }
+ }
+
+ private static final Dependency TEMPLATE = new Dependency();
+ private String groupId = TEMPLATE.getGroupId();
+ private String artifactId = TEMPLATE.getArtifactId();
+ private String version = TEMPLATE.getVersion();
+ private String type = TEMPLATE.getType();
+ private String classifier = TEMPLATE.getClassifier();
+ private String scope = TEMPLATE.getScope();
+ private String optional = TEMPLATE.getOptional();
+ private final Map inputLocationMap = new HashMap<>();
private DependencyBuilder() {}
@@ -44,7 +60,7 @@ private DependencyBuilder() {}
* @return builder instance
*/
public DependencyBuilder withGroupId(String groupId) {
- this.groupId = ofNullable(groupId);
+ this.groupId = groupId;
return this;
}
@@ -54,7 +70,7 @@ public DependencyBuilder withGroupId(String groupId) {
* @return builder instance
*/
public DependencyBuilder withArtifactId(String artifactId) {
- this.artifactId = ofNullable(artifactId);
+ this.artifactId = artifactId;
return this;
}
@@ -64,7 +80,7 @@ public DependencyBuilder withArtifactId(String artifactId) {
* @return builder instance
*/
public DependencyBuilder withVersion(String version) {
- this.version = ofNullable(version);
+ this.version = version;
return this;
}
@@ -74,7 +90,7 @@ public DependencyBuilder withVersion(String version) {
* @return builder instance
*/
public DependencyBuilder withType(String type) {
- this.type = ofNullable(type);
+ this.type = type;
return this;
}
@@ -84,7 +100,7 @@ public DependencyBuilder withType(String type) {
* @return builder instance
*/
public DependencyBuilder withClassifier(String classifier) {
- this.classifier = ofNullable(classifier);
+ this.classifier = classifier;
return this;
}
@@ -94,7 +110,7 @@ public DependencyBuilder withClassifier(String classifier) {
* @return builder instance
*/
public DependencyBuilder withScope(String scope) {
- this.scope = ofNullable(scope);
+ this.scope = scope;
return this;
}
@@ -104,7 +120,7 @@ public DependencyBuilder withScope(String scope) {
* @return builder instance
*/
public DependencyBuilder withOptional(String optional) {
- this.optional = ofNullable(optional);
+ this.optional = optional;
return this;
}
@@ -114,7 +130,12 @@ public DependencyBuilder withOptional(String optional) {
* @return builder instance
*/
public DependencyBuilder withOptional(boolean optional) {
- this.optional = of(String.valueOf(optional));
+ this.optional = String.valueOf(optional);
+ return this;
+ }
+
+ public DependencyBuilder withLocation(String element, InputLocation location) {
+ this.inputLocationMap.put(element, location);
return this;
}
@@ -132,14 +153,14 @@ public static DependencyBuilder newBuilder() {
*/
public Dependency build() {
Dependency inst = new Dependency();
- groupId.ifPresent(inst::setGroupId);
- artifactId.ifPresent(inst::setArtifactId);
- version.ifPresent(inst::setVersion);
- type.ifPresent(inst::setType);
- classifier.ifPresent(inst::setClassifier);
- scope.ifPresent(inst::setScope);
- optional.ifPresent(inst::setOptional);
-
+ inst.setGroupId(groupId);
+ inst.setArtifactId(artifactId);
+ inst.setVersion(version);
+ inst.setType(type);
+ inst.setClassifier(classifier);
+ inst.setScope(scope);
+ inst.setOptional(optional);
+ inputLocationMap.forEach(inst::setLocation);
return inst;
}
}
diff --git a/versions-maven-plugin/src/it/it-display-dependency-updates-008-outputLineWidth/invoker.properties b/versions-maven-plugin/src/it/it-display-dependency-updates-008-outputLineWidth/invoker.properties
deleted file mode 100644
index 3a78145dd3..0000000000
--- a/versions-maven-plugin/src/it/it-display-dependency-updates-008-outputLineWidth/invoker.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-invoker.goals=${project.groupId}:${project.artifactId}:${project.version}:display-dependency-updates
-invoker.mavenOpts=-Dverbose=true -Dversions.outputFile=./dependencyUpdate.txt -DoutputEncoding=UTF-8 -Dversions.outputLineWidth=120
\ No newline at end of file
diff --git a/versions-maven-plugin/src/it/it-display-dependency-updates-008-outputLineWidth/pom.xml b/versions-maven-plugin/src/it/it-display-dependency-updates-008-outputLineWidth/pom.xml
deleted file mode 100644
index 9955ecbc5c..0000000000
--- a/versions-maven-plugin/src/it/it-display-dependency-updates-008-outputLineWidth/pom.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
- 4.0.0
- localhost
- it-display-dependency-updates-008-displayTerminalWidth
- 1.0
- pom
- display-dependency-updates
- Validate usage of displayTerminalWidth parameter
- http://localhost/
-
-
- localhost
- dummy-api
- 1.1
-
-
-
-
-
-
- localhost
- dummy-maven-plugin
- 1.0
-
-
- maven-clean-plugin
- 2.2
-
-
- maven-deploy-plugin
- 2.3
-
-
- maven-install-plugin
- 2.2
-
-
- maven-site-plugin
- 2.0
-
-
- maven-project-info-reports-plugin
- 2.1
-
-
-
-
-
diff --git a/versions-maven-plugin/src/it/it-display-dependency-updates-008-outputLineWidth/verify.bsh b/versions-maven-plugin/src/it/it-display-dependency-updates-008-outputLineWidth/verify.bsh
deleted file mode 100644
index 956ef51dfb..0000000000
--- a/versions-maven-plugin/src/it/it-display-dependency-updates-008-outputLineWidth/verify.bsh
+++ /dev/null
@@ -1,27 +0,0 @@
-import java.io.*;
-import org.codehaus.plexus.util.FileUtils;
-
-try
-{
-
- // validate outputFile
- File outputFile = new File( basedir, "dependencyUpdate.txt" );
- if (!outputFile.exists()) {
- System.out.println( "outputFile not found: " + outputFile.getPath() );
- return false;
- }
- buf = FileUtils.fileRead( outputFile );
- if ( !buf.contains("localhost:dummy-api ............................................................................... 1.1 ->") )
- {
- System.out.println( "displayTerminalWidth parameter not respected" );
- return false;
- }
-
-}
-catch( Throwable t )
-{
- t.printStackTrace();
- return false;
-}
-
-return true;
diff --git a/versions-maven-plugin/src/it/it-display-dependency-updates-008/invoker.properties b/versions-maven-plugin/src/it/it-display-dependency-updates-008/invoker.properties
new file mode 100644
index 0000000000..339620d806
--- /dev/null
+++ b/versions-maven-plugin/src/it/it-display-dependency-updates-008/invoker.properties
@@ -0,0 +1,2 @@
+invoker.goals=${project.groupId}:${project.artifactId}:${project.version}:display-dependency-updates
+invoker.mavenOpts=-Dverbose=true -Dversions.outputFile=./output.txt -DoutputEncoding=UTF-8 -Dversions.outputLineWidth=120
diff --git a/versions-maven-plugin/src/it/it-display-dependency-updates-008/pom.xml b/versions-maven-plugin/src/it/it-display-dependency-updates-008/pom.xml
new file mode 100644
index 0000000000..4f0675f020
--- /dev/null
+++ b/versions-maven-plugin/src/it/it-display-dependency-updates-008/pom.xml
@@ -0,0 +1,19 @@
+
+
+ 4.0.0
+ localhost
+ it-display-dependency-updates-008-displayTerminalWidth
+ 1.0
+ pom
+ display-dependency-updates
+ Validate usage of displayTerminalWidth parameter
+ http://localhost/
+
+
+ localhost
+ dummy-api
+ 1.0
+
+
+
diff --git a/versions-maven-plugin/src/it/it-display-dependency-updates-008/verify.groovy b/versions-maven-plugin/src/it/it-display-dependency-updates-008/verify.groovy
new file mode 100644
index 0000000000..cd00007eba
--- /dev/null
+++ b/versions-maven-plugin/src/it/it-display-dependency-updates-008/verify.groovy
@@ -0,0 +1,2 @@
+def output = new File(basedir, "output.txt").text
+assert output.contains('localhost:dummy-api ............................................................................... 1.0 ->')
\ No newline at end of file
diff --git a/versions-maven-plugin/src/it/it-display-dependency-updates-009-processDependencyManagementTransitive-false/invoker.properties b/versions-maven-plugin/src/it/it-display-dependency-updates-009-processDependencyManagementTransitive-false/invoker.properties
deleted file mode 100644
index e4813a9162..0000000000
--- a/versions-maven-plugin/src/it/it-display-dependency-updates-009-processDependencyManagementTransitive-false/invoker.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-invoker.goals=${project.groupId}:${project.artifactId}:${project.version}:display-dependency-updates
-invoker.mavenOpts=-DprocessDependencyManagementTransitive=false
diff --git a/versions-maven-plugin/src/it/it-display-dependency-updates-009-processDependencyManagementTransitive-false/verify.bsh b/versions-maven-plugin/src/it/it-display-dependency-updates-009-processDependencyManagementTransitive-false/verify.bsh
deleted file mode 100644
index c44a94c018..0000000000
--- a/versions-maven-plugin/src/it/it-display-dependency-updates-009-processDependencyManagementTransitive-false/verify.bsh
+++ /dev/null
@@ -1,45 +0,0 @@
-import java.io.*;
-import org.codehaus.plexus.util.FileUtils;
-import java.util.regex.*;
-
-try
-{
- File file = new File( basedir, "build.log" );
- String buf = FileUtils.fileRead( file );
-
- Pattern p;
- Matcher m;
-
- p = Pattern.compile( "\\Qlocalhost:dummy-api\\E\\s*\\.*\\s*1\\.1\\s+->\\s+3\\.0" );
- m = p.matcher( buf.toString() );
- if ( !m.find() )
- {
- System.out.println( "Did not suggest updating dummy-api to version 3.0" );
- return false;
- }
- System.out.println( m.group( 0 ) );
-
- p = Pattern.compile( "\\Qlocalhost:dummy-impl\\E\\s*\\.*\\s*1\\.2\\s+->\\s+2\\.2" );
- m = p.matcher( buf.toString() );
- if ( m.find() )
- {
- System.out.println( "Did suggest updating dummy-impl to version 2.2" );
- return false;
- }
-
- p = Pattern.compile( "\\Qlocalhost:dummy-api-impl-bom-pom\\E\\s*\\.*\\s*1\\.0\\s+->\\s+2\\.0" );
- m = p.matcher( buf.toString() );
- if ( !m.find() )
- {
- System.out.println( "Did not suggest updating dummy-api-impl-bom-pom to version 2.0" );
- return false;
- }
- System.out.println( m.group( 0 ) );
-}
-catch( Throwable t )
-{
- t.printStackTrace();
- return false;
-}
-
-return true;
diff --git a/versions-maven-plugin/src/it/it-display-dependency-updates-009-processDependencyManagementTransitive-true/invoker.properties b/versions-maven-plugin/src/it/it-display-dependency-updates-009-processDependencyManagementTransitive-true/invoker.properties
deleted file mode 100644
index fa969d852b..0000000000
--- a/versions-maven-plugin/src/it/it-display-dependency-updates-009-processDependencyManagementTransitive-true/invoker.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-invoker.goals=${project.groupId}:${project.artifactId}:${project.version}:display-dependency-updates
-invoker.mavenOpts=-DprocessDependencyManagementTransitive=true
diff --git a/versions-maven-plugin/src/it/it-display-dependency-updates-009-processDependencyManagementTransitive-true/pom.xml b/versions-maven-plugin/src/it/it-display-dependency-updates-009-processDependencyManagementTransitive-true/pom.xml
deleted file mode 100644
index d22ccbd936..0000000000
--- a/versions-maven-plugin/src/it/it-display-dependency-updates-009-processDependencyManagementTransitive-true/pom.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-
- 4.0.0
- localhost
- it-display-dependency-updates-001
- 1.0
- pom
- display-dependency-updates
- http://localhost/
-
-
- localhost
- dummy-api
-
-
-
-
-
- localhost
- dummy-api-impl-bom-pom
- 1.0
- pom
- import
-
-
-
-
-
-
-
- localhost
- dummy-maven-plugin
- 1.0
-
-
- maven-clean-plugin
- 2.2
-
-
- maven-deploy-plugin
- 2.3
-
-
- maven-install-plugin
- 2.2
-
-
- maven-site-plugin
- 2.0
-
-
- maven-project-info-reports-plugin
- 2.1
-
-
-
-
-
diff --git a/versions-maven-plugin/src/it/it-display-dependency-updates-009-processDependencyManagementTransitive-true/verify.bsh b/versions-maven-plugin/src/it/it-display-dependency-updates-009-processDependencyManagementTransitive-true/verify.bsh
deleted file mode 100644
index 7aaf3d73b7..0000000000
--- a/versions-maven-plugin/src/it/it-display-dependency-updates-009-processDependencyManagementTransitive-true/verify.bsh
+++ /dev/null
@@ -1,45 +0,0 @@
-import java.io.*;
-import org.codehaus.plexus.util.FileUtils;
-import java.util.regex.*;
-
-try
-{
- File file = new File( basedir, "build.log" );
- String buf = FileUtils.fileRead( file );
-
- Pattern p;
- Matcher m;
-
- p = Pattern.compile( "\\Qlocalhost:dummy-api\\E\\s*\\.*\\s*1\\.1\\s+->\\s+3\\.0" );
- m = p.matcher( buf.toString() );
- if ( !m.find() )
- {
- System.out.println( "Did not suggest updating dummy-api to version 3.0" );
- return false;
- }
- System.out.println( m.group( 0 ) );
-
- p = Pattern.compile( "\\Qlocalhost:dummy-impl\\E\\s*\\.*\\s*1\\.2\\s+->\\s+2\\.2" );
- m = p.matcher( buf.toString() );
- if ( !m.find() )
- {
- System.out.println( "Did not suggest updating dummy-impl to version 2.2" );
- return false;
- }
- System.out.println( m.group( 0 ) );
-
- p = Pattern.compile( "\\Qlocalhost:dummy-api-impl-bom-pom\\E\\s*\\.*\\s*1\\.0\\s+->\\s+2\\.0" );
- m = p.matcher( buf.toString() );
- if ( m.find() )
- {
- System.out.println( "Did suggest updating dummy-api-impl-bom-pom to version 2.0" );
- return false;
- }
-}
-catch( Throwable t )
-{
- t.printStackTrace();
- return false;
-}
-
-return true;
diff --git a/versions-maven-plugin/src/it/it-display-dependency-updates-009/invoker.properties b/versions-maven-plugin/src/it/it-display-dependency-updates-009/invoker.properties
new file mode 100644
index 0000000000..626c84fe07
--- /dev/null
+++ b/versions-maven-plugin/src/it/it-display-dependency-updates-009/invoker.properties
@@ -0,0 +1,8 @@
+invoker.goals.1=${project.groupId}:${project.artifactId}:${project.version}:display-dependency-updates
+invoker.mavenOpts.1=-DprocessDependencyManagementTransitive=false -Dversions.outputFile=./output.1.txt -DoutputEncoding=UTF-8
+
+invoker.goals.2=${project.groupId}:${project.artifactId}:${project.version}:display-dependency-updates
+invoker.mavenOpts.2=-DprocessDependencyManagementTransitive=true -Dversions.outputFile=./output.2.txt -DoutputEncoding=UTF-8
+
+invoker.goals.3=${project.groupId}:${project.artifactId}:${project.version}:display-dependency-updates
+invoker.mavenOpts.3=-DprocessDependencyManagementTransitive=true -Dverbose=true -Dversions.outputFile=./output.3.txt -DoutputEncoding=UTF-8
diff --git a/versions-maven-plugin/src/it/it-display-dependency-updates-009-processDependencyManagementTransitive-false/pom.xml b/versions-maven-plugin/src/it/it-display-dependency-updates-009/pom.xml
similarity index 100%
rename from versions-maven-plugin/src/it/it-display-dependency-updates-009-processDependencyManagementTransitive-false/pom.xml
rename to versions-maven-plugin/src/it/it-display-dependency-updates-009/pom.xml
diff --git a/versions-maven-plugin/src/it/it-display-dependency-updates-009/verify.groovy b/versions-maven-plugin/src/it/it-display-dependency-updates-009/verify.groovy
new file mode 100644
index 0000000000..3de8ff8777
--- /dev/null
+++ b/versions-maven-plugin/src/it/it-display-dependency-updates-009/verify.groovy
@@ -0,0 +1,13 @@
+def output = (1..3).collect{new File( basedir, "output." + it + ".txt").text.replaceAll( "(\n|\r)", " " ) }
+
+assert output[0] =~ /localhost:dummy-api \.* 1.1 -> 3.0/
+assert !(output[0] =~ /localhost:dummy-impl \.* 1.2 -> 2.2/)
+assert output[0] =~ /localhost:dummy-api-impl-bom-pom \.* 1.0 -> 2.0/
+
+assert output[1] =~ /localhost:dummy-api \.* 1.1 -> 3.0/
+assert output[1] =~ /localhost:dummy-impl \.* 1.2 -> 2.2/
+assert !(output[1] =~ /localhost:dummy-api-impl-bom-pom \.* 1.0 -> 2.0/)
+
+assert output[2] =~ /localhost:dummy-api.*\b1.1\b.*\Q(managed by localhost:dummy-api-impl-bom-pom:1.0)\E.*\b3.0\b/
+assert output[2] =~ /localhost:dummy-impl.*\b1.2\b.*\Q(managed by localhost:dummy-api-impl-bom-pom:1.0)\E.*\b2.2\b/
+assert !(output[2] =~ /localhost:dummy-api-impl-bom-pom \.* 1.0 -> 2.0/)
diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojo.java
index 28cb6e85ad..ecf370aa56 100644
--- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojo.java
+++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojo.java
@@ -50,6 +50,8 @@
import static java.util.Collections.emptySet;
import static org.codehaus.mojo.versions.filtering.DependencyFilter.filterDependencies;
+import static org.codehaus.mojo.versions.utils.DependencyBuilder.Location.ARTIFACT_ID;
+import static org.codehaus.mojo.versions.utils.DependencyBuilder.Location.VERSION;
import static org.codehaus.mojo.versions.utils.MavenProjectUtils.extractDependenciesFromDependencyManagement;
import static org.codehaus.mojo.versions.utils.MavenProjectUtils.extractDependenciesFromPlugins;
import static org.codehaus.mojo.versions.utils.MavenProjectUtils.extractPluginDependenciesFromPluginsInPluginManagement;
@@ -73,7 +75,7 @@ public class DisplayDependencyUpdatesMojo extends AbstractVersionsDisplayMojo {
* @since 1.2
*/
@Parameter(property = "processDependencyManagement", defaultValue = "true")
- private boolean processDependencyManagement;
+ protected boolean processDependencyManagement = true;
/**
* Whether to process the dependencyManagement part transitive or not.
@@ -86,13 +88,23 @@ public class DisplayDependencyUpdatesMojo extends AbstractVersionsDisplayMojo {
* @since 2.11
*/
@Parameter(property = "processDependencyManagementTransitive", defaultValue = "true")
- private boolean processDependencyManagementTransitive;
+ protected boolean processDependencyManagementTransitive = true;
+
+ /**
+ * Include dependencies with version set in a parent or in a BOM.
+ * This is similar to {@code processDependencyManagementTransitive}, but will
+ * report updates on dependencies.
+ * Default is {@code false}.
+ *
+ * @since 2.18.1
+ */
+ @Parameter(property = "showVersionless", defaultValue = "true")
+ protected boolean showVersionless = true;
/**
* Only take these artifacts into consideration.
*
* Comma-separated list of extended GAV patterns.
- *
*
* Extended GAV: groupId:artifactId:version:type:classifier:scope
*
@@ -100,7 +112,6 @@ public class DisplayDependencyUpdatesMojo extends AbstractVersionsDisplayMojo {
* The wildcard "*" can be used as the only, first, last or both characters in each token.
* The version token does support version ranges.
*
- *
*
* Example: {@code "mygroup:artifact:*,*:*:*:*:*:compile"}
*
@@ -114,7 +125,6 @@ public class DisplayDependencyUpdatesMojo extends AbstractVersionsDisplayMojo {
* Exclude these artifacts from consideration.
*
* Comma-separated list of extended GAV patterns.
- *
*
* Extended GAV: groupId:artifactId:version:type:classifier:scope
*
@@ -122,7 +132,6 @@ public class DisplayDependencyUpdatesMojo extends AbstractVersionsDisplayMojo {
* The wildcard "*" can be used as the only, first, last or both characters in each token.
* The version token does support version ranges.
*
- *
*
* Example: {@code "mygroup:artifact:*,*:*:*:*:*:provided,*:*:*:*:*:system"}
*
@@ -138,7 +147,7 @@ public class DisplayDependencyUpdatesMojo extends AbstractVersionsDisplayMojo {
* @since 1.2
*/
@Parameter(property = "processDependencies", defaultValue = "true")
- private boolean processDependencies;
+ protected boolean processDependencies;
/**
* Only take the specified input dependencies into account.
@@ -146,7 +155,6 @@ public class DisplayDependencyUpdatesMojo extends AbstractVersionsDisplayMojo {
* To filter output versions, please use {@link #ruleSet} or {@link #ignoredVersions}.
*
* Comma-separated list of extended GAV patterns.
- *
*
* Extended GAV: groupId:artifactId:version:type:classifier:scope
*
@@ -154,7 +162,6 @@ public class DisplayDependencyUpdatesMojo extends AbstractVersionsDisplayMojo {
* The wildcard "*" can be used as the only, first, last or both characters in each token.
* The version token does support version ranges.
*
- *
*
* Example: {@code "mygroup:artifact:*,*:*:*:*:*:compile"}
*
@@ -162,7 +169,7 @@ public class DisplayDependencyUpdatesMojo extends AbstractVersionsDisplayMojo {
* @since 2.12.0
*/
@Parameter(property = "dependencyIncludes", defaultValue = WildcardMatcher.WILDCARD)
- private List dependencyIncludes;
+ protected List dependencyIncludes;
/**
* Do not take the specified input dependencies into account.
@@ -170,7 +177,6 @@ public class DisplayDependencyUpdatesMojo extends AbstractVersionsDisplayMojo {
* To filter output versions, please use {@link #ruleSet} or {@link #ignoredVersions}.
*
* Comma-separated list of extended GAV patterns.
- *
*
* Extended GAV: groupId:artifactId:version:type:classifier:scope
*
@@ -178,7 +184,6 @@ public class DisplayDependencyUpdatesMojo extends AbstractVersionsDisplayMojo {
* The wildcaNote:rd "*" can be used as the only, first, last or both characters in each token.
* The version token does support version ranges.
*
- *
*
* Example: {@code "mygroup:artifact:*,*:*:*:*:*:provided,*:*:*:*:*:system"}
*
@@ -186,7 +191,7 @@ public class DisplayDependencyUpdatesMojo extends AbstractVersionsDisplayMojo {
* @since 2.12.0
*/
@Parameter(property = "dependencyExcludes")
- private List dependencyExcludes;
+ protected List dependencyExcludes;
/**
* Whether to process the dependencies sections of plugins.
@@ -210,17 +215,16 @@ public class DisplayDependencyUpdatesMojo extends AbstractVersionsDisplayMojo {
* @since 2.5
*/
@Parameter(property = "allowMajorUpdates", defaultValue = "true")
- private boolean allowMajorUpdates = true;
+ protected boolean allowMajorUpdates = true;
/**
* Whether to allow the minor version number to be changed.
- *
* Note: {@code false} also implies {@linkplain #allowMajorUpdates} to be {@code false}
*
* @since 2.5
*/
@Parameter(property = "allowMinorUpdates", defaultValue = "true")
- private boolean allowMinorUpdates = true;
+ protected boolean allowMinorUpdates = true;
/**
* Whether to allow the incremental version number to be changed.
@@ -231,25 +235,25 @@ public class DisplayDependencyUpdatesMojo extends AbstractVersionsDisplayMojo {
* @since 2.5
*/
@Parameter(property = "allowIncrementalUpdates", defaultValue = "true")
- private boolean allowIncrementalUpdates = true;
+ protected boolean allowIncrementalUpdates = true;
/**
- * Whether to show additional information such as dependencies that do not need updating. Defaults to false.
+ * If {@code true}, shows dependencies that do not have updates. Also, with dependencies with
+ * versions managed outside the reactor, will show the location of the pom.xml managing the version.
+ * Default is {@code false}.
*
* @since 2.1
*/
@Parameter(property = "verbose", defaultValue = "false")
- private boolean verbose;
+ protected boolean verbose;
/**
* Only take these artifacts into consideration:
* Comma-separated list of {@code groupId:[artifactId[:version]]} patterns
- *
*
* The wildcard "*" can be used as the only, first, last or both characters in each token.
* The version token does support version ranges.
*
- *
*
* Example: {@code "mygroup:artifact:*,othergroup:*,anothergroup"}
*
@@ -262,12 +266,10 @@ public class DisplayDependencyUpdatesMojo extends AbstractVersionsDisplayMojo {
/**
* Exclude these artifacts into consideration:
* Comma-separated list of {@code groupId:[artifactId[:version]]} patterns
- *
*
* The wildcard "*" can be used as the only, first, last or both characters in each token.
* The version token does support version ranges.
*
- *
*
* Example: {@code "mygroup:artifact:*,othergroup:*,anothergroup"}
*
@@ -284,7 +286,6 @@ public class DisplayDependencyUpdatesMojo extends AbstractVersionsDisplayMojo {
* The wildcard "*" can be used as the only, first, last or both characters in each token.
* The version token does support version ranges.
*
- *
*
* Example: {@code "mygroup:artifact:*,othergroup:*,anothergroup"}
*
@@ -297,12 +298,10 @@ public class DisplayDependencyUpdatesMojo extends AbstractVersionsDisplayMojo {
/**
* Exclude these artifacts into consideration:
* Comma-separated list of {@code groupId:[artifactId[:version]]} patterns
- *
*
* The wildcard "*" can be used as the only, first, last or both characters in each token.
* The version token does support version ranges.
*
- *
*
* Example: {@code "mygroup:artifact:*,othergroup:*,anothergroup"}
*
@@ -372,6 +371,14 @@ public boolean isVerbose() {
// --------------------- Interface Mojo ---------------------
+ /**
+ * @return {@code true} if the version of the dependency is definned locally in the same project
+ */
+ private static boolean dependencyVersionLocalToReactor(Dependency dependency) {
+ return dependency.getLocation(VERSION.toString()).getSource()
+ == dependency.getLocation(ARTIFACT_ID.toString()).getSource();
+ }
+
/**
* @throws org.apache.maven.plugin.MojoExecutionException when things go wrong
* @throws org.apache.maven.plugin.MojoFailureException when things go wrong in a very bad way
@@ -413,6 +420,8 @@ public void execute() throws MojoExecutionException, MojoFailureException {
.filter(dep -> finalDependencyManagement.stream()
.noneMatch(depMan ->
dependenciesMatch(dep, depMan)))
+ .filter(dep -> showVersionless
+ || dependencyVersionLocalToReactor(dep))
.collect(
() -> new TreeSet<>(
DependencyComparator.INSTANCE),
@@ -480,6 +489,7 @@ protected void validateInput() throws MojoExecutionException {
/**
* Validates a list of GAV strings
+ *
* @param gavList list of the input GAV strings
* @param numSections number of sections in the GAV to verify against
* @param argumentName argument name to indicate in the exception
@@ -496,7 +506,12 @@ private void logUpdates(Map versionMap, String sec
Optional unchangedSegment = SegmentUtils.determineUnchangedSegment(
allowMajorUpdates, allowMinorUpdates, allowIncrementalUpdates, getLog());
DependencyUpdatesResult updates = DependencyUpdatesLoggingHelper.getDependencyUpdates(
- versionMap, allowSnapshots, unchangedSegment, INFO_PAD_SIZE + getOutputLineWidthOffset());
+ getProject(),
+ versionMap,
+ allowSnapshots,
+ unchangedSegment,
+ INFO_PAD_SIZE + getOutputLineWidthOffset(),
+ verbose);
if (isVerbose()) {
if (updates.getUsingLatest().isEmpty()) {
diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayExtensionUpdatesMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayExtensionUpdatesMojo.java
index 3beffc112d..16ecde5318 100644
--- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayExtensionUpdatesMojo.java
+++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayExtensionUpdatesMojo.java
@@ -202,7 +202,12 @@ private void logUpdates(Map versionMap) {
allowMajorUpdates, allowMinorUpdates, allowIncrementalUpdates, getLog());
DependencyUpdatesLoggingHelper.DependencyUpdatesResult updates =
DependencyUpdatesLoggingHelper.getDependencyUpdates(
- versionMap, allowSnapshots, unchangedSegment, INFO_PAD_SIZE + getOutputLineWidthOffset());
+ getProject(),
+ versionMap,
+ allowSnapshots,
+ unchangedSegment,
+ INFO_PAD_SIZE + getOutputLineWidthOffset(),
+ verbose);
if (verbose) {
if (updates.getUsingLatest().isEmpty()) {
diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/internal/DependencyUpdatesLoggingHelper.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/internal/DependencyUpdatesLoggingHelper.java
index 96eb2acb08..086d90f884 100644
--- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/internal/DependencyUpdatesLoggingHelper.java
+++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/internal/DependencyUpdatesLoggingHelper.java
@@ -10,6 +10,7 @@
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.Restriction;
import org.apache.maven.model.Dependency;
+import org.apache.maven.project.MavenProject;
import org.codehaus.mojo.versions.DisplayDependencyUpdatesMojo;
import org.codehaus.mojo.versions.DisplayExtensionUpdatesMojo;
import org.codehaus.mojo.versions.api.ArtifactVersions;
@@ -17,6 +18,7 @@
import org.codehaus.mojo.versions.ordering.InvalidSegmentException;
import static java.util.Optional.empty;
+import static org.codehaus.mojo.versions.utils.DependencyBuilder.Location.VERSION;
/**
* Helper class for {@link DisplayDependencyUpdatesMojo} and {@link DisplayExtensionUpdatesMojo},
@@ -24,29 +26,53 @@
*/
public class DependencyUpdatesLoggingHelper {
+ /**
+ * @return {@code true} if the version of the dependency is in the project
+ */
+ private static boolean dependencyVersionLocalToProject(MavenProject project, Dependency dependency) {
+ return dependency
+ .getLocation(VERSION.toString())
+ .getSource()
+ .getModelId()
+ .equals(project.getGroupId() + ":" + project.getArtifactId() + ":" + project.getVersion());
+ }
+
/**
* Compiles a {@link DependencyUpdatesResult} object containing dependency updates for the given dependency map
* and the given unchanged segment.
+ * @param project a {@link MavenProject} object
* @param updates map of available versions per dependency
* @param allowSnapshots whether snapshots should be allowed as updates
* @param unchangedSegment the most major segment not allowed to be updated or {@code Optional.empty()} if
* all segments are allowed to be updated
* @param maxLineWith maximum line width
+ * @param displayManagedBy if {@code true}, will display information on the pom managing the given dependency
+ * for dependencies not managed by the current project
* @return a {@link DependencyUpdatesResult} object containing the result
*/
public static DependencyUpdatesResult getDependencyUpdates(
+ MavenProject project,
Map updates,
boolean allowSnapshots,
Optional unchangedSegment,
- int maxLineWith) {
+ int maxLineWith,
+ boolean displayManagedBy) {
List withUpdates = new ArrayList<>();
List usingCurrent = new ArrayList<>();
- for (ArtifactVersions versions : updates.values()) {
+ for (Map.Entry entry : updates.entrySet()) {
+ Dependency dep = entry.getKey();
+ ArtifactVersions versions = entry.getValue();
String left = " " + ArtifactUtils.versionlessKey(versions.getArtifact()) + " ";
String currentVersion;
Optional latestVersion;
if (versions.getCurrentVersion() != null) {
- currentVersion = versions.getCurrentVersion().toString();
+ currentVersion = versions.getCurrentVersion()
+ + (!displayManagedBy || dependencyVersionLocalToProject(project, dep)
+ ? ""
+ : " (managed by "
+ + dep.getLocation(VERSION.toString())
+ .getSource()
+ .getModelId() + ")");
try {
latestVersion = versions.getNewestVersion(currentVersion, unchangedSegment, allowSnapshots, false);
} catch (InvalidSegmentException e) {
diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojoTest.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojoTest.java
index 04b9f3aebe..8c275ff088 100644
--- a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojoTest.java
+++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojoTest.java
@@ -16,11 +16,14 @@
*/
import java.io.File;
+import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
+import org.apache.maven.model.InputLocation;
+import org.apache.maven.model.InputSource;
import org.apache.maven.model.Model;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.testing.AbstractMojoTestCase;
@@ -47,6 +50,7 @@
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
@@ -120,10 +124,13 @@ private MavenProject createProject() {
setArtifactId("default-artifact");
setVersion("1.0.0-SNAPSHOT");
+ InputLocation fakeLocation = new InputLocation(-1, -1, new InputSource());
setDependencies(singletonList(DependencyBuilder.newBuilder()
.withGroupId("default-group")
.withArtifactId("default-dependency")
.withVersion("1.0.0")
+ .withLocation(DependencyBuilder.Location.ARTIFACT_ID.toString(), fakeLocation)
+ .withLocation(DependencyBuilder.Location.VERSION.toString(), fakeLocation)
.build()));
}
}) {
@@ -149,12 +156,13 @@ public void testVersionsWithQualifiersNotConsideredAsMinorUpdates() throws Excep
null) {
{
setProject(createProject());
- setVariableValueToObject(this, "allowMajorUpdates", false);
- setVariableValueToObject(this, "processDependencies", true);
- setVariableValueToObject(this, "dependencyIncludes", singletonList(WildcardMatcher.WILDCARD));
- setVariableValueToObject(this, "dependencyExcludes", emptyList());
- this.allowSnapshots = true;
- this.outputFile = tempFile.getPath().toFile();
+ allowMajorUpdates = false;
+ processDependencies = true;
+ processDependencyManagement = false;
+ dependencyIncludes = singletonList(WildcardMatcher.WILDCARD);
+ dependencyExcludes = emptyList();
+ allowSnapshots = true;
+ outputFile = tempFile.getPath().toFile();
setPluginContext(new HashMap<>());
session = mockMavenSession();
@@ -184,11 +192,12 @@ public void testAllowMajorUpdatesFalse() throws Exception {
null) {
{
setProject(createProject());
- setVariableValueToObject(this, "allowMajorUpdates", false);
- setVariableValueToObject(this, "processDependencies", true);
- setVariableValueToObject(this, "dependencyIncludes", singletonList(WildcardMatcher.WILDCARD));
- setVariableValueToObject(this, "dependencyExcludes", emptyList());
- this.outputFile = tempFile.getPath().toFile();
+ allowMajorUpdates = false;
+ processDependencies = true;
+ processDependencyManagement = false;
+ dependencyIncludes = singletonList(WildcardMatcher.WILDCARD);
+ dependencyExcludes = emptyList();
+ outputFile = tempFile.getPath().toFile();
setPluginContext(new HashMap<>());
session = mockMavenSession();
@@ -216,11 +225,12 @@ public void testAllowMinorUpdatesFalse() throws Exception {
null) {
{
setProject(createProject());
- setVariableValueToObject(this, "allowMinorUpdates", false);
- setVariableValueToObject(this, "processDependencies", true);
- setVariableValueToObject(this, "dependencyIncludes", singletonList(WildcardMatcher.WILDCARD));
- setVariableValueToObject(this, "dependencyExcludes", emptyList());
- this.outputFile = tempFile.getPath().toFile();
+ allowMinorUpdates = false;
+ processDependencies = true;
+ processDependencyManagement = false;
+ dependencyIncludes = singletonList(WildcardMatcher.WILDCARD);
+ dependencyExcludes = emptyList();
+ outputFile = tempFile.getPath().toFile();
setPluginContext(new HashMap<>());
session = mockMavenSession();
@@ -249,11 +259,12 @@ public void testAllowIncrementalUpdatesFalse() throws Exception {
null) {
{
setProject(createProject());
- setVariableValueToObject(this, "allowIncrementalUpdates", false);
- setVariableValueToObject(this, "processDependencies", true);
- setVariableValueToObject(this, "dependencyIncludes", singletonList(WildcardMatcher.WILDCARD));
- setVariableValueToObject(this, "dependencyExcludes", emptyList());
- this.outputFile = tempFile.getPath().toFile();
+ allowIncrementalUpdates = false;
+ processDependencies = true;
+ processDependencyManagement = false;
+ dependencyIncludes = singletonList(WildcardMatcher.WILDCARD);
+ dependencyExcludes = emptyList();
+ outputFile = tempFile.getPath().toFile();
setPluginContext(new HashMap<>());
session = mockMavenSession();
@@ -285,12 +296,13 @@ public void testVersionsWithQualifiersNotConsideredAsIncrementalUpdates() throws
null) {
{
setProject(createProject());
- setVariableValueToObject(this, "allowMinorUpdates", false);
- setVariableValueToObject(this, "processDependencies", true);
- setVariableValueToObject(this, "dependencyIncludes", singletonList(WildcardMatcher.WILDCARD));
- setVariableValueToObject(this, "dependencyExcludes", emptyList());
- this.allowSnapshots = true;
- this.outputFile = tempFile.getPath().toFile();
+ allowMinorUpdates = false;
+ processDependencies = true;
+ processDependencyManagement = false;
+ dependencyIncludes = singletonList(WildcardMatcher.WILDCARD);
+ dependencyExcludes = emptyList();
+ allowSnapshots = true;
+ outputFile = tempFile.getPath().toFile();
setPluginContext(new HashMap<>());
session = mockMavenSession();
@@ -360,7 +372,7 @@ public void testVersionInterpolation() throws Exception {
put("dummy-api", new String[] {"2.0.1"});
}
});
- setVariableValueToObject(mojo, "processDependencyManagementTransitive", false);
+ mojo.processDependencyManagementTransitive = false;
mojo.execute();
List output = Files.readAllLines(tempFile.getPath(), UTF_8);
assertThat(output, not(hasItem(containsString("mycomponent.version"))));
@@ -381,11 +393,12 @@ public void testAllowSnapshots() throws Exception {
null) {
{
setProject(createProject());
- setVariableValueToObject(this, "processDependencies", true);
- setVariableValueToObject(this, "dependencyIncludes", singletonList(WildcardMatcher.WILDCARD));
- setVariableValueToObject(this, "dependencyExcludes", emptyList());
- this.allowSnapshots = true;
- this.outputFile = tempFile.getPath().toFile();
+ processDependencies = true;
+ processDependencyManagement = false;
+ dependencyIncludes = singletonList(WildcardMatcher.WILDCARD);
+ dependencyExcludes = emptyList();
+ allowSnapshots = true;
+ outputFile = tempFile.getPath().toFile();
setPluginContext(new HashMap<>());
session = mockMavenSession();
@@ -411,11 +424,12 @@ private void testAllowUpdatesFromLesserSegments(String availableVersion) throws
null) {
{
setProject(createProject());
- setVariableValueToObject(this, "processDependencies", true);
- setVariableValueToObject(this, "dependencyIncludes", singletonList(WildcardMatcher.WILDCARD));
- setVariableValueToObject(this, "dependencyExcludes", emptyList());
- setVariableValueToObject(this, "allowMajorUpdates", false);
- this.outputFile = tempFile.getPath().toFile();
+ processDependencies = true;
+ processDependencyManagement = false;
+ dependencyIncludes = singletonList(WildcardMatcher.WILDCARD);
+ dependencyExcludes = emptyList();
+ allowMajorUpdates = false;
+ outputFile = tempFile.getPath().toFile();
setPluginContext(new HashMap<>());
session = mockMavenSession();
@@ -442,4 +456,86 @@ public void testAllowUpdatesFromLesserSegmentsIncremental() throws Exception {
public void testAllowUpdatesFromLesserSegmentsSubIncremental() throws Exception {
testAllowUpdatesFromLesserSegments("1.0.0-1");
}
+
+ /*
+ * A dependency version is managed by a parent from outside the reactor; with showVersionsless false the output
+ * should not be generated at all.
+ */
+ @Test
+ public void testShowVersionlessFalse() throws Exception {
+ try (CloseableTempFile tempFile = new CloseableTempFile("display-dependency-updates")) {
+ DisplayDependencyUpdatesMojo mojo = (DisplayDependencyUpdatesMojo) mojoRule.lookupConfiguredMojo(
+ new File("target/test-classes/org/codehaus/mojo/display-dependency-updates/"
+ + "version-from-parent/child"),
+ "display-dependency-updates");
+ mojo.setPluginContext(new HashMap<>());
+ mojo.showVersionless = false;
+ mojo.processDependencyManagement = false;
+ mojo.outputFile = tempFile.getPath().toFile();
+ mojo.outputEncoding = Charset.defaultCharset().toString();
+ mojo.repositorySystem = mockAetherRepositorySystem(new HashMap() {
+ {
+ put("dummy-api", new String[] {"1.0.0", "2.0.0"});
+ }
+ });
+ mojo.execute();
+ assertThat(Files.exists(tempFile.getPath()), is(false));
+ }
+ }
+
+ /*
+ * A dependency version is managed by a parent from outside the reactor; with showVersionsless true
+ * and verbose, the output should contain the location of the versionless dependency.
+ */
+ @Test
+ public void testShowVersionlessVerbose() throws Exception {
+ try (CloseableTempFile tempFile = new CloseableTempFile("display-dependency-updates")) {
+ DisplayDependencyUpdatesMojo mojo = (DisplayDependencyUpdatesMojo) mojoRule.lookupConfiguredMojo(
+ new File("target/test-classes/org/codehaus/mojo/display-dependency-updates/"
+ + "version-from-parent/child"),
+ "display-dependency-updates");
+ mojo.setPluginContext(new HashMap<>());
+ mojo.showVersionless = true;
+ mojo.verbose = true;
+ mojo.processDependencyManagement = false;
+ mojo.outputFile = tempFile.getPath().toFile();
+ mojo.outputEncoding = Charset.defaultCharset().toString();
+ mojo.repositorySystem = mockAetherRepositorySystem(new HashMap() {
+ {
+ put("dummy-api", new String[] {"1.0.0", "2.0.0"});
+ }
+ });
+ mojo.execute();
+
+ String output = String.join("", Files.readAllLines(tempFile.getPath()));
+ assertThat(
+ output, containsString("1.0.0 (managed by default-group:parent-artifact:1.0.0-SNAPSHOT) -> 2.0.0"));
+ }
+ }
+
+ /*
+ * A dependency version is managed by a parent from outside the reactor; with showVersionsless false the output
+ * should be generated and should contain the transitive dependency
+ */
+ @Test
+ public void testShowVersionlessFalseDependencyManagementTransitive() throws Exception {
+ try (CloseableTempFile tempFile = new CloseableTempFile("display-dependency-updates")) {
+ DisplayDependencyUpdatesMojo mojo = (DisplayDependencyUpdatesMojo) mojoRule.lookupConfiguredMojo(
+ new File("target/test-classes/org/codehaus/mojo/display-dependency-updates/"
+ + "dependency-management-from-parent/child"),
+ "display-dependency-updates");
+ mojo.setPluginContext(new HashMap<>());
+ mojo.showVersionless = false;
+ mojo.outputFile = tempFile.getPath().toFile();
+ mojo.outputEncoding = Charset.defaultCharset().toString();
+ mojo.repositorySystem = mockAetherRepositorySystem(new HashMap() {
+ {
+ put("dummy-api", new String[] {"1.0.0", "2.0.0"});
+ }
+ });
+ mojo.execute();
+ String output = String.join("", Files.readAllLines(tempFile.getPath()));
+ assertThat(output, containsString("1.0.0 -> 2.0.0"));
+ }
+ }
}
diff --git a/versions-maven-plugin/src/test/resources/org/codehaus/mojo/display-dependency-updates/dependency-management-from-parent/child/pom.xml b/versions-maven-plugin/src/test/resources/org/codehaus/mojo/display-dependency-updates/dependency-management-from-parent/child/pom.xml
new file mode 100644
index 0000000000..544da936f8
--- /dev/null
+++ b/versions-maven-plugin/src/test/resources/org/codehaus/mojo/display-dependency-updates/dependency-management-from-parent/child/pom.xml
@@ -0,0 +1,33 @@
+
+
+
+ 4.0.0
+
+
+ default-group
+ parent-artifact
+ 1.0.0-SNAPSHOT
+
+
+ child-artifact
+ 1.0.0-SNAPSHOT
+
+
diff --git a/versions-maven-plugin/src/test/resources/org/codehaus/mojo/display-dependency-updates/dependency-management-from-parent/pom.xml b/versions-maven-plugin/src/test/resources/org/codehaus/mojo/display-dependency-updates/dependency-management-from-parent/pom.xml
new file mode 100644
index 0000000000..b0ee19c5dd
--- /dev/null
+++ b/versions-maven-plugin/src/test/resources/org/codehaus/mojo/display-dependency-updates/dependency-management-from-parent/pom.xml
@@ -0,0 +1,37 @@
+
+
+
+ 4.0.0
+ default-group
+ parent-artifact
+ 1.0.0-SNAPSHOT
+ pom
+
+
+
+
+ localhost
+ dummy-api
+ 1.0.0
+
+
+
+
diff --git a/versions-maven-plugin/src/test/resources/org/codehaus/mojo/display-dependency-updates/version-from-parent/child/pom.xml b/versions-maven-plugin/src/test/resources/org/codehaus/mojo/display-dependency-updates/version-from-parent/child/pom.xml
new file mode 100644
index 0000000000..68656428cc
--- /dev/null
+++ b/versions-maven-plugin/src/test/resources/org/codehaus/mojo/display-dependency-updates/version-from-parent/child/pom.xml
@@ -0,0 +1,40 @@
+
+
+
+ 4.0.0
+
+
+ default-group
+ parent-artifact
+ 1.0.0-SNAPSHOT
+
+
+ child-artifact
+ 1.0.0-SNAPSHOT
+
+
+
+ localhost
+ dummy-api
+
+
+
+
diff --git a/versions-maven-plugin/src/test/resources/org/codehaus/mojo/display-dependency-updates/version-from-parent/pom.xml b/versions-maven-plugin/src/test/resources/org/codehaus/mojo/display-dependency-updates/version-from-parent/pom.xml
new file mode 100644
index 0000000000..b0ee19c5dd
--- /dev/null
+++ b/versions-maven-plugin/src/test/resources/org/codehaus/mojo/display-dependency-updates/version-from-parent/pom.xml
@@ -0,0 +1,37 @@
+
+
+
+ 4.0.0
+ default-group
+ parent-artifact
+ 1.0.0-SNAPSHOT
+ pom
+
+
+
+
+ localhost
+ dummy-api
+ 1.0.0
+
+
+
+