From e7d2931e401dd35e1e030dfffcbbf679c8b42960 Mon Sep 17 00:00:00 2001 From: "Vladislav.Soroka" Date: Thu, 26 Jul 2018 16:51:10 +0300 Subject: [PATCH] Gradle: resolve dependency sources in all defined repositories (IDEA-178891) --- .../project/manage/LibraryDataService.java | 4 ++ .../src/util/GradleAttachSourcesProvider.java | 58 ++++++++++++++++--- 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/LibraryDataService.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/LibraryDataService.java index 2c052f93e644..7aa043900163 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/LibraryDataService.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/LibraryDataService.java @@ -234,6 +234,10 @@ public class LibraryDataService extends AbstractProjectDataService toAddPerType = ContainerUtilRt.newHashSet(externalLibrary.getPaths(pathType)); toAdd.put(ideType, toAddPerType); + // do not remove attached or manually added sources/javadocs if nothing to add + if(pathType != LibraryPathType.BINARY && toAddPerType.isEmpty()) { + continue; + } HashSet toRemovePerType = ContainerUtilRt.newHashSet(); toRemove.put(ideType, toRemovePerType); diff --git a/plugins/gradle/java/src/util/GradleAttachSourcesProvider.java b/plugins/gradle/java/src/util/GradleAttachSourcesProvider.java index 70ee10a54719..4a9e0b061055 100644 --- a/plugins/gradle/java/src/util/GradleAttachSourcesProvider.java +++ b/plugins/gradle/java/src/util/GradleAttachSourcesProvider.java @@ -36,6 +36,7 @@ import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.UserDataHolderBase; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -43,11 +44,13 @@ import com.intellij.psi.PsiFile; import com.intellij.util.containers.ContainerUtil; import org.gradle.initialization.BuildLayoutParameters; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.service.project.GradleProjectResolverUtil; import org.jetbrains.plugins.gradle.service.task.GradleTaskManager; import org.jetbrains.plugins.gradle.settings.GradleSettings; import java.io.File; +import java.io.IOException; import java.util.*; import static com.intellij.jarFinder.InternetAttachSourceProvider.attachSourceJar; @@ -93,21 +96,46 @@ public class GradleAttachSourcesProvider implements AttachSourcesProvider { final String gradlePath = GradleProjectResolverUtil.getGradlePath(module); if (gradlePath == null) return ActionCallback.REJECTED; + final String sourcesLocationFilePath; + final File sourcesLocationFile; + try { + sourcesLocationFile = new File(FileUtil.createTempDirectory("sources", "loc"), "path.tmp"); + sourcesLocationFilePath = StringUtil.escapeBackSlashes(sourcesLocationFile.getCanonicalPath()); + Runtime.getRuntime().addShutdownHook(new Thread(() -> FileUtil.delete(sourcesLocationFile))); + } + catch (IOException e) { + GradleLog.LOG.warn(e); + return ActionCallback.REJECTED; + } final String taskName = "DownloadSources"; + // @formatter:off String initScript = "allprojects {\n" + " afterEvaluate { project ->\n" + " if(project.path == '" + gradlePath + "') {\n" + - " project.configurations.maybeCreate('downloadSources')\n" + - " project.dependencies.add('downloadSources', '" + artifactCoordinates + ":sources" + "')\n" + " project.tasks.create(name: '" + taskName + "', overwrite: true) {\n" + " doLast {\n" + - " project.configurations.downloadSources.resolve()\n" + + " def configuration = null\n" + + " def repository = project.repositories.toList().find {\n" + + " project.repositories.clear()\n" + + " project.repositories.add(it)\n" + + " configuration = project.configurations.create('downloadSourcesFrom_' + it.name + '_' + UUID.randomUUID())\n" + + " configuration.transitive = false\n" + + " project.dependencies.add(configuration.name, '" + artifactCoordinates + ":sources" + "')\n" + + " configuration.resolvedConfiguration.lenientConfiguration.getFiles().any()\n" + + " }\n" + + " if (!repository) {\n" + + " configuration = project.configurations.create('downloadSources_' + UUID.randomUUID())\n" + + " configuration.transitive = false\n" + + " project.dependencies.add(configuration.name, '" + artifactCoordinates + ":sources" + "')\n" + + " configuration.resolve()\n" + + " }\n" + + " new File('" + sourcesLocationFilePath + "').write configuration?.singleFile?.path\n" + " }\n" + " }\n" + " }\n" + " }\n" + "}\n"; - + // @formatter:on UserDataHolderBase userData = new UserDataHolderBase(); userData.putUserData(GradleTaskManager.INIT_SCRIPT_KEY, initScript); @@ -123,13 +151,26 @@ public class GradleAttachSourcesProvider implements AttachSourcesProvider { new TaskCallback() { @Override public void onSuccess() { - File sourceJar = getSourceFile(artifactCoordinates, libraryOrderEntry.getFiles(OrderRootType.CLASSES)[0], project); + VirtualFile classesFile = libraryOrderEntry.getFiles(OrderRootType.CLASSES)[0]; + File sourceJar = getSourceFile(artifactCoordinates, classesFile, project); + if (sourceJar == null) { + try { + sourceJar = new File(FileUtil.loadFile(sourcesLocationFile)); + FileUtil.delete(sourcesLocationFile); + } + catch (IOException e) { + GradleLog.LOG.warn(e); + } + } + File finalSourceJar = sourceJar; ApplicationManager.getApplication().invokeLater(() -> { final Set libraries = new HashSet<>(); for (LibraryOrderEntry orderEntry : orderEntries) { ContainerUtil.addIfNotNull(libraries, orderEntry.getLibrary()); } - attachSourceJar(sourceJar, libraries); + if (finalSourceJar != null) { + attachSourceJar(finalSourceJar, libraries); + } resultWrapper.setDone(); }); } @@ -149,7 +190,7 @@ public class GradleAttachSourcesProvider implements AttachSourcesProvider { }); } - @NotNull + @Nullable private static File getSourceFile(String artifactCoordinates, VirtualFile classesFile, Project project) { LibraryData data = new LibraryData(GradleConstants.SYSTEM_ID, artifactCoordinates); data.addPath(LibraryPathType.BINARY, VfsUtil.getLocalFile(classesFile).getPath()); @@ -157,7 +198,8 @@ public class GradleAttachSourcesProvider implements AttachSourcesProvider { File gradleUserHome = serviceDirectory != null ? new File(serviceDirectory) : new BuildLayoutParameters().getGradleUserHomeDir(); attachSourcesAndJavadocFromGradleCacheIfNeeded(gradleUserHome, data); - return new File(data.getPaths(LibraryPathType.SOURCE).iterator().next()); + Iterator iterator = data.getPaths(LibraryPathType.SOURCE).iterator(); + return iterator.hasNext() ? new File(iterator.next()) : null; } private static Map getGradleModules(List libraryOrderEntries) {