package netflix.nebula.dependency.recommender;

import org.apache.commons.lang.StringUtils;
import org.gradle.api.Action;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.artifacts.*;
import org.gradle.api.plugins.JavaPlugin;

import java.util.ArrayList;
import java.util.List;

public class DependencyRecommendationsPlugin implements Plugin<Project> {
    @Override
    public void apply(final Project project) {
        project.getPlugins().withType(JavaPlugin.class, new Action<JavaPlugin>() {
            @Override
            public void execute(JavaPlugin javaPlugin) {
                project.getExtensions().create("dependencyRecommendations", RecommendationProviderContainer.class, project);
                applyRecommendations();
            }

            public void applyRecommendations() {
                project.getConfigurations().all(new Action<Configuration>() {
                    @Override
                    public void execute(final Configuration conf) {
                        final List<String> firstOrderDepsWithVersions = new ArrayList<>();

                        conf.getIncoming().beforeResolve(new Action<ResolvableDependencies>() {
                            @Override
                            public void execute(ResolvableDependencies resolvableDependencies) {
                                for (Dependency dependency : resolvableDependencies.getDependencies()) {
                                    if(!StringUtils.isBlank(dependency.getVersion()))
                                        firstOrderDepsWithVersions.add(dependency.getGroup() + ":" + dependency.getName());
                                }
                            }
                        });

                        conf.getResolutionStrategy().eachDependency(new Action<DependencyResolveDetails>() {
                            @Override
                            public void execute(DependencyResolveDetails details) {
                                ModuleVersionSelector requested = details.getRequested();
                                String coord = requested.getGroup() + ":" + requested.getName();

                                // don't interfere with the way forces trump everything
                                for (ModuleVersionSelector force : conf.getResolutionStrategy().getForcedModules())
                                    if(requested.getGroup().equals(force.getGroup()) && requested.getName().equals(force.getName())) {
                                        return;
                                    }

                                String version = getRecommendedVersionRecursive(project, requested);
                                if (version != null && !firstOrderDepsWithVersions.contains(coord)) {
                                    details.useVersion(version);
                                }
                                else if (StringUtils.isBlank(requested.getVersion())) {
                                    project.getLogger().error("Unable to provide a recommended version for " + coord);
                                }
                            }
                        });
                    }
                });
            }
        });
    }

    /**
     * Look for recommended versions in a project and each of its ancestors in order until one is found or the root is reached
     * @return the recommended version or <code>null</code>
     */
    protected String getRecommendedVersionRecursive(Project project, ModuleVersionSelector mvSelector) {
        String version = project.getExtensions()
                .getByType(RecommendationProviderContainer.class)
                .getRecommendedVersion(mvSelector.getGroup(), mvSelector.getName());
        if (version != null)
            return version;
        if (project.getParent() != null)
            return getRecommendedVersionRecursive(project.getParent(), mvSelector);
        return null;
    }
}

@@ -437,24 +437,150 @@
  project) %7B%0A
+        project.getExtensions().create(%22dependencyRecommendations%22, RecommendationProviderContainer.class, project);%0A        %0A
         proj
@@ -733,133 +733,8 @@
 ) %7B%0A
-                project.getExtensions().create(%22dependencyRecommendations%22, RecommendationProviderContainer.class, project);%0A
     

Update DependencyRecommendationsPlugin.java