From c49d68bcdb3a6071c7b5f60eb4f8bf54b435b3b1 Mon Sep 17 00:00:00 2001 From: Yaroslav Pankratyev Date: Wed, 4 Oct 2017 18:16:57 +0700 Subject: [PATCH] IDEA-179010 Display missing testdata file paths relative to module/project --- .../TestDataNavigationElementFactory.java | 20 ++++- .../src/testAssistant/TestDataUtil.java | 78 ++++++++++++++++++- 2 files changed, 90 insertions(+), 8 deletions(-) diff --git a/plugins/devkit/src/testAssistant/TestDataNavigationElementFactory.java b/plugins/devkit/src/testAssistant/TestDataNavigationElementFactory.java index 7f2800507a10..9e888d00d1a0 100644 --- a/plugins/devkit/src/testAssistant/TestDataNavigationElementFactory.java +++ b/plugins/devkit/src/testAssistant/TestDataNavigationElementFactory.java @@ -26,6 +26,7 @@ import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.SimpleTextAttributes; import com.intellij.util.PathUtil; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.devkit.DevKitBundle; @@ -73,8 +74,16 @@ public class TestDataNavigationElementFactory { } if (filePathsToCreate.size() > CREATE_MISSING_FILES_WITHOUT_CONFIRMATION_LIMIT) { + List displayPaths = new ArrayList<>(); + for (String path : filePathsToCreate) { + displayPaths.add(TestDataUtil.getHtmlDisplayPathForMissingFile(project, path)); + } + + displayPaths.sort(String.CASE_INSENSITIVE_ORDER); + String filePathsDisplayStr = StringUtil.join(displayPaths, "\n"); + int code = Messages.showOkCancelDialog( - project, DevKitBundle.message("testdata.confirm.create.missing.files.dialog.message", StringUtil.join(filePathsToCreate, "\n")), + project, DevKitBundle.message("testdata.confirm.create.missing.files.dialog.message", filePathsDisplayStr), DevKitBundle.message("testdata.create.missing.files"), Messages.getQuestionIcon()); if (code != Messages.OK) { return; @@ -192,9 +201,12 @@ public class TestDataNavigationElementFactory { public List> getTitleFragments() { VirtualFile file = TestDataUtil.getFileByPath(myPath); if (file == null) { - return Collections.singletonList(new Pair<>( - String.format("%s (%s)", PathUtil.getFileName(myPath), PathUtil.getParentPath(myPath)), - SimpleTextAttributes.GRAYED_ATTRIBUTES)); + Pair relativePath = TestDataUtil.getRelativePathPairForMissingFile(myProject, myPath); + return ContainerUtil.list( + new Pair<>(PathUtil.getFileName(myPath) + " (", SimpleTextAttributes.GRAYED_ATTRIBUTES), + new Pair<>(relativePath.first == null ? "" : relativePath.first, SimpleTextAttributes.GRAYED_BOLD_ATTRIBUTES), + new Pair<>(relativePath.first == null ? "" : "/" + relativePath.second + ")", SimpleTextAttributes.GRAYED_ATTRIBUTES) + ); } Pair relativePath = TestDataUtil.getModuleOrProjectRelativeParentPath(myProject, file); diff --git a/plugins/devkit/src/testAssistant/TestDataUtil.java b/plugins/devkit/src/testAssistant/TestDataUtil.java index 9fe3bcb5f956..46f4e68658eb 100644 --- a/plugins/devkit/src/testAssistant/TestDataUtil.java +++ b/plugins/devkit/src/testAssistant/TestDataUtil.java @@ -168,7 +168,8 @@ public class TestDataUtil { new OpenFileDescriptor(project, file).navigate(true); } else { - int rc = Messages.showYesNoDialog(project, DevKitBundle.message("testdata.file.doesn.not.exist", path), + String displayPath = getHtmlDisplayPathForMissingFile(project, path); + int rc = Messages.showYesNoDialog(project, DevKitBundle.message("testdata.file.doesn.not.exist", displayPath), DevKitBundle.message("testdata.create.dialog.title"), Messages.getQuestionIcon()); if (rc == Messages.YES) { VirtualFile vFile = createFileByName(project, path); @@ -192,6 +193,37 @@ public class TestDataUtil { return LocalFileSystem.getInstance().refreshAndFindFileByPath(path); } + @Nullable + private static Pair getModuleOrProjectRelativePath(Project project, String filePath) { + String currentPath = PathUtil.getParentPath(filePath); + if (currentPath.isEmpty()) { + return null; + } + + LocalFileSystem fileSystem = LocalFileSystem.getInstance(); + VirtualFile dir; + while ((dir = fileSystem.refreshAndFindFileByPath(currentPath)) == null) { + currentPath = PathUtil.getParentPath(currentPath); + if (currentPath.isEmpty()) { + break; + } + } + if (dir == null) { + return null; + } + + Pair relativeParentPath = getModuleOrProjectRelativePath(project, dir); + if (relativeParentPath != null) { + String dirPath = dir.getPath(); + if (!filePath.startsWith(dirPath)) { + // shouldn't happen + return null; + } + return new Pair<>(relativeParentPath.first, relativeParentPath.second + filePath.substring(dirPath.length())); + } + return null; + } + @Nullable static Pair getModuleOrProjectRelativeParentPath(Project project, VirtualFile file) { VirtualFile parent = file.getParent(); @@ -200,13 +232,18 @@ public class TestDataUtil { return null; } - Module module = ModuleUtilCore.findModuleForFile(parent, project); + return getModuleOrProjectRelativePath(project, parent); + } + + @Nullable + private static Pair getModuleOrProjectRelativePath(Project project, VirtualFile file) { + Module module = ModuleUtilCore.findModuleForFile(file, project); if (module != null) { VirtualFile moduleFile = module.getModuleFile(); if (moduleFile != null) { VirtualFile moduleFileDir = moduleFile.getParent(); if (moduleFileDir != null) { - String moduleRelativePath = VfsUtilCore.getRelativePath(parent, moduleFileDir); + String moduleRelativePath = VfsUtilCore.getRelativePath(file, moduleFileDir); if (moduleRelativePath != null) { return new Pair<>(module.getName(), moduleRelativePath); } @@ -216,7 +253,7 @@ public class TestDataUtil { VirtualFile projectDir = project.getBaseDir(); if (projectDir != null) { - String projectRelativePath = VfsUtilCore.getRelativePath(parent, projectDir); + String projectRelativePath = VfsUtilCore.getRelativePath(file, projectDir); if (projectRelativePath != null) { return new Pair<>(project.getName(), projectRelativePath); } @@ -224,4 +261,37 @@ public class TestDataUtil { return null; } + + + @NotNull + static String getHtmlDisplayPathForMissingFile(Project project, String path) { + return getHtmlDisplayPathForRelativePathPair(getRelativePathPairForMissingFile(project, path)); + } + + /** + * @return pair of module/project name (or null if cannot be determined) and relative (or absolute) path. + */ + @NotNull + static Pair getRelativePathPairForMissingFile(Project project, String path) { + Pair relativePath = getModuleOrProjectRelativePath(project, path); + if (relativePath == null) { + return new Pair<>(null, path); + } + return relativePath; + } + + /** + * Returns the presentable path for passed pair of module/project name (or null) and relative (or absolute) path. HTML is used. + * @see #getRelativePathPairForMissingFile(Project, String) + */ + @NotNull + static String getHtmlDisplayPathForRelativePathPair(Pair relativePathPair) { + String base = relativePathPair.getFirst(); + if (base == null) { + return relativePathPair.getSecond(); + } + else { + return "" + base + "/" + relativePathPair.getSecond(); + } + } }