From 88cfe8d35ba9afff7871f5ee810b68adc30a0d5e Mon Sep 17 00:00:00 2001 From: Martin Chalupa Date: Tue, 14 Jan 2020 10:43:22 -0800 Subject: [PATCH] When version is found through recursion find also reasons of recommendation --- .../DependencyRecommendationsPlugin.java | 22 ++++++-- ...commendationsPluginMultiprojectSpec.groovy | 53 +++++++++++++++++++ 2 files changed, 71 insertions(+), 4 deletions(-) diff --git a/src/main/groovy/netflix/nebula/dependency/recommender/DependencyRecommendationsPlugin.java b/src/main/groovy/netflix/nebula/dependency/recommender/DependencyRecommendationsPlugin.java index 3b7ca5e..1852bc0 100644 --- a/src/main/groovy/netflix/nebula/dependency/recommender/DependencyRecommendationsPlugin.java +++ b/src/main/groovy/netflix/nebula/dependency/recommender/DependencyRecommendationsPlugin.java @@ -40,9 +40,7 @@ import org.gradle.api.plugins.ExtraPropertiesExtension; import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; +import java.util.*; public class DependencyRecommendationsPlugin implements Plugin { public static final String NEBULA_RECOMMENDER_BOM = "nebulaRecommenderBom"; @@ -128,7 +126,7 @@ public void execute(DependencyResolveDetails details) { String strategyText = whichStrategy(strategy); logger.debug("Recommending version " + version + " for dependency " + coordinate); details.because("Recommending version " + version + " for dependency " + coordinate + " via " + strategyText + "\n" + - "\twith reasons: " + StringUtils.join(recommendationProviderContainer.getReasons(), ", ")); + "\twith reasons: " + StringUtils.join(getReasonsRecursive(project), ", ")); } else { if (recommendationProviderContainer.isStrictMode()) { String errorMessage = "Dependency " + details.getRequested().getGroup() + ":" + details.getRequested().getName() + " omitted version with no recommended version. General causes include a dependency being removed from the recommendation source or not applying a recommendation source to a project that depends on another project using a recommender."; @@ -225,4 +223,20 @@ public String getRecommendedVersionRecursive(Project project, ModuleVersionSelec return getRecommendedVersionRecursive(project.getParent(), mvSelector); return null; } + + /** + * Look for recommendation reasons in a project and each of its ancestors in order until one is found or the root is reached + * + * @param project the gradle Project + * @return the recommended version or null + */ + public Set getReasonsRecursive(Project project) { + Set reasons = Objects.requireNonNull(project.getExtensions().findByType(RecommendationProviderContainer.class)) + .getReasons(); + if (! reasons.isEmpty()) + return reasons; + if (project.getParent() != null) + return getReasonsRecursive(project.getParent()); + return Collections.emptySet(); + } } diff --git a/src/test/groovy/netflix/nebula/dependency/recommender/DependencyRecommendationsPluginMultiprojectSpec.groovy b/src/test/groovy/netflix/nebula/dependency/recommender/DependencyRecommendationsPluginMultiprojectSpec.groovy index 2d0fe4a..6457c59 100644 --- a/src/test/groovy/netflix/nebula/dependency/recommender/DependencyRecommendationsPluginMultiprojectSpec.groovy +++ b/src/test/groovy/netflix/nebula/dependency/recommender/DependencyRecommendationsPluginMultiprojectSpec.groovy @@ -176,4 +176,57 @@ class DependencyRecommendationsPluginMultiprojectSpec extends IntegrationSpec { //output where message is printed is different between Gradle 4.7 and 4.8 while we are testing Gradle 4.8 we need to check both results.standardError.contains(expectedMessage) || results.standardOutput.contains(expectedMessage) } + + def 'recommendation is defined in root and we can see proper reasons in submodule dependency insight'() { + def repo = new MavenRepo() + repo.root = new File(projectDir, 'build/bomrepo') + def pom = new Pom('test.nebula.bom', 'multiprojectbom', '1.0.0', ArtifactType.POM) + pom.addManagementDependency('example', 'foo', '1.0.0') + pom.addManagementDependency('example', 'bar', '1.0.0') + repo.poms.add(pom) + repo.generate() + def depGraph = new DependencyGraphBuilder() + .addModule('example:foo:1.0.0') + .addModule('example:bar:1.0.0') + .build() + def generator = new GradleDependencyGenerator(depGraph) + generator.generateTestMavenRepo() + + addSubproject('a', '''\ + apply plugin: 'java' + + dependencies { + implementation 'example:foo' + } + '''.stripIndent()) + + addSubproject('b', '''\ + apply plugin: 'java' + + dependencies { + implementation project(':a') + } + '''.stripIndent()) + + buildFile << """\ + allprojects { + apply plugin: 'nebula.dependency-recommender' + + repositories { + maven { url '${repo.root.absoluteFile.toURI()}' } + ${generator.mavenRepositoryBlock} + } + } + + dependencyRecommendations { + mavenBom module: 'test.nebula.bom:multiprojectbom:1.0.0@pom' + } + """.stripIndent() + when: + def results = runTasksSuccessfully(':a:dependencyInsight', '--dependency', 'foo', '--configuration', 'compileClasspath') + + then: + results.standardOutput.contains 'Recommending version 1.0.0 for dependency example:foo' + results.standardOutput.contains 'nebula.dependency-recommender uses mavenBom: test.nebula.bom:multiprojectbom:pom:1.0.0' + } }