[coverage] IDEA-340872 Extract service for external reports import

GitOrigin-RevId: 11b0325a71edf0e9d6ca4644271af63d945d3d4a
This commit is contained in:
Maksim Zuev
2024-01-18 16:44:44 +01:00
committed by intellij-monorepo-bot
parent 84145e5533
commit dcf27325e9
2 changed files with 89 additions and 70 deletions

View File

@@ -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<CoverageSuite> suites = collectSelectedSuites();
Map<CoverageEngine, List<CoverageSuite>> byEngine = suites.stream().collect(Collectors.groupingBy((suite) -> suite.getCoverageEngine()));
closeBundlesThatAreNotChosen(byEngine);
for (List<CoverageSuite> 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<CoverageEngine, List<CoverageSuite>> byEngine) {
Collection<CoverageSuitesBundle> activeSuites = myCoverageManager.activeSuites();
Set<CoverageEngine> 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<CoverageSuite> collectSelectedSuites() {
final List<CoverageSuite> 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<CoverageSuite> currentlySelected = collectSelectedSuites();
currentlySelected.add(coverageSuite);
initTree();
selectSuites(currentlySelected);
((DefaultTreeModel)mySuitesTree.getModel()).reload();
TreeUtil.expandAll(mySuitesTree);
}
List<CoverageSuite> suites = ExternalReportImportManager.getInstance(myProject).chooseAndImportCoverageReportsFromDisc();
if (!suites.isEmpty()) {
List<CoverageSuite> currentlySelected = collectSelectedSuites();
currentlySelected.addAll(suites);
initTree();
selectSuites(currentlySelected);
((DefaultTreeModel)mySuitesTree.getModel()).reload();
TreeUtil.expandAll(mySuitesTree);
}
}
}

View File

@@ -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<CoverageSuite>) {
val suitesByEngine = suites.groupBy { it.coverageEngine }
closeBundlesThatAreNotChosen(suitesByEngine)
for (engineSuites in suitesByEngine.values) {
val bundle = CoverageSuitesBundle(engineSuites.toTypedArray<CoverageSuite>())
logSuiteImport(project, bundle)
CoverageDataManager.getInstance(project).chooseSuitesBundle(bundle)
}
if (!suites.isEmpty()) {
ExternalCoverageWatchManager.getInstance(project).addRootsToWatch(suites)
}
}
fun chooseAndImportCoverageReportsFromDisc(): List<CoverageSuite> {
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<CoverageEngine, List<CoverageSuite>>) {
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
}