From ff6fc5c17570899d163fba65697eb8ab757848c7 Mon Sep 17 00:00:00 2001 From: Nikita Skvortsov Date: Mon, 7 May 2018 19:34:07 +0300 Subject: [PATCH] extract methods and classes for readability --- .../builder/ExternalProjectBuilderImpl.groovy | 2 +- .../util/resolve/ArtifactQueryResolver.java | 188 +++++++ .../util/resolve/DependencyResolverImpl.java | 156 +----- .../resolve/DependencyResultsTransformer.java | 516 ++++++++++-------- .../resolve/ExternalDepsResolutionResult.java | 8 +- 5 files changed, 497 insertions(+), 373 deletions(-) create mode 100644 plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/util/resolve/ArtifactQueryResolver.java diff --git a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/ExternalProjectBuilderImpl.groovy b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/ExternalProjectBuilderImpl.groovy index a29febb47992..69083a7873c5 100644 --- a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/ExternalProjectBuilderImpl.groovy +++ b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/ExternalProjectBuilderImpl.groovy @@ -39,8 +39,8 @@ import org.jetbrains.plugins.gradle.model.* import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder import org.jetbrains.plugins.gradle.tooling.ModelBuilderService import org.jetbrains.plugins.gradle.tooling.util.ArtifactsCollectionResolver -import org.jetbrains.plugins.gradle.tooling.util.DependencyResolverImpl import org.jetbrains.plugins.gradle.tooling.util.SourceSetCachedFinder +import org.jetbrains.plugins.gradle.tooling.util.resolve.DependencyResolverImpl /** * @author Vladislav.Soroka diff --git a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/util/resolve/ArtifactQueryResolver.java b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/util/resolve/ArtifactQueryResolver.java new file mode 100644 index 000000000000..d275f2d41a28 --- /dev/null +++ b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/util/resolve/ArtifactQueryResolver.java @@ -0,0 +1,188 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package org.jetbrains.plugins.gradle.tooling.util.resolve; + +import org.gradle.api.Project; +import org.gradle.api.artifacts.Configuration; +import org.gradle.api.artifacts.ModuleVersionIdentifier; +import org.gradle.api.artifacts.ProjectDependency; +import org.gradle.api.artifacts.ResolvedArtifact; +import org.gradle.api.artifacts.component.ComponentIdentifier; +import org.gradle.api.artifacts.component.ModuleComponentIdentifier; +import org.gradle.api.artifacts.dsl.DependencyHandler; +import org.gradle.api.artifacts.result.ComponentArtifactsResult; +import org.gradle.api.artifacts.result.ResolutionResult; +import org.gradle.api.component.Artifact; +import org.gradle.api.component.Component; +import org.gradle.api.specs.Specs; +import org.gradle.internal.impldep.com.google.common.collect.ArrayListMultimap; +import org.gradle.internal.impldep.com.google.common.collect.Multimap; +import org.gradle.internal.impldep.com.google.common.collect.Sets; +import org.gradle.language.base.artifact.SourcesArtifact; +import org.gradle.language.java.artifact.JavadocArtifact; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.gradle.model.DefaultFileCollectionDependency; +import org.jetbrains.plugins.gradle.model.ExternalDependency; +import org.jetbrains.plugins.gradle.tooling.util.SourceSetCachedFinder; + +import java.io.File; +import java.util.*; + +class ArtifactQueryResolver { + private final Configuration myConfiguration; + private final String myScope; + private final Project myProject; + private final boolean myDownloadSources; + private final boolean myDownloadJavadoc; + private final SourceSetCachedFinder mySourceSetFinder; + + public ArtifactQueryResolver(@NotNull final Configuration configuration, + @NotNull final String scope, + @NotNull final Project project, + final boolean downloadJavadoc, + final boolean downloadSources, + @NotNull final SourceSetCachedFinder sourceSetFinder) { + myConfiguration = configuration; + myScope = scope; + myProject = project; + myDownloadJavadoc = downloadJavadoc; + myDownloadSources = downloadSources; + mySourceSetFinder = sourceSetFinder; + } + + public ExternalDepsResolutionResult resolve() { + final Collection extDependencies = new ArrayList(); + + Class jvmLibrary = tryLoadingJvmLibraryClass(); + + if (jvmLibrary == null) { + return ExternalDepsResolutionResult.EMPTY; + } + + Set resolvedArtifacts = myConfiguration.getResolvedConfiguration() + .getLenientConfiguration() + .getArtifacts(Specs.SATISFIES_ALL); + + final Multimap artifactMap = + groupByModuleVersionId(resolvedArtifacts); + final Map componentResultsMap = + getComponentIdToArtifactResultMap(jvmLibrary, resolvedArtifacts); + + final Multimap configurationProjectDependencies = + DependencyResolverImpl.collectProjectDeps(myConfiguration); + + if(!myConfiguration.getResolvedConfiguration().hasError()) { + extDependencies.addAll(buildFileCollectionDeps(resolvedArtifacts, configurationProjectDependencies.values())); + } + + DependencyResultsTransformer dependencyResultsTransformer = + new DependencyResultsTransformer(myProject, mySourceSetFinder, + artifactMap, + componentResultsMap, + configurationProjectDependencies, + myScope); + + ResolutionResult resolutionResult = myConfiguration.getIncoming().getResolutionResult(); + extDependencies.addAll(dependencyResultsTransformer.transform(resolutionResult.getRoot().getDependencies())); + + return new ExternalDepsResolutionResult(extDependencies, + new ArrayList(dependencyResultsTransformer.resolvedDepsFiles)); + } + + @NotNull + public Multimap groupByModuleVersionId(Set resolvedArtifacts) { + Multimap artifactMap = ArrayListMultimap.create(); + for (ResolvedArtifact artifact : resolvedArtifacts) { + final ModuleVersionIdentifier moduleVersionId = artifact.getModuleVersion().getId(); + artifactMap.put(moduleVersionId, artifact); + } + return artifactMap; + } + + @NotNull + public Map getComponentIdToArtifactResultMap(@NotNull final Class jvmLibrary, + @NotNull final Set resolvedArtifacts) { + List components = new ArrayList(); + for (ResolvedArtifact artifact : resolvedArtifacts) { + final ModuleVersionIdentifier moduleVersionId = artifact.getModuleVersion().getId(); + if (!DependencyResolverImpl.isProjectDependencyArtifact(artifact)) { + components.add(DependencyResolverImpl.toComponentIdentifier(moduleVersionId)); + } + } + + boolean isBuildScriptConfiguration = myProject.getBuildscript().getConfigurations().contains(myConfiguration); + DependencyHandler dependencyHandler = isBuildScriptConfiguration ? myProject.getBuildscript().getDependencies() : myProject.getDependencies(); + + Set componentResults = dependencyHandler.createArtifactResolutionQuery() + .forComponents(components) + .withArtifacts(jvmLibrary, additionalArtifactsTypes().toArray(new Class[0])) + .execute() + .getResolvedComponents(); + + Map componentResultsMap = + new HashMap(); + + for (ComponentArtifactsResult artifactsResult : componentResults) { + componentResultsMap.put(artifactsResult.getId(), artifactsResult); + } + return componentResultsMap; + } + + protected Collection buildFileCollectionDeps(Collection resolvedArtifactToFilter, + Collection projectDepsToFilter) { + Collection result = new ArrayList(); + + Set fileDeps = new LinkedHashSet(myConfiguration.getIncoming().getFiles().getFiles()); + for (ResolvedArtifact artifact : resolvedArtifactToFilter) { + fileDeps.remove(artifact.getFile()); + } + + for (ProjectDependency dep : projectDepsToFilter) { + Set depFiles = DependencyResolverImpl.getTargetConfiguration(dep).getAllArtifacts().getFiles().getFiles(); + + final Set intersection = new HashSet(Sets.intersection(fileDeps, depFiles)); + if (!intersection.isEmpty()) { + DefaultFileCollectionDependency fileCollectionDependency = new DefaultFileCollectionDependency(intersection); + fileCollectionDependency.setScope(myScope); + result.add(fileCollectionDependency); + fileDeps.removeAll(intersection); + } + } + + for (File file : fileDeps) { + DefaultFileCollectionDependency fileCollectionDependency = new DefaultFileCollectionDependency(Collections.singleton(file)); + fileCollectionDependency.setScope(myScope); + result.add(fileCollectionDependency); + } + + return result; + } + + + @NotNull + protected List> additionalArtifactsTypes() { + List> artifactTypes = new ArrayList>(); + if (myDownloadSources) { artifactTypes.add(SourcesArtifact.class); } + if (myDownloadJavadoc) { artifactTypes.add(JavadocArtifact.class); } + return artifactTypes; + } + + @Nullable + protected Class tryLoadingJvmLibraryClass() { + Class jvmLibrary = null; + try { + jvmLibrary = (Class)Class.forName("org.gradle.jvm.JvmLibrary"); + } + catch (ClassNotFoundException ignored) { + } + + if (jvmLibrary == null) { + try { + jvmLibrary = (Class)Class.forName("org.gradle.runtime.jvm.JvmLibrary"); + } + catch (ClassNotFoundException ignored) { + } + } + return jvmLibrary; + } +} diff --git a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/util/resolve/DependencyResolverImpl.java b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/util/resolve/DependencyResolverImpl.java index 6fbadd73a78a..5a8ca703411a 100644 --- a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/util/resolve/DependencyResolverImpl.java +++ b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/util/resolve/DependencyResolverImpl.java @@ -6,14 +6,8 @@ package org.jetbrains.plugins.gradle.tooling.util.resolve; import org.gradle.api.Project; import org.gradle.api.Task; import org.gradle.api.artifacts.*; -import org.gradle.api.artifacts.component.ComponentIdentifier; import org.gradle.api.artifacts.component.ModuleComponentIdentifier; import org.gradle.api.artifacts.component.ProjectComponentIdentifier; -import org.gradle.api.artifacts.dsl.DependencyHandler; -import org.gradle.api.artifacts.result.ComponentArtifactsResult; -import org.gradle.api.artifacts.result.ResolutionResult; -import org.gradle.api.component.Artifact; -import org.gradle.api.component.Component; import org.gradle.api.plugins.WarPlugin; import org.gradle.api.specs.Specs; import org.gradle.api.tasks.SourceSet; @@ -24,9 +18,6 @@ import org.gradle.internal.impldep.com.google.common.base.Predicate; import org.gradle.internal.impldep.com.google.common.collect.ArrayListMultimap; import org.gradle.internal.impldep.com.google.common.collect.Lists; import org.gradle.internal.impldep.com.google.common.collect.Multimap; -import org.gradle.internal.impldep.com.google.common.collect.Sets; -import org.gradle.language.base.artifact.SourcesArtifact; -import org.gradle.language.java.artifact.JavadocArtifact; import org.gradle.plugins.ide.idea.IdeaPlugin; import org.gradle.util.GUtil; import org.gradle.util.GradleVersion; @@ -111,130 +102,39 @@ public class DependencyResolverImpl implements DependencyResolver { } public ExternalDepsResolutionResult resolveDependencies(@Nullable Configuration configuration, @Nullable String scope) { - if (configuration == null) { + if (configuration == null + || configuration.getAllDependencies().isEmpty()) { return ExternalDepsResolutionResult.EMPTY; } - if (configuration.getAllDependencies().isEmpty()) { - return ExternalDepsResolutionResult.EMPTY; - } - - final Collection result = new LinkedHashSet(); - - final List resolvedFileDependencies = new ArrayList(); + final ExternalDepsResolutionResult result; if (!myIsPreview && isArtifactResolutionQuerySupported) { - Class jvmLibrary = null; - try { - jvmLibrary = (Class)Class.forName("org.gradle.jvm.JvmLibrary"); - } - catch (ClassNotFoundException ignored) { - } - if (jvmLibrary == null) { - try { - jvmLibrary = (Class)Class.forName("org.gradle.runtime.jvm.JvmLibrary"); - } - catch (ClassNotFoundException ignored) { - } - } - - if (jvmLibrary != null) { - List> artifactTypes = new ArrayList>(); - - if (myDownloadSources) { artifactTypes.add(SourcesArtifact.class); } - if (myDownloadJavadoc) { artifactTypes.add(JavadocArtifact.class); } - - - Set resolvedArtifacts = - configuration.getResolvedConfiguration().getLenientConfiguration().getArtifacts(Specs.SATISFIES_ALL); - - Multimap artifactMap = ArrayListMultimap.create(); - - for (ResolvedArtifact artifact : resolvedArtifacts) { - artifactMap.put(artifact.getModuleVersion().getId(), artifact); - } - - - boolean isBuildScriptConfiguration = myProject.getBuildscript().getConfigurations().contains(configuration); - //noinspection GroovyAssignabilityCheck - DependencyHandler dependencyHandler = isBuildScriptConfiguration ? myProject.getBuildscript().getDependencies() : myProject.getDependencies(); - - List components = new ArrayList(); - for (ResolvedArtifact artifact : resolvedArtifacts) { - if (!isProjectDependencyArtifact(artifact)) { - components.add(toComponentIdentifier(artifact.getModuleVersion().getId())); - } - } - - Set componentResults = dependencyHandler.createArtifactResolutionQuery() - .forComponents(components) - .withArtifacts(jvmLibrary, artifactTypes.toArray(new Class[0])) - .execute() - .getResolvedComponents(); - - Map componentResultsMap = - new HashMap(); - - for (ComponentArtifactsResult artifactsResult : componentResults) { - componentResultsMap.put(artifactsResult.getId(), artifactsResult); - } - - Set processedConfigurations = new HashSet(); - Multimap configurationProjectDependencies = - projectDeps(configuration, ArrayListMultimap.create(), processedConfigurations); - - ResolutionResult resolutionResult = configuration.getIncoming().getResolutionResult(); - if(!configuration.getResolvedConfiguration().hasError()) { - Set fileDeps = new LinkedHashSet(configuration.getIncoming().getFiles().getFiles()); - - for (ResolvedArtifact artifact : artifactMap.values()) { - fileDeps.remove(artifact.getFile()); - } - - for (ProjectDependency dep : configurationProjectDependencies.values()) { - Set depFiles = getTargetConfiguration(dep).getAllArtifacts().getFiles().getFiles(); - final Set intersection = new HashSet(Sets.intersection(fileDeps, depFiles)); - if (!intersection.isEmpty()) { - DefaultFileCollectionDependency fileCollectionDependency = new DefaultFileCollectionDependency(intersection); - fileCollectionDependency.setScope(scope); - result.add(fileCollectionDependency); - fileDeps.removeAll(intersection); - } - } - - for (File file : fileDeps) { - DefaultFileCollectionDependency fileCollectionDependency = new DefaultFileCollectionDependency(Collections.singleton(file)); - fileCollectionDependency.setScope(scope); - result.add(fileCollectionDependency); - } - } - - DependencyResultsTransformer dependencyResultsTransformer = - new DependencyResultsTransformer(myProject, mySourceSetFinder, artifactMap, componentResultsMap, configurationProjectDependencies, scope); - result.addAll(dependencyResultsTransformer.transform(resolutionResult.getRoot().getDependencies())); - - resolvedFileDependencies.addAll(dependencyResultsTransformer.resolvedDepsFiles); - } + result = new ArtifactQueryResolver(configuration, scope, myProject, myDownloadJavadoc, myDownloadSources, mySourceSetFinder).resolve(); + } else { + result = new ExternalDepsResolutionResult(findDependencies(configuration, configuration.getAllDependencies(), scope), + new ArrayList()); } - if (myIsPreview || !isArtifactResolutionQuerySupported) { - Set projectDependencies = findDependencies(configuration, configuration.getAllDependencies(), scope); - result.addAll(projectDependencies); - } Set fileDependencies = findAllFileDependencies(configuration.getAllDependencies(), scope); - // TODO investigate resolvedFileDependencies content - fileDependencies.removeAll(resolvedFileDependencies); - result.addAll(fileDependencies); - - return new ExternalDepsResolutionResult(new ArrayList(result), resolvedFileDependencies); + result.getExternalDeps().addAll(fileDependencies); + return result; } - Multimap projectDeps(Configuration conf, - Multimap map, - Set processedConfigurations) { + + protected static Multimap collectProjectDeps(@NotNull final Configuration configuration) { + return projectDeps(configuration, + ArrayListMultimap.create(), + new HashSet()); + } + + private static Multimap projectDeps(Configuration conf, + Multimap map, + Set processedConfigurations) { if(!processedConfigurations.add(conf)) { return map; } + for (Dependency dep : conf.getIncoming().getDependencies()) { if (dep instanceof ProjectDependency) { map.put(toComponentIdentifier(dep.getGroup(), dep.getName(), dep.getVersion()), (ProjectDependency)dep); @@ -841,10 +741,9 @@ public class DependencyResolverImpl implements DependencyResolver { return result; } - private Set findDependencies( - Configuration configuration, - Collection dependencies, - String scope) { + private Set findDependencies(@NotNull final Configuration configuration, + @NotNull final Collection dependencies, + @NotNull final String scope) { Set result = new LinkedHashSet(); Set resolvedArtifacts = myIsPreview ? new HashSet() : @@ -871,7 +770,7 @@ public class DependencyResolverImpl implements DependencyResolver { projectDependency.setConfigurationName(targetConfiguration.getName()); Set artifacts = targetConfiguration.getAllArtifacts().getFiles().getFiles(); projectDependency.setProjectDependencyArtifacts(artifacts); - setProjectDependencyArtifactsSources(projectDependency, artifacts, mySourceSetFinder); + projectDependency.setProjectDependencyArtifactsSources(findArtifactSources(artifacts, mySourceSetFinder)); result.add(projectDependency); } else if (it != null) { @@ -929,9 +828,8 @@ public class DependencyResolverImpl implements DependencyResolver { } - public static void setProjectDependencyArtifactsSources(DefaultExternalProjectDependency projectDependency, - Collection artifactFiles, - SourceSetCachedFinder sourceSetFinder) { + @NotNull + public static List findArtifactSources(Collection artifactFiles, SourceSetCachedFinder sourceSetFinder) { List artifactSources = new ArrayList(); for (File artifactFile : artifactFiles) { SourceSet sourceSet = sourceSetFinder.findByArtifact(artifactFile.getPath()); @@ -939,7 +837,7 @@ public class DependencyResolverImpl implements DependencyResolver { artifactSources.addAll(sourceSet.getAllJava().getSrcDirs()); } } - projectDependency.setProjectDependencyArtifactsSources(artifactSources); + return artifactSources; } public static boolean isProjectDependencyArtifact(ResolvedArtifact artifact) { diff --git a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/util/resolve/DependencyResultsTransformer.java b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/util/resolve/DependencyResultsTransformer.java index 8f162b7f193c..1e83346c229b 100644 --- a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/util/resolve/DependencyResultsTransformer.java +++ b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/util/resolve/DependencyResultsTransformer.java @@ -12,11 +12,11 @@ import org.gradle.api.component.Artifact; import org.gradle.api.tasks.AbstractCopyTask; import org.gradle.api.tasks.SourceSetOutput; import org.gradle.api.tasks.bundling.AbstractArchiveTask; -import org.gradle.internal.impldep.com.google.common.collect.Lists; import org.gradle.internal.impldep.com.google.common.collect.Multimap; import org.gradle.internal.impldep.com.google.common.io.Files; import org.gradle.language.base.artifact.SourcesArtifact; import org.gradle.language.java.artifact.JavadocArtifact; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.model.*; import org.jetbrains.plugins.gradle.model.ExternalDependency; @@ -29,7 +29,6 @@ import java.util.*; class DependencyResultsTransformer { private final Project myProject; private final SourceSetCachedFinder mySourceSetFinder; - Collection handledDependencyResults; Multimap artifactMap; Map componentResultsMap; Multimap configurationProjectDependencies; @@ -44,261 +43,294 @@ class DependencyResultsTransformer { String scope) { myProject = project; mySourceSetFinder = sourceSetFinder; - this.handledDependencyResults = Lists.newArrayList(); + this.artifactMap = artifactMap; this.componentResultsMap = componentResultsMap; this.configurationProjectDependencies = configurationProjectDependencies; this.scope = scope; } - Set transform(Collection dependencyResults) { - Set dependencies = new LinkedHashSet(); - for (DependencyResult dependencyResult : dependencyResults) { + Set transform(Collection gradleDependencies) { + Set handledDependencyResults = new HashSet(); + Set result = new LinkedHashSet(); + for (DependencyResult gradleDep : gradleDependencies) { // dependency cycles check - if (!handledDependencyResults.contains(dependencyResult)) { - handledDependencyResults.add(dependencyResult); - - if (dependencyResult instanceof ResolvedDependencyResult) { - ResolvedComponentResult componentResult = ((ResolvedDependencyResult)dependencyResult).getSelected(); - ComponentSelector componentSelector = dependencyResult.getRequested(); - ModuleComponentIdentifier componentIdentifier = DependencyResolverImpl.toComponentIdentifier(componentResult.getModuleVersion()); - - String name = componentResult.getModuleVersion().getName(); - String group = componentResult.getModuleVersion().getGroup(); - String version = componentResult.getModuleVersion().getVersion(); - String selectionReason = componentResult.getSelectionReason().getDescription(); - - boolean resolveFromArtifacts = componentSelector instanceof ModuleComponentSelector; - - if (componentSelector instanceof ProjectComponentSelector) { - Collection projectDependencies = configurationProjectDependencies.get(componentIdentifier); - Collection dependencyConfigurations; - if (projectDependencies.isEmpty()) { - Project dependencyProject = myProject.findProject(((ProjectComponentSelector)componentSelector).getProjectPath()); - if (dependencyProject != null) { - Configuration dependencyProjectConfiguration = - dependencyProject.getConfigurations().getByName(Dependency.DEFAULT_CONFIGURATION); - dependencyConfigurations = Collections.singleton(dependencyProjectConfiguration); - } else { - dependencyConfigurations = Collections.emptySet(); - resolveFromArtifacts = true; - selectionReason = "composite build substitution"; - } - } else { - dependencyConfigurations = new ArrayList(); - for (ProjectDependency dependency : projectDependencies) { - dependencyConfigurations.add(DependencyResolverImpl.getTargetConfiguration(dependency)); - } - } - - for (Configuration it : dependencyConfigurations) { - if (it.getName().equals(Dependency.DEFAULT_CONFIGURATION)) { - DefaultExternalProjectDependency dependency = new DefaultExternalProjectDependency(); - dependency.setName( name); - dependency.setGroup(group); - dependency.setVersion(version); - dependency.setScope(scope); - dependency.setSelectionReason(selectionReason); - dependency.setProjectPath(((ProjectComponentSelector)componentSelector).getProjectPath()); - dependency.setConfigurationName(it.getName()); - Set artifacts = it.getAllArtifacts().getFiles().getFiles(); - dependency.setProjectDependencyArtifacts(artifacts); - DependencyResolverImpl.setProjectDependencyArtifactsSources(dependency, artifacts, mySourceSetFinder); - - resolvedDepsFiles.addAll(dependency.getProjectDependencyArtifacts()); - - if (it.getArtifacts().size() == 1) { - PublishArtifact publishArtifact = it.getAllArtifacts().iterator().next(); - dependency.setClassifier(publishArtifact.getClassifier()); - dependency.setPackaging(publishArtifact.getExtension() != null ? publishArtifact.getExtension() : "jar"); - } - - if (!componentResult.equals(dependencyResult.getFrom())) { - dependency.getDependencies().addAll( - transform(componentResult.getDependencies()) - ); - } - dependencies.add(dependency); - } - else { - DefaultExternalProjectDependency dependency = new DefaultExternalProjectDependency(); - dependency.setName(name); - dependency.setGroup(group); - dependency.setVersion(version); - dependency.setScope(scope); - dependency.setSelectionReason(selectionReason); - dependency.setProjectPath(((ProjectComponentSelector)componentSelector).getProjectPath()); - dependency.setConfigurationName(it.getName()); - Set artifactsFiles = it.getAllArtifacts().getFiles().getFiles(); - dependency.setProjectDependencyArtifacts(artifactsFiles); - DependencyResolverImpl.setProjectDependencyArtifactsSources(dependency, artifactsFiles, mySourceSetFinder); - - resolvedDepsFiles.addAll(dependency.getProjectDependencyArtifacts()); - - if (it.getArtifacts().size() == 1) { - PublishArtifact publishArtifact = it.getAllArtifacts().iterator().next(); - dependency.setClassifier(publishArtifact.getClassifier()); - dependency.setPackaging(publishArtifact.getExtension() != null ? publishArtifact.getExtension() : "jar"); - } - - if (!componentResult.equals(dependencyResult.getFrom())) { - - dependency.getDependencies().addAll( - transform(componentResult.getDependencies()) - ); - } - - dependencies.add(dependency); - - List files = new ArrayList(); - PublishArtifactSet artifacts = it.getArtifacts(); - if (artifacts != null && !artifacts.isEmpty()) { - PublishArtifact artifact = artifacts.iterator().next(); - final MetaProperty taskProperty = DefaultGroovyMethods.hasProperty(artifact, "archiveTask"); - if (taskProperty != null && (taskProperty.getProperty(artifact) instanceof AbstractArchiveTask)) { - - AbstractArchiveTask archiveTask = (AbstractArchiveTask)taskProperty.getProperty(artifact); - resolvedDepsFiles.add(new File(archiveTask.getDestinationDir(), archiveTask.getArchiveName())); - - - try { - final Method mainSpecGetter = AbstractCopyTask.class.getDeclaredMethod("getMainSpec"); - mainSpecGetter.setAccessible(true); - Object mainSpec = mainSpecGetter.invoke(archiveTask); - - final List sourcePathGetters = - DefaultGroovyMethods.respondsTo(mainSpec, "getSourcePaths", new Object[]{}); - if (!sourcePathGetters.isEmpty()) { - Set sourcePaths = (Set)sourcePathGetters.get(0).doMethodInvoke(mainSpec, new Object[]{}); - if (sourcePaths != null) { - for (Object path : sourcePaths) { - if (path instanceof String) { - File file = new File((String)path); - if (file.isAbsolute()) { - files.add(file); - } - } - else if (path instanceof SourceSetOutput) { - files.addAll(((SourceSetOutput)path).getFiles()); - } - } - } - } - } catch (Exception e) { - throw new RuntimeException(e); - } - } - } - - if (!files.isEmpty()) { - final DefaultFileCollectionDependency fileCollectionDependency = new DefaultFileCollectionDependency(files); - fileCollectionDependency.setScope(scope); - dependencies.add(fileCollectionDependency); - resolvedDepsFiles.addAll(files); - } - } - } - } - - if (resolveFromArtifacts) { - Collection artifacts = artifactMap.get(componentResult.getModuleVersion()); - - if (artifacts != null && artifacts.isEmpty()) { - dependencies.addAll( - transform(componentResult.getDependencies()) - ); - } - - boolean first = true; - - if (artifacts != null) { - for (ResolvedArtifact artifact: artifacts) { - String packaging = artifact.getExtension() != null ? artifact.getExtension() : "jar"; - String classifier = artifact.getClassifier(); - final ExternalDependency dependency; - if (DependencyResolverImpl.isProjectDependencyArtifact(artifact)) { - ProjectComponentIdentifier artifactComponentIdentifier = - (ProjectComponentIdentifier)artifact.getId().getComponentIdentifier(); - - dependency = new DefaultExternalProjectDependency(); - DefaultExternalProjectDependency dDep = (DefaultExternalProjectDependency)dependency; - dDep.setName(name); - dDep.setGroup(group); - dDep.setVersion(version); - dDep.setScope(scope); - dDep.setSelectionReason(selectionReason); - dDep.setProjectPath(artifactComponentIdentifier.getProjectPath()); - dDep.setConfigurationName(Dependency.DEFAULT_CONFIGURATION); - - List files = new ArrayList(); - for (ResolvedArtifact resolvedArtifact : artifactMap.get(componentResult.getModuleVersion())) { - files.add(resolvedArtifact.getFile()); - } - dDep.setProjectDependencyArtifacts(files); - DependencyResolverImpl.setProjectDependencyArtifactsSources(dDep, files, mySourceSetFinder); - resolvedDepsFiles.addAll(dDep.getProjectDependencyArtifacts()); - } - else { - dependency = new DefaultExternalLibraryDependency(); - DefaultExternalLibraryDependency dDep = (DefaultExternalLibraryDependency)dependency; - dDep.setName(name); - dDep.setGroup(group); - dDep.setPackaging(packaging); - dDep.setClassifier(classifier); - dDep.setVersion(version); - dDep.setScope(scope); - dDep.setSelectionReason(selectionReason); - dDep.setFile(artifact.getFile()); - - ComponentArtifactsResult artifactsResult = componentResultsMap.get(componentIdentifier); - if (artifactsResult != null) { - ResolvedArtifactResult - sourcesResult = findMatchingArtifact(artifact, artifactsResult, SourcesArtifact.class); - if (sourcesResult != null) { - ((DefaultExternalLibraryDependency)dependency).setSource(sourcesResult.getFile()); - } - - ResolvedArtifactResult javadocResult = findMatchingArtifact(artifact, artifactsResult, JavadocArtifact.class); - if (javadocResult != null) { - ((DefaultExternalLibraryDependency)dependency).setJavadoc(javadocResult.getFile()); - } - } - } - - if (first) { - dependency.getDependencies().addAll( - transform(componentResult.getDependencies()) - ); - first = false; - } - - dependencies.add(dependency); - resolvedDepsFiles.add(artifact.getFile()); - } - } - } + if (handledDependencyResults.add(gradleDep)) { + if (gradleDep instanceof ResolvedDependencyResult) { + result.addAll(transformDependencyResult((ResolvedDependencyResult)gradleDep)); } - if (dependencyResult instanceof UnresolvedDependencyResult) { - ComponentSelector attempted = ((UnresolvedDependencyResult)dependencyResult).getAttempted(); - if (attempted instanceof ModuleComponentSelector) { - final ModuleComponentSelector attemptedMCSelector = (ModuleComponentSelector)attempted; - final DefaultUnresolvedExternalDependency dependency = new DefaultUnresolvedExternalDependency(); - dependency.setName(attemptedMCSelector.getModule()); - dependency.setGroup(attemptedMCSelector.getGroup()); - dependency.setVersion(attemptedMCSelector.getVersion()); - dependency.setScope(scope); - dependency.setFailureMessage(((UnresolvedDependencyResult)dependencyResult).getFailure().getMessage()); - - dependencies.add(dependency); - } + if (gradleDep instanceof UnresolvedDependencyResult) { + result.addAll(transformDependencyResult((UnresolvedDependencyResult)gradleDep)); } } } - return dependencies; + return result; + } + + private Set transformDependencyResult(UnresolvedDependencyResult unresolvedGradleDep) { + ComponentSelector attempted = unresolvedGradleDep.getAttempted(); + if (attempted instanceof ModuleComponentSelector) { + final ModuleComponentSelector attemptedMCSelector = (ModuleComponentSelector)attempted; + return Collections.singleton(createUnresolvedExternalDep(attemptedMCSelector, + unresolvedGradleDep.getFailure().getMessage())); + } + return Collections.emptySet(); + } + + + private Set transformDependencyResult(ResolvedDependencyResult resolvedGradleDep) { + Set result = new LinkedHashSet(); + ResolvedComponentResult componentResult = resolvedGradleDep.getSelected(); + ComponentSelector componentSelector = resolvedGradleDep.getRequested(); + final ModuleVersionIdentifier moduleVersionId = componentResult.getModuleVersion(); + ModuleComponentIdentifier componentIdentifier = DependencyResolverImpl.toComponentIdentifier(moduleVersionId); + String selectionReason = componentResult.getSelectionReason().getDescription(); + + boolean resolveFromArtifacts = false; + + if (componentSelector instanceof ProjectComponentSelector) { + final ProjectComponentSelector selector = (ProjectComponentSelector)componentSelector; + + final Collection dependencyConfigurations = + getProjectDepsConfigurations(selector.getProjectPath(), + configurationProjectDependencies.get(componentIdentifier)); + + if (dependencyConfigurations.isEmpty()) { + resolveFromArtifacts = true; + selectionReason = "composite build substitution"; + } + + for (Configuration it : dependencyConfigurations) { + DefaultExternalProjectDependency dependency = createExternalProjectDep(moduleVersionId, + selectionReason, + selector.getProjectPath(), + it.getName()); + processProjectDependencyConfiguration(resolvedGradleDep, result, componentResult, it, dependency); + } + } + + if (componentSelector instanceof ModuleComponentSelector || resolveFromArtifacts) { + Collection artifacts = artifactMap.get(moduleVersionId); + + final Set transitiveDeps = transform(componentResult.getDependencies()); + if (artifacts != null && artifacts.isEmpty()) { + result.addAll(transitiveDeps); + } + + boolean first = true; + + if (artifacts != null) { + for (ResolvedArtifact artifact: artifacts) { + final ExternalDependency dependency = transformResolvedArtifact(moduleVersionId, componentIdentifier, selectionReason, artifact); + + if (first) { + dependency.getDependencies().addAll(transitiveDeps); + first = false; + } + result.add(dependency); + resolvedDepsFiles.add(artifact.getFile()); + } + } + } + + return result; + } + + @NotNull + private Collection getProjectDepsConfigurations(@NotNull final String projectPath, + @NotNull final Collection projectDependencies) { + Collection dependencyConfigurations; + if (projectDependencies.isEmpty()) { + Project dependencyProject = myProject.findProject(projectPath); + if (dependencyProject != null) { + Configuration dependencyProjectConfiguration = + dependencyProject.getConfigurations().getByName(Dependency.DEFAULT_CONFIGURATION); + dependencyConfigurations = Collections.singleton(dependencyProjectConfiguration); + } else { + dependencyConfigurations = Collections.emptySet(); + } + } else { + dependencyConfigurations = new ArrayList(); + for (ProjectDependency dependency : projectDependencies) { + dependencyConfigurations.add(DependencyResolverImpl.getTargetConfiguration(dependency)); + } + } + return dependencyConfigurations; + } + + @NotNull + private ExternalDependency transformResolvedArtifact(@NotNull final ModuleVersionIdentifier moduleVersionId, + @NotNull final ModuleComponentIdentifier componentIdentifier, + @NotNull final String selectionReason, + @NotNull final ResolvedArtifact artifact) { + String packaging = artifact.getExtension() != null ? artifact.getExtension() : "jar"; + String classifier = artifact.getClassifier(); + final ExternalDependency dependency; + + if (DependencyResolverImpl.isProjectDependencyArtifact(artifact)) { + + final String projectPath = ((ProjectComponentIdentifier)artifact.getId().getComponentIdentifier()).getProjectPath(); + dependency = createExternalProjectDep(moduleVersionId, + selectionReason, + projectPath, + Dependency.DEFAULT_CONFIGURATION); + + DefaultExternalProjectDependency projectDependency = (DefaultExternalProjectDependency)dependency; + + List files = new ArrayList(); + for (ResolvedArtifact resolvedArtifact : artifactMap.get(moduleVersionId)) { + files.add(resolvedArtifact.getFile()); + } + + projectDependency.setProjectDependencyArtifacts(files); + projectDependency.setProjectDependencyArtifactsSources(DependencyResolverImpl.findArtifactSources(files, mySourceSetFinder)); + resolvedDepsFiles.addAll(projectDependency.getProjectDependencyArtifacts()); + } + else { + dependency = createExternalLibraryDep(moduleVersionId, selectionReason); + DefaultExternalLibraryDependency libraryDependency = (DefaultExternalLibraryDependency)dependency; + + libraryDependency.setPackaging(packaging); + libraryDependency.setClassifier(classifier); + libraryDependency.setFile(artifact.getFile()); + + ComponentArtifactsResult artifactsResult = componentResultsMap.get(componentIdentifier); + if (artifactsResult != null) { + ResolvedArtifactResult sourcesResult = findMatchingArtifact(artifact, artifactsResult, SourcesArtifact.class); + if (sourcesResult != null) { + libraryDependency.setSource(sourcesResult.getFile()); + } + + ResolvedArtifactResult javadocResult = findMatchingArtifact(artifact, artifactsResult, JavadocArtifact.class); + if (javadocResult != null) { + libraryDependency.setJavadoc(javadocResult.getFile()); + } + } + } + return dependency; + } + + private void processProjectDependencyConfiguration(@NotNull final ResolvedDependencyResult resolvedGradleDep, + @NotNull final Set result, + @NotNull final ResolvedComponentResult componentResult, + @NotNull final Configuration projectDepConfiguration, + @NotNull final DefaultExternalProjectDependency dependency) { + Set artifactsFiles = projectDepConfiguration.getAllArtifacts().getFiles().getFiles(); + dependency.setProjectDependencyArtifacts(artifactsFiles); + dependency.setProjectDependencyArtifactsSources(DependencyResolverImpl.findArtifactSources(artifactsFiles, mySourceSetFinder)); + resolvedDepsFiles.addAll(dependency.getProjectDependencyArtifacts()); + + if (projectDepConfiguration.getArtifacts().size() == 1) { + PublishArtifact publishArtifact = projectDepConfiguration.getAllArtifacts().iterator().next(); + dependency.setClassifier(publishArtifact.getClassifier()); + dependency.setPackaging(publishArtifact.getExtension() != null ? publishArtifact.getExtension() : "jar"); + } + + if (!componentResult.equals(resolvedGradleDep.getFrom())) { + dependency.getDependencies().addAll(transform(componentResult.getDependencies())); + } + result.add(dependency); + + if (!projectDepConfiguration.getName().equals(Dependency.DEFAULT_CONFIGURATION)) { + List configurationSources = new ArrayList(); + PublishArtifactSet artifacts = projectDepConfiguration.getArtifacts(); + + if (artifacts != null && !artifacts.isEmpty()) { + configurationSources.addAll(collectSourcesOfDependencyConfiguration(artifacts)); + } + + if (!configurationSources.isEmpty()) { + final DefaultFileCollectionDependency fileCollectionDependency = new DefaultFileCollectionDependency(configurationSources); + fileCollectionDependency.setScope(scope); + result.add(fileCollectionDependency); + resolvedDepsFiles.addAll(configurationSources); + } + } + } + + @NotNull + private List collectSourcesOfDependencyConfiguration(@NotNull final PublishArtifactSet artifacts) { + final List files = new ArrayList(); + + PublishArtifact artifact = artifacts.iterator().next(); + final MetaProperty taskProperty = DefaultGroovyMethods.hasProperty(artifact, "archiveTask"); + if (taskProperty != null && (taskProperty.getProperty(artifact) instanceof AbstractArchiveTask)) { + + AbstractArchiveTask archiveTask = (AbstractArchiveTask)taskProperty.getProperty(artifact); + resolvedDepsFiles.add(new File(archiveTask.getDestinationDir(), archiveTask.getArchiveName())); + + try { + final Method mainSpecGetter = AbstractCopyTask.class.getDeclaredMethod("getMainSpec"); + mainSpecGetter.setAccessible(true); + Object mainSpec = mainSpecGetter.invoke(archiveTask); + + final List sourcePathGetters = + DefaultGroovyMethods.respondsTo(mainSpec, "getSourcePaths", new Object[]{}); + if (!sourcePathGetters.isEmpty()) { + Set sourcePaths = (Set)sourcePathGetters.get(0).doMethodInvoke(mainSpec, new Object[]{}); + if (sourcePaths != null) { + for (Object path : sourcePaths) { + if (path instanceof String) { + File file = new File((String)path); + if (file.isAbsolute()) { + files.add(file); + } + } + else if (path instanceof SourceSetOutput) { + files.addAll(((SourceSetOutput)path).getFiles()); + } + } + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + return files; + } + + + private ExternalLibraryDependency createExternalLibraryDep(@NotNull final ModuleVersionIdentifier moduleVersionId, + @NotNull final String selectionReason) { + DefaultExternalLibraryDependency dDep = new DefaultExternalLibraryDependency(); + dDep.setName(moduleVersionId.getName()); + dDep.setGroup(moduleVersionId.getGroup()); + dDep.setVersion(moduleVersionId.getVersion()); + dDep.setSelectionReason(selectionReason); + dDep.setScope(scope); + return dDep; + } + + @NotNull + private DefaultExternalProjectDependency createExternalProjectDep(@NotNull final ModuleVersionIdentifier moduleVersionId, + @NotNull final String selectionReason, + @NotNull final String projectPath, + @NotNull final String configurationName) { + DefaultExternalProjectDependency dependency = new DefaultExternalProjectDependency(); + dependency.setName(moduleVersionId.getName()); + dependency.setGroup(moduleVersionId.getGroup()); + dependency.setVersion(moduleVersionId.getVersion()); + dependency.setScope(scope); + dependency.setSelectionReason(selectionReason); + dependency.setProjectPath(projectPath); + dependency.setConfigurationName(configurationName); + return dependency; + } + + @NotNull + private DefaultUnresolvedExternalDependency createUnresolvedExternalDep(@NotNull final ModuleComponentSelector attemptedMCSelector, + @NotNull final String message) { + final DefaultUnresolvedExternalDependency dependency = new DefaultUnresolvedExternalDependency(); + dependency.setName(attemptedMCSelector.getModule()); + dependency.setGroup(attemptedMCSelector.getGroup()); + dependency.setVersion(attemptedMCSelector.getVersion()); + dependency.setScope(scope); + dependency.setFailureMessage(message); + return dependency; } @Nullable diff --git a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/util/resolve/ExternalDepsResolutionResult.java b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/util/resolve/ExternalDepsResolutionResult.java index f0a09f91b2dd..559a9a165b36 100644 --- a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/util/resolve/ExternalDepsResolutionResult.java +++ b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/util/resolve/ExternalDepsResolutionResult.java @@ -4,15 +4,21 @@ package org.jetbrains.plugins.gradle.tooling.util.resolve; import org.jetbrains.plugins.gradle.model.ExternalDependency; import java.io.File; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -class ExternalDepsResolutionResult { +public class ExternalDepsResolutionResult { public static ExternalDepsResolutionResult EMPTY = new ExternalDepsResolutionResult(Collections.emptySet(), Collections.emptySet()); private final Collection externalDeps; private final Collection resolvedFiles; + public ExternalDepsResolutionResult() { + externalDeps = new ArrayList(); + resolvedFiles = new ArrayList(); + } + public ExternalDepsResolutionResult(Collection deps, Collection files) { externalDeps = deps; resolvedFiles = files;