[Gradle] Dependencies graph: show file dependencies IDEA-218166
authorVladislav.Soroka <Vladislav.Soroka@jetbrains.com>
Thu, 26 Dec 2019 05:00:52 +0000 (08:00 +0300)
committerintellij-monorepo-bot <intellij-monorepo-bot-no-reply@jetbrains.com>
Wed, 22 Jan 2020 18:07:02 +0000 (18:07 +0000)
GitOrigin-RevId: fdb2ff39053db1ed2c9bda279f2de4f8c73c5273

platform/external-system-api/resources/messages/ExternalSystemBundle.properties
platform/external-system-impl/src/com/intellij/openapi/externalSystem/view/ExternalSystemViewDefaultContributor.java
platform/external-system-rt/src/com/intellij/openapi/externalSystem/model/project/dependencies/FileCollectionDependencyNode.java [new file with mode: 0644]
platform/external-system-rt/src/com/intellij/openapi/externalSystem/model/project/dependencies/FileCollectionDependencyNodeImpl.java [new file with mode: 0644]
plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/tasks/DependenciesReport.groovy
plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/tasks/DependencyNodeDeserializer.java

index bf61c4368ddbe91cc82aa34f6ccf7b4971922495..cf9051c80ecd56ec60d57349e18aba4c931393c2 100644 (file)
@@ -43,7 +43,8 @@ error.resolve.already.running=Another ''Reimport project'' task is currently run
 # Tool window
 tool.window.title.projects=projects
 tool.window.title.tasks=tasks
-external.system.view.nodes.run_configurations.name = Run Configurations
+external.system.view.nodes.run_configurations.name=Run Configurations
+external.system.view.nodes.dependency_reference_node_tooltip=Dependencies omitted (listed previously). <br/>Press Enter or left mouse button double click to navigate to dependencies.
 
 # Action.
 action.refresh.all.projects.text=Reimport All {0} Projects
index dc5fde9bfd949caf64d9e1aeadb49ca84ef3080f..f11b4d1f75963eb505cfc2d632f024dba75c3599 100644 (file)
@@ -14,6 +14,7 @@ import com.intellij.openapi.externalSystem.service.project.IdeModelsProviderImpl
 import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings;
 import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
 import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
+import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
 import com.intellij.openapi.externalSystem.util.Order;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.roots.OrderEntry;
@@ -26,6 +27,7 @@ import com.intellij.util.ObjectUtils;
 import com.intellij.util.SmartList;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.containers.MultiMap;
+import org.apache.commons.lang.StringEscapeUtils;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -308,8 +310,19 @@ public class ExternalSystemViewDefaultContributor extends ExternalSystemViewCont
       super.update(presentation);
       boolean isProjectDependency = myDependencyNode instanceof ProjectDependencyNode || myReferencedNode instanceof ProjectDependencyNode;
       presentation.setIcon(isProjectDependency ? getUiAware().getProjectIcon() : AllIcons.Nodes.PpLib);
-      String tooltip = "Dependencies omitted (listed previously). <br/>" +
-                       "Press Enter or left mouse button double click to navigate to dependencies.";
+      String tooltip;
+      if (myReferencedNode != null) {
+        tooltip = ExternalSystemBundle.message("external.system.view.nodes.dependency_reference_node_tooltip");
+      }
+      else {
+        if (myDependencyNode instanceof FileCollectionDependencyNode) {
+          String path = ((FileCollectionDependencyNode)myDependencyNode).getPath();
+          tooltip = StringUtil.join(path.split(File.pathSeparator), s -> StringEscapeUtils.escapeHtml(s) + "<br/>" , "");
+        }
+        else {
+          tooltip = null;
+        }
+      }
       setNameAndTooltip(getName(), tooltip, (String)null);
     }
 
diff --git a/platform/external-system-rt/src/com/intellij/openapi/externalSystem/model/project/dependencies/FileCollectionDependencyNode.java b/platform/external-system-rt/src/com/intellij/openapi/externalSystem/model/project/dependencies/FileCollectionDependencyNode.java
new file mode 100644 (file)
index 0000000..3bc9c2f
--- /dev/null
@@ -0,0 +1,9 @@
+// Copyright 2000-2019 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 com.intellij.openapi.externalSystem.model.project.dependencies;
+
+import org.jetbrains.annotations.NotNull;
+
+public interface FileCollectionDependencyNode extends DependencyNode {
+  @NotNull
+  String getPath();
+}
diff --git a/platform/external-system-rt/src/com/intellij/openapi/externalSystem/model/project/dependencies/FileCollectionDependencyNodeImpl.java b/platform/external-system-rt/src/com/intellij/openapi/externalSystem/model/project/dependencies/FileCollectionDependencyNodeImpl.java
new file mode 100644 (file)
index 0000000..c5e1d94
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright 2000-2019 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 com.intellij.openapi.externalSystem.model.project.dependencies;
+
+import com.intellij.serialization.PropertyMapping;
+import org.jetbrains.annotations.NotNull;
+
+public class FileCollectionDependencyNodeImpl extends AbstractDependencyNode implements FileCollectionDependencyNode {
+
+  private final String displayName;
+  private final String path;
+
+  @PropertyMapping({"id", "displayName", "path"})
+  public FileCollectionDependencyNodeImpl(long id, @NotNull String displayName, @NotNull String path) {
+    super(id);
+    this.displayName = displayName;
+    this.path = path;
+  }
+
+  @Override
+  @NotNull
+  public String getPath() {
+    return path;
+  }
+
+  @NotNull
+  @Override
+  public String getDisplayName() {
+    return displayName;
+  }
+}
index f945e46e4ffd8b90bdd37c537be8492a81667591..0abc948b5553ddd6fc6c201bebdc215895734f3d 100644 (file)
@@ -5,11 +5,15 @@ import com.google.gson.GsonBuilder
 import com.intellij.openapi.externalSystem.model.project.dependencies.*
 import groovy.transform.CompileStatic
 import org.gradle.api.DefaultTask
+import org.gradle.api.Describable
 import org.gradle.api.Project
 import org.gradle.api.artifacts.Configuration
+import org.gradle.api.artifacts.Dependency
+import org.gradle.api.artifacts.FileCollectionDependency
 import org.gradle.api.artifacts.component.ModuleComponentIdentifier
 import org.gradle.api.artifacts.component.ProjectComponentIdentifier
 import org.gradle.api.artifacts.result.ResolutionResult
+import org.gradle.api.file.FileCollection
 import org.gradle.api.tasks.Input
 import org.gradle.api.tasks.OutputFile
 import org.gradle.api.tasks.TaskAction
@@ -69,6 +73,36 @@ class DependenciesReport extends DefaultTask {
     String scopeDisplayName = "project " + project.path + " (" + configurationName + ")"
     DependencyScopeNode node = new DependencyScopeNode(id, configurationName, scopeDisplayName, configuration.getDescription())
     node.setResolutionState(root.resolutionState.name())
+    for (Dependency dependency : configuration.getAllDependencies()) {
+      if (dependency instanceof FileCollectionDependency) {
+        FileCollection fileCollection = ((FileCollectionDependency)dependency).getFiles();
+        if (fileCollection instanceof Configuration) continue;
+        def files = fileCollection.files
+        if (files.isEmpty()) continue
+
+        String displayName = null
+        if (fileCollection instanceof Describable) {
+          displayName = ((Describable)fileCollection).displayName
+        } else {
+          def string = fileCollection.toString()
+          if ("file collection" != string) {
+            displayName = string
+          }
+        }
+
+        if (displayName != null) {
+          long fileDepId = idGenerator.getId(displayName, configurationName)
+          node.dependencies.add(new FileCollectionDependencyNodeImpl(fileDepId, displayName, fileCollection.getAsPath()))
+        }
+        else {
+          for (File file : files) {
+            long fileDepId = idGenerator.getId(file.path, configurationName)
+            node.dependencies.add(new FileCollectionDependencyNodeImpl(fileDepId, file.name, file.path))
+          }
+        }
+      }
+    }
+
     Map<Object, DependencyNode> added = [:]
     for (RenderableDependency child in root.getChildren()) {
       node.dependencies.add(toNode(child, configurationName, added, idGenerator, projectNameFunction))
@@ -121,8 +155,8 @@ class DependenciesReport extends DefaultTask {
     private Map<String, Long> idMap = new HashMap<>()
     private long value
 
-    private long getId(RenderableDependency dependency, String configurationName) {
-      def key = dependency.id.toString() + '_' + configurationName
+    private long getId(String prefix, String configurationName) {
+      def key = prefix + '_' + configurationName
       def id = idMap.get(key)
       if (id == null) {
         idMap[key] = ++value
@@ -130,5 +164,9 @@ class DependenciesReport extends DefaultTask {
       }
       return id
     }
+
+    private long getId(RenderableDependency dependency, String configurationName) {
+      return getId(dependency.id.toString(), configurationName)
+    }
   }
 }
index b6d62112e609f58ec405642cd5a59a02de0fa4bd..a57ce5d3d2b56ab2e24428e7c34da1d5b51b7ff7 100644 (file)
@@ -20,6 +20,9 @@ public class DependencyNodeDeserializer implements JsonDeserializer<DependencyNo
     else if (jsonObject.get("module") != null) {
       return context.deserialize(json, ArtifactDependencyNodeImpl.class);
     }
+    else if (jsonObject.get("path") != null) {
+      return context.deserialize(json, FileCollectionDependencyNodeImpl.class);
+    }
     else if (jsonObject.size() == 1 && jsonObject.get("id") != null) {
       return context.deserialize(json, ReferenceNode.class);
     }