From dcf27325e9b7797d4c2ecc2542e40f1cffcb391e Mon Sep 17 00:00:00 2001 From: Maksim Zuev Date: Thu, 18 Jan 2024 16:44:44 +0100 Subject: [PATCH] [coverage] IDEA-340872 Extract service for external reports import GitOrigin-RevId: 11b0325a71edf0e9d6ca4644271af63d945d3d4a --- .../actions/CoverageSuiteChooserDialog.java | 82 +++---------------- .../actions/ExternalReportImportManager.kt | 77 +++++++++++++++++ 2 files changed, 89 insertions(+), 70 deletions(-) create mode 100644 plugins/coverage-common/src/com/intellij/coverage/actions/ExternalReportImportManager.kt diff --git a/plugins/coverage-common/src/com/intellij/coverage/actions/CoverageSuiteChooserDialog.java b/plugins/coverage-common/src/com/intellij/coverage/actions/CoverageSuiteChooserDialog.java index dbddba658921..e1778d039946 100644 --- a/plugins/coverage-common/src/com/intellij/coverage/actions/CoverageSuiteChooserDialog.java +++ b/plugins/coverage-common/src/com/intellij/coverage/actions/CoverageSuiteChooserDialog.java @@ -5,15 +5,9 @@ import com.intellij.CommonBundle; import com.intellij.coverage.*; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.fileChooser.FileChooser; -import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; -import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Comparing; -import com.intellij.openapi.vfs.VfsUtil; -import com.intellij.openapi.vfs.VfsUtilCore; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.*; import com.intellij.util.IconUtil; import com.intellij.util.PlatformIcons; @@ -24,7 +18,6 @@ import com.intellij.util.ui.tree.TreeUtil; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; @@ -32,9 +25,10 @@ import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreePath; import java.awt.*; import java.awt.event.ActionEvent; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; -import java.util.*; -import java.util.stream.Collectors; +import java.util.Map; public class CoverageSuiteChooserDialog extends DialogWrapper { @NonNls private static final String LOCAL = "Local"; @@ -99,33 +93,10 @@ public class CoverageSuiteChooserDialog extends DialogWrapper { @Override protected void doOKAction() { final List suites = collectSelectedSuites(); - Map> byEngine = suites.stream().collect(Collectors.groupingBy((suite) -> suite.getCoverageEngine())); - closeBundlesThatAreNotChosen(byEngine); - - for (List suiteList : byEngine.values()) { - CoverageSuitesBundle bundle = new CoverageSuitesBundle(suiteList.toArray(new CoverageSuite[0])); - CoverageLogger.logSuiteImport(myProject, bundle); - myCoverageManager.chooseSuitesBundle(bundle); - } - - if (!suites.isEmpty()) { - ExternalCoverageWatchManager.getInstance(myProject).addRootsToWatch(suites); - } + ExternalReportImportManager.getInstance(myProject).openSuites(suites); super.doOKAction(); } - private void closeBundlesThatAreNotChosen(Map> byEngine) { - Collection activeSuites = myCoverageManager.activeSuites(); - Set activeEngines = activeSuites.stream().map(b -> b.getCoverageEngine()).collect(Collectors.toSet()); - activeEngines.removeAll(byEngine.keySet()); - - for (CoverageSuitesBundle bundle : activeSuites) { - if (activeEngines.contains(bundle.getCoverageEngine())) { - myCoverageManager.closeSuitesBundle(bundle); - } - } - } - @Override protected Action @NotNull [] createActions() { return new Action[]{getOKAction(), new NoCoverageAction(), getCancelAction()}; @@ -135,16 +106,6 @@ public class CoverageSuiteChooserDialog extends DialogWrapper { return CoverageBundle.message("coverage.data.runner.name", coverageRunner.getPresentableName()); } - @Nullable - private static CoverageRunner getCoverageRunner(@NotNull VirtualFile file) { - for (CoverageRunner runner : CoverageRunner.EP_NAME.getExtensionList()) { - for (String extension : runner.getDataFileExtensions()) { - if (Comparing.strEqual(file.getExtension(), extension) && runner.canBeLoaded(VfsUtilCore.virtualToIoFile(file))) return runner; - } - } - return null; - } - private List collectSelectedSuites() { final List suites = new ArrayList<>(); TreeUtil.treeNodeTraverser(myRootNode).traverse(TreeTraversal.PRE_ORDER_DFS).processEach(treeNode -> { @@ -280,33 +241,14 @@ public class CoverageSuiteChooserDialog extends DialogWrapper { @Override public void actionPerformed(@NotNull AnActionEvent e) { - final VirtualFile[] files = - FileChooser.chooseFiles(new FileChooserDescriptor(true, false, false, false, false, true) { - @Override - public boolean isFileSelectable(@Nullable VirtualFile file) { - return file != null && getCoverageRunner(file) != null; - } - }, myProject, null); - if (files.length > 0) { - //ensure timestamp in vfs is updated - VfsUtil.markDirtyAndRefresh(false, false, false, files); - - for (VirtualFile file : files) { - final CoverageRunner coverageRunner = getCoverageRunner(file); - if (coverageRunner == null) { - Messages.showErrorDialog(myProject, CoverageBundle.message("no.coverage.runner.available.for", file.getName()), CommonBundle.getErrorTitle()); - continue; - } - - CoverageSuite coverageSuite = myCoverageManager.addExternalCoverageSuite(VfsUtilCore.virtualToIoFile(file), coverageRunner); - - List currentlySelected = collectSelectedSuites(); - currentlySelected.add(coverageSuite); - initTree(); - selectSuites(currentlySelected); - ((DefaultTreeModel)mySuitesTree.getModel()).reload(); - TreeUtil.expandAll(mySuitesTree); - } + List suites = ExternalReportImportManager.getInstance(myProject).chooseAndImportCoverageReportsFromDisc(); + if (!suites.isEmpty()) { + List currentlySelected = collectSelectedSuites(); + currentlySelected.addAll(suites); + initTree(); + selectSuites(currentlySelected); + ((DefaultTreeModel)mySuitesTree.getModel()).reload(); + TreeUtil.expandAll(mySuitesTree); } } } diff --git a/plugins/coverage-common/src/com/intellij/coverage/actions/ExternalReportImportManager.kt b/plugins/coverage-common/src/com/intellij/coverage/actions/ExternalReportImportManager.kt new file mode 100644 index 000000000000..33e3df99e83f --- /dev/null +++ b/plugins/coverage-common/src/com/intellij/coverage/actions/ExternalReportImportManager.kt @@ -0,0 +1,77 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.coverage.actions + +import com.intellij.coverage.* +import com.intellij.coverage.CoverageLogger.logSuiteImport +import com.intellij.openapi.components.Service +import com.intellij.openapi.components.service +import com.intellij.openapi.fileChooser.FileChooser +import com.intellij.openapi.fileChooser.FileChooserDescriptor +import com.intellij.openapi.project.Project +import com.intellij.openapi.util.Comparing +import com.intellij.openapi.vfs.VfsUtil +import com.intellij.openapi.vfs.VfsUtilCore +import com.intellij.openapi.vfs.VirtualFile + +@Service(Service.Level.PROJECT) +class ExternalReportImportManager(private val project: Project) { + companion object { + @JvmStatic + fun getInstance(project: Project): ExternalReportImportManager = project.service() + } + + fun openSuites(suites: List) { + val suitesByEngine = suites.groupBy { it.coverageEngine } + closeBundlesThatAreNotChosen(suitesByEngine) + + for (engineSuites in suitesByEngine.values) { + val bundle = CoverageSuitesBundle(engineSuites.toTypedArray()) + logSuiteImport(project, bundle) + CoverageDataManager.getInstance(project).chooseSuitesBundle(bundle) + } + + if (!suites.isEmpty()) { + ExternalCoverageWatchManager.getInstance(project).addRootsToWatch(suites) + } + } + + fun chooseAndImportCoverageReportsFromDisc(): List { + return FileChooser.chooseFiles(object : FileChooserDescriptor(true, false, false, false, false, true) { + override fun isFileSelectable(file: VirtualFile?): Boolean = file != null && getCoverageRunner(file) != null + }, project, null) + .mapNotNull { file -> + val runner = getCoverageRunner(file) ?: return@mapNotNull null + file to runner + }.takeIf { it.isNotEmpty() } + ?.also { list -> + //ensure timestamp in vfs is updated + VfsUtil.markDirtyAndRefresh(false, false, false, *list.map { it.first }.toTypedArray()) + } + ?.mapNotNull { (virtualFile, runner) -> + val file = VfsUtilCore.virtualToIoFile(virtualFile) + CoverageDataManager.getInstance(project).addExternalCoverageSuite(file, runner) + } ?: emptyList() + } + + private fun closeBundlesThatAreNotChosen(suitesByEngine: Map>) { + val activeSuites = CoverageDataManager.getInstance(project).activeSuites() + val activeEngines = activeSuites.map { it.coverageEngine }.toHashSet() + activeEngines.removeAll(suitesByEngine.keys) + + for (bundle in activeSuites) { + if (bundle.coverageEngine in activeEngines) { + CoverageDataManager.getInstance(project).closeSuitesBundle(bundle) + } + } + } +} + + +private fun getCoverageRunner(file: VirtualFile): CoverageRunner? { + for (runner in CoverageRunner.EP_NAME.extensionList) { + for (extension in runner.dataFileExtensions) { + if (Comparing.strEqual(file.extension, extension) && runner.canBeLoaded(VfsUtilCore.virtualToIoFile(file))) return runner + } + } + return null +}