From 353935ad19cfee89ec1ebebb10247fa15799d8db Mon Sep 17 00:00:00 2001 From: Eyal Kapon Date: Mon, 23 Sep 2024 14:26:47 +0300 Subject: [PATCH] Fixed dependency tree right click action (#483) --- .../idea/inspections/AbstractInspection.java | 17 +++++++++++-- .../inspections/GradleGroovyInspection.java | 11 +++++---- .../inspections/GradleKotlinInspection.java | 9 +++---- .../ide/idea/inspections/MavenInspection.java | 7 +++--- .../idea/navigation/NavigationService.java | 1 + .../ide/idea/ui/LocalComponentsTree.java | 24 +++++++++++++++---- .../GradleGroovyInspectionTest.java | 14 +++++------ .../inspections/GradleInspectionTest.java | 2 +- .../GradleKotlinInspectionTest.java | 4 ++-- .../idea/inspections/MavenInspectionTest.java | 6 ++--- 10 files changed, 63 insertions(+), 32 deletions(-) diff --git a/src/main/java/com/jfrog/ide/idea/inspections/AbstractInspection.java b/src/main/java/com/jfrog/ide/idea/inspections/AbstractInspection.java index cdf9570b..40a21fc3 100644 --- a/src/main/java/com/jfrog/ide/idea/inspections/AbstractInspection.java +++ b/src/main/java/com/jfrog/ide/idea/inspections/AbstractInspection.java @@ -180,6 +180,7 @@ boolean isShowInspection(PsiElement element) { return false; // File is not a package descriptor file } + ScannerBase scanner = getScanner(project, editorFile.getParent().getPath()); if (scanner == null) { return false; // Scan manager for this project not yet created @@ -234,7 +235,8 @@ private List getMatchDependencies(DescriptorFileTreeNode file, S boolean isNodeMatch(DependencyNode node, String componentName) { String artifactID = node.getComponentIdWithoutPrefix(); ImpactTree impactTree = node.getImpactTree(); - return StringUtils.equals(artifactID, componentName) || impactTree.contains(componentName); + String versionPrefix = ":"; + return StringUtils.equals(extractArtifactIdWithoutVersion(artifactID), componentName) || impactTree.contains(componentName+versionPrefix); } abstract UpgradeVersion getUpgradeVersion(String componentName, String fixVersion, Collection issues, String descriptorPath); @@ -296,4 +298,15 @@ protected static String convertFixVersionStringToMinFixVersion(String fixVersion fixVersion = StringUtils.strip(fixVersion, "]"); return fixVersion; } -} + + + private String extractArtifactIdWithoutVersion(String artifact) { + int versionIndex = artifact.lastIndexOf(':'); + + if (versionIndex != -1) { + return artifact.substring(0, versionIndex); + } else { + return artifact; + } + } + } \ No newline at end of file diff --git a/src/main/java/com/jfrog/ide/idea/inspections/GradleGroovyInspection.java b/src/main/java/com/jfrog/ide/idea/inspections/GradleGroovyInspection.java index d627bc7b..f09c6186 100644 --- a/src/main/java/com/jfrog/ide/idea/inspections/GradleGroovyInspection.java +++ b/src/main/java/com/jfrog/ide/idea/inspections/GradleGroovyInspection.java @@ -43,7 +43,12 @@ public GradleGroovyInspection() { * @return the value of the literal */ public static String getLiteralValue(GrLiteral literal) { - return Objects.toString((literal).getValue(), ""); + String artifact = Objects.toString((literal).getValue(), ""); + int versionIndex = artifact.lastIndexOf(':'); + if (versionIndex == -1) { + return artifact; + } + return artifact.substring(0, versionIndex); } public static boolean isNamedArgumentComponent(PsiElement element) { @@ -117,9 +122,7 @@ String createComponentName(PsiElement element) { // implementation group: 'j', name: 'k', version: 'l' return String.join(":", extractExpression(element, GRADLE_GROUP_KEY), - extractExpression(element, GRADLE_NAME_KEY), - extractExpression(element, GRADLE_VERSION_KEY) - ); + extractExpression(element, GRADLE_NAME_KEY)); } if (element instanceof GrLiteral) { // implementation 'g:h:i' diff --git a/src/main/java/com/jfrog/ide/idea/inspections/GradleKotlinInspection.java b/src/main/java/com/jfrog/ide/idea/inspections/GradleKotlinInspection.java index 38d33e9a..77dbda1f 100644 --- a/src/main/java/com/jfrog/ide/idea/inspections/GradleKotlinInspection.java +++ b/src/main/java/com/jfrog/ide/idea/inspections/GradleKotlinInspection.java @@ -77,14 +77,15 @@ String createComponentName(PsiElement element) { List argumentList = ((KtValueArgumentList) element).getArguments(); if (argumentList.size() == 1) { // "commons-collections:commons-collections:3.2.2" - return extractArgument(argumentList.get(0)); + String artifactId = extractArgument(argumentList.get(0)); + return StringUtils.substringBeforeLast(artifactId, ":"); } if (argumentList.size() >= 3) { - // "commons-collections", "commons-collections", "3.2.2" + // "commons-collections", "commons-collections" return String.join(":", extractArgument(argumentList.get(0)), - extractArgument(argumentList.get(1)), - extractArgument(argumentList.get(2))); + extractArgument(argumentList.get(1)) + ); } return ""; } diff --git a/src/main/java/com/jfrog/ide/idea/inspections/MavenInspection.java b/src/main/java/com/jfrog/ide/idea/inspections/MavenInspection.java index 993a6f76..eef7c463 100644 --- a/src/main/java/com/jfrog/ide/idea/inspections/MavenInspection.java +++ b/src/main/java/com/jfrog/ide/idea/inspections/MavenInspection.java @@ -19,9 +19,7 @@ import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.idea.maven.dom.model.MavenDomArtifactCoordinates; - import java.util.Collection; - /** * @author yahavi */ @@ -92,8 +90,7 @@ String createComponentName(PsiElement element) { } DomElement domElement = DomManager.getDomManager(element.getProject()).getDomElement((XmlTag) element); if (domElement instanceof MavenDomArtifactCoordinates) { - String version = ((MavenDomArtifactCoordinates) domElement).getVersion().getStringValue(); - return String.join(":", groupId.getValue().getText(), artifactId.getValue().getText(), version); + return String.join(":", groupId.getValue().getText(), artifactId.getValue().getText()); } return null; } @@ -102,4 +99,6 @@ String createComponentName(PsiElement element) { UpgradeVersion getUpgradeVersion(String componentName, String fixVersion, Collection issue, String descriptorPath) { return new MavenUpgradeVersion(componentName, fixVersion, issue); } + } + diff --git a/src/main/java/com/jfrog/ide/idea/navigation/NavigationService.java b/src/main/java/com/jfrog/ide/idea/navigation/NavigationService.java index 5b6af74e..8a3eb791 100644 --- a/src/main/java/com/jfrog/ide/idea/navigation/NavigationService.java +++ b/src/main/java/com/jfrog/ide/idea/navigation/NavigationService.java @@ -51,6 +51,7 @@ public void addNavigation(DependencyNode treeNode, PsiElement navigationTargetEl Set navigationTargets = navigationMap.get(treeNode); if (navigationTargets == null) { navigationTargets = new HashSet<>(Collections.singletonList(navigationTarget)); + navigationMap.put(treeNode, navigationTargets); return; } diff --git a/src/main/java/com/jfrog/ide/idea/ui/LocalComponentsTree.java b/src/main/java/com/jfrog/ide/idea/ui/LocalComponentsTree.java index a4a7688f..5acb81e4 100644 --- a/src/main/java/com/jfrog/ide/idea/ui/LocalComponentsTree.java +++ b/src/main/java/com/jfrog/ide/idea/ui/LocalComponentsTree.java @@ -29,6 +29,7 @@ import java.io.IOException; import java.util.*; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; /** * @author yahavi @@ -108,24 +109,29 @@ private void handleContextMenu(ComponentsTree tree, MouseEvent e) { return; } // Event is right-click. + TreePath selectedPath = tree.getPathForRow(tree.getClosestRowForLocation(e.getX(), e.getY())); if (selectedPath == null) { return; } Object selected = selectedPath.getLastPathComponent(); + + // Create the popup menu if clicked on a package. if it's a vulnerability, create ignore rule option. if (selected instanceof DependencyNode) { - createNodePopupMenu((DependencyNode) selected); + DescriptorFileTreeNode descriptorFileTreeNode = (DescriptorFileTreeNode) selectedPath.getParentPath().getLastPathComponent(); + String descriptorPath = descriptorFileTreeNode.getSubtitle(); + createNodePopupMenu((DependencyNode) selected, descriptorPath); } else if (selected instanceof VulnerabilityNode) { createIgnoreRuleOption((VulnerabilityNode) selected, e); } else if (selected instanceof ApplicableIssueNode) { createIgnoreRuleOption(((ApplicableIssueNode) selected).getIssue(), e); } else { - // No context menu was created. return; } popupMenu.show(tree, e.getX(), e.getY()); } + private void createIgnoreRuleOption(VulnerabilityNode selectedIssue, MouseEvent mouseEvent) { popupMenu.removeAll(); popupMenu.add(new CreateIgnoreRuleAction(selectedIssue.getIgnoreRuleUrl(), mouseEvent)); @@ -134,12 +140,20 @@ private void createIgnoreRuleOption(VulnerabilityNode selectedIssue, MouseEvent toolTip.setEnabled(true); } - private void createNodePopupMenu(DependencyNode selectedNode) { + private void createNodePopupMenu(DependencyNode selectedNode, String descriptorPath) { popupMenu.removeAll(); NavigationService navigationService = NavigationService.getInstance(project); Set navigationCandidates = navigationService.getNavigation(selectedNode); + //filtering candidates in case of multi module project + Set filteredCandidates = navigationCandidates.stream() + .filter(navigationTarget -> + descriptorPath.equals(navigationTarget.getElement() + .getContainingFile() + .getVirtualFile() + .getPath())) + .collect(Collectors.toSet()); - addNodeNavigation(navigationCandidates); + addNodeNavigation(filteredCandidates); } private void addNodeNavigation(Set navigationCandidates) { @@ -259,4 +273,4 @@ public void setNoIssuesEmptyText() { public void setScanErrorEmptyText() { SwingUtilities.invokeLater(() -> getEmptyText().setText(ERROR_WHILE_SCANNING)); } -} +} \ No newline at end of file diff --git a/src/test/java/com/jfrog/ide/idea/inspections/GradleGroovyInspectionTest.java b/src/test/java/com/jfrog/ide/idea/inspections/GradleGroovyInspectionTest.java index c1a29745..eb0fe149 100644 --- a/src/test/java/com/jfrog/ide/idea/inspections/GradleGroovyInspectionTest.java +++ b/src/test/java/com/jfrog/ide/idea/inspections/GradleGroovyInspectionTest.java @@ -17,13 +17,13 @@ public class GradleGroovyInspectionTest extends InspectionsTestBase { // files as groovy-script. private static final String PACKAGE_DESCRIPTOR = "build.groovy"; private final InspectionTestDependency[] DEPENDENCIES = { - new InspectionTestDependency(96, "a", "b:c"), - new InspectionTestDependency(139, "d", "e:f"), - new InspectionTestDependency(180, "g", "h:i"), - new InspectionTestDependency(200, "j", "k:l"), - new InspectionTestDependency(225, "m", "n:o"), - new InspectionTestDependency(320, "net.lingala.zip4j", "zip4j:2.3.0"), - new InspectionTestDependency(390, "org.codehaus.groovy", "groovy-all:3.0.5"), + new InspectionTestDependency(96, "a", "b"), + new InspectionTestDependency(139, "d", "e"), + new InspectionTestDependency(180, "g", "h"), + new InspectionTestDependency(200, "j", "k"), + new InspectionTestDependency(225, "m", "n"), + new InspectionTestDependency(320, "net.lingala.zip4j", "zip4j"), + new InspectionTestDependency(390, "org.codehaus.groovy", "groovy-all"), }; @SuppressWarnings("MethodDoesntCallSuperMethod") diff --git a/src/test/java/com/jfrog/ide/idea/inspections/GradleInspectionTest.java b/src/test/java/com/jfrog/ide/idea/inspections/GradleInspectionTest.java index cfd27862..27df7ab5 100644 --- a/src/test/java/com/jfrog/ide/idea/inspections/GradleInspectionTest.java +++ b/src/test/java/com/jfrog/ide/idea/inspections/GradleInspectionTest.java @@ -23,7 +23,7 @@ public static Collection data() { return Arrays.asList(new Object[][]{ {"a:b:c", "a:b"}, {"a:b:c:d", "a:b"}, - {"a:b", "a:b"}, + {"a", "a"}, {"xyz", "xyz"} }); } diff --git a/src/test/java/com/jfrog/ide/idea/inspections/GradleKotlinInspectionTest.java b/src/test/java/com/jfrog/ide/idea/inspections/GradleKotlinInspectionTest.java index f8543e33..64419792 100644 --- a/src/test/java/com/jfrog/ide/idea/inspections/GradleKotlinInspectionTest.java +++ b/src/test/java/com/jfrog/ide/idea/inspections/GradleKotlinInspectionTest.java @@ -11,8 +11,8 @@ public class GradleKotlinInspectionTest extends InspectionsTestBase { // files as groovy-script. private static final String PACKAGE_DESCRIPTOR = "build.gradle.kts"; private final InspectionTestDependency[] DEPENDENCIES = { - new InspectionTestDependency(119, "a", "b:c"), - new InspectionTestDependency(144, "d", "e:f"), + new InspectionTestDependency(119, "a", "b"), + new InspectionTestDependency(144, "d", "e"), }; private final int[] NON_DEPENDENCIES_POSITIONS = {273, 338}; diff --git a/src/test/java/com/jfrog/ide/idea/inspections/MavenInspectionTest.java b/src/test/java/com/jfrog/ide/idea/inspections/MavenInspectionTest.java index efee600c..32024b0f 100644 --- a/src/test/java/com/jfrog/ide/idea/inspections/MavenInspectionTest.java +++ b/src/test/java/com/jfrog/ide/idea/inspections/MavenInspectionTest.java @@ -9,9 +9,9 @@ public class MavenInspectionTest extends InspectionsTestBase { private static final String PACKAGE_DESCRIPTOR = "pom.xml"; private final InspectionTestDependency[] DEPENDENCIES = { - new InspectionTestDependency(550, "a", "b:c"), - new InspectionTestDependency(788, "d", "e:f"), - new InspectionTestDependency(990, "g", "h:i"), + new InspectionTestDependency(550, "a", "b"), + new InspectionTestDependency(788, "d", "e"), + new InspectionTestDependency(990, "g", "h"), }; private final int[] NON_DEPENDENCIES_POSITIONS = {397, 1197, 1258};