Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: don't use scss for open source #627

Merged
merged 6 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ repositories {
dependencies {
implementation(platform("com.squareup.okhttp3:okhttp-bom:4.12.0"))
implementation(platform("com.squareup.retrofit2:retrofit-bom:2.11.0"))
implementation("org.eclipse.lsp4j:org.eclipse.lsp4j:0.22.0")
implementation("org.eclipse.lsp4j:org.eclipse.lsp4j:0.23.1")

implementation("org.commonmark:commonmark:0.21.0")
implementation("com.google.code.gson:gson:2.10.1")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class GenerateAIFixHandler() {
val aiFixQuery = JBCefJSQuery.create(jbCefBrowser)

aiFixQuery.addHandler { value ->
val params = value.split(":")
val params = value.split("@|@")
val folderURI = params[0]
val fileURI = params[1]
val issueID = params[2]
Expand Down Expand Up @@ -54,15 +54,15 @@ class GenerateAIFixHandler() {
const filePath = aiFixButton.getAttribute('file-path');

aiFixButton.addEventListener('click', () => {
window.aiFixQuery(folderPath + ":" + filePath + ":" + issueId);
window.aiFixQuery(folderPath + "@|@" + filePath + "@|@" + issueId);
});

retryFixButton.addEventListener('click', () => {
window.aiFixQuery(folderPath + ":" + filePath + ":" + issueId);
window.aiFixQuery(folderPath + "@|@" + filePath + "@|@" + issueId);
});

retryFixButton.addEventListener('click', () => {
window.aiFixQuery(folderPath + ":" + filePath + ":" + issueId);
window.aiFixQuery(folderPath + "@|@" + filePath + "@|@" + issueId);
});
})();
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ import io.snyk.plugin.ui.toolwindow.panels.StatePanel
import io.snyk.plugin.ui.toolwindow.panels.TreePanel
import io.snyk.plugin.ui.wrapWithScrollPane
import org.jetbrains.annotations.TestOnly
import org.jetbrains.concurrency.runAsync
import snyk.common.ProductType
import snyk.common.SnykError
import snyk.common.lsp.LanguageServerWrapper
Expand All @@ -79,6 +80,7 @@ import java.awt.BorderLayout
import java.util.Objects.nonNull
import javax.swing.JPanel
import javax.swing.JScrollPane
import javax.swing.event.TreeSelectionEvent
import javax.swing.tree.DefaultMutableTreeNode
import javax.swing.tree.DefaultTreeModel
import javax.swing.tree.TreePath
Expand All @@ -93,7 +95,7 @@ class SnykToolWindowPanel(
Disposable {
private val descriptionPanel = SimpleToolWindowPanel(true, true).apply { name = "descriptionPanel" }
private val logger = Logger.getInstance(this::class.java)
private val rootTreeNode = ChooseBranchNode(project = project)
private val rootTreeNode = ChooseBranchNode(project = project)
private val rootOssTreeNode = RootOssTreeNode(project)
private val rootSecurityIssuesTreeNode = RootSecurityIssuesTreeNode(project)
private val rootQualityIssuesTreeNode = RootQualityIssuesTreeNode(project)
Expand Down Expand Up @@ -129,10 +131,10 @@ class SnykToolWindowPanel(
}



init {
val folderConfig = service<FolderConfigSettings>().getFolderConfig(project.basePath.toString())
val rootNodeText = folderConfig?.let { getRootNodeText(it.folderPath, it.baseBranch) } ?: "Choose branch on ${project.basePath}"
val rootNodeText = folderConfig?.let { getRootNodeText(it.folderPath, it.baseBranch) }
?: "Choose branch on ${project.basePath}"
rootTreeNode.info = rootNodeText

vulnerabilitiesTree.cellRenderer = SnykTreeCellRenderer()
Expand All @@ -148,8 +150,10 @@ class SnykToolWindowPanel(
createTreeAndDescriptionPanel()
chooseMainPanelToDisplay()

vulnerabilitiesTree.selectionModel.addTreeSelectionListener {
updateDescriptionPanelBySelectedTreeNode()
vulnerabilitiesTree.selectionModel.addTreeSelectionListener { treeSelectionEvent ->
runAsync {
updateDescriptionPanelBySelectedTreeNode(treeSelectionEvent)
}
}

val scanListenerLS =
Expand Down Expand Up @@ -316,45 +320,74 @@ class SnykToolWindowPanel(
)
}

private fun updateDescriptionPanelBySelectedTreeNode() {
private fun updateDescriptionPanelBySelectedTreeNode(treeSelectionEvent: TreeSelectionEvent) {
val capturedSmartReloadMode = smartReloadMode
val capturedNavigateToSourceEnabled = triggerSelectionListeners

ApplicationManager.getApplication().invokeLater {
descriptionPanel.removeAll()
val selectionPath = vulnerabilitiesTree.selectionPath
if (nonNull(selectionPath)) {
val lastPathComponent = selectionPath!!.lastPathComponent
val selectionPath = treeSelectionEvent.path
if (nonNull(selectionPath) && treeSelectionEvent.isAddedPath) {
val lastPathComponent = selectionPath.lastPathComponent

if (lastPathComponent is ChooseBranchNode && capturedNavigateToSourceEnabled && !capturedSmartReloadMode) {
if (lastPathComponent is ChooseBranchNode && capturedNavigateToSourceEnabled && !capturedSmartReloadMode) {
invokeLater {
BranchChooserComboBoxDialog(project).show()
}
}

if (!capturedSmartReloadMode &&
capturedNavigateToSourceEnabled &&
lastPathComponent is NavigatableToSourceTreeNode
) {
lastPathComponent.navigateToSource()
}
when (val selectedNode: DefaultMutableTreeNode = lastPathComponent as DefaultMutableTreeNode) {
is DescriptionHolderTreeNode -> {
if (!capturedSmartReloadMode &&
capturedNavigateToSourceEnabled &&
lastPathComponent is NavigatableToSourceTreeNode
) {
lastPathComponent.navigateToSource()
}
when (val selectedNode: DefaultMutableTreeNode = lastPathComponent as DefaultMutableTreeNode) {
is DescriptionHolderTreeNode -> {
if (selectedNode is SuggestionTreeNode) {
val cache = getSnykCachedResults(project) ?: return
val issue = selectedNode.issue
val productIssues = when (issue.filterableIssueType) {
ScanIssue.CODE_SECURITY, ScanIssue.CODE_QUALITY -> cache.currentSnykCodeResultsLS
ScanIssue.OPEN_SOURCE -> cache.currentOSSResultsLS
ScanIssue.INFRASTRUCTURE_AS_CODE -> cache.currentIacResultsLS
ScanIssue.CONTAINER -> cache.currentContainerResultsLS
else -> {
emptyMap()
}
}
productIssues.values.flatten().filter { issue.id == it.id }.forEach { _ ->
val newDescriptionPanel = selectedNode.getDescriptionPanel()
descriptionPanel.removeAll()
descriptionPanel.add(
newDescriptionPanel,
BorderLayout.CENTER,
)
}
} else {
descriptionPanel.removeAll()
descriptionPanel.add(
selectedNode.getDescriptionPanel(),
BorderLayout.CENTER,
)
}

is ErrorHolderTreeNode -> {
selectedNode.getSnykError()?.let {
displaySnykError(it)
} ?: displayEmptyDescription()
}
}

else -> displayEmptyDescription()
is ErrorHolderTreeNode -> {
descriptionPanel.removeAll()
selectedNode.getSnykError()?.let {
displaySnykError(it)
} ?: displayEmptyDescription()
}

else -> {
descriptionPanel.removeAll()
displayEmptyDescription()
}
} else {
displayEmptyDescription()
}
} else {
displayEmptyDescription()
}
invokeLater {
descriptionPanel.revalidate()
descriptionPanel.repaint()
}
Expand Down Expand Up @@ -842,9 +875,6 @@ class SnykToolWindowPanel(
smartReloadMode = true
try {
selectedNode?.let { TreeUtil.selectNode(vulnerabilitiesTree, it) }
// for some reason TreeSelectionListener is not initiated here on node selection
// also we need to update Description panel in case if no selection was made before
updateDescriptionPanelBySelectedTreeNode()
} finally {
smartReloadMode = false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import io.snyk.plugin.events.SnykScanListenerLS
import io.snyk.plugin.getSnykCachedResults
import io.snyk.plugin.pluginSettings
import io.snyk.plugin.refreshAnnotationsForOpenFiles
import io.snyk.plugin.ui.expandTreeNodeRecursively
import io.snyk.plugin.ui.toolwindow.SnykToolWindowPanel.Companion.CODE_QUALITY_ROOT_TEXT
import io.snyk.plugin.ui.toolwindow.SnykToolWindowPanel.Companion.CODE_SECURITY_ROOT_TEXT
import io.snyk.plugin.ui.toolwindow.SnykToolWindowPanel.Companion.IAC_ROOT_TEXT
Expand Down Expand Up @@ -336,16 +337,12 @@ class SnykToolWindowSnykScanListenerLS(
}

val settings = pluginSettings()
var text = "✅ Congrats! No vulnerabilities found!"
var text = "✅ Congrats! No issues found!"
val issuesCount = issues.size
val ignoredIssuesCount = issues.count { it.isIgnored() }
if (issuesCount != 0) {
val plural = if (issuesCount == 1) {
"y"
} else {
"ies"
}
text = "✋ $issuesCount vulnerabilit$plural found by Snyk"
val plural = getPlural(issuesCount)
text = "✋ $issuesCount issue$plural found by Snyk"
if (pluginSettings().isGlobalIgnoresFeatureEnabled) {
text += ", $ignoredIssuesCount ignored"
}
Expand All @@ -359,15 +356,16 @@ class SnykToolWindowSnykScanListenerLS(

if (fixableIssuesCount != null) {
if (fixableIssuesCount > 0) {
val plural = getPlural(fixableIssuesCount)
rootNode.add(
InfoTreeNode(
"⚡ $fixableIssuesCount vulnerabilities can be fixed automatically",
"⚡ $fixableIssuesCount issue$plural can be fixed automatically",
project,
),
)
} else {
rootNode.add(
InfoTreeNode("There are no vulnerabilities automatically fixable", project),
InfoTreeNode("There are no issues automatically fixable", project),
)
}
}
Expand All @@ -390,6 +388,12 @@ class SnykToolWindowSnykScanListenerLS(
}
}

private fun getPlural(issuesCount: Int) = if (issuesCount > 1) {
"s"
} else {
""
}

private fun displayResultsForRootTreeNode(
rootNode: DefaultMutableTreeNode,
issues: Map<SnykFile, List<ScanIssue>>,
Expand Down Expand Up @@ -422,12 +426,14 @@ class SnykToolWindowSnykScanListenerLS(
.forEach { issue ->
fileTreeNode.add(
SuggestionTreeNode(
project,
issue,
navigateToSource(entry.key.virtualFile, issue.textRange ?: TextRange(0, 0)),
),
)
}
}
expandTreeNodeRecursively(snykToolWindowPanel.vulnerabilitiesTree, rootNode)
}

private fun buildSeveritiesPostfixForFileNode(results: Map<SnykFile, List<ScanIssue>>): String {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,20 @@
package io.snyk.plugin.ui.toolwindow.nodes.leaf

import io.snyk.plugin.SnykFile
import com.intellij.openapi.project.Project
import io.snyk.plugin.ui.toolwindow.nodes.DescriptionHolderTreeNode
import io.snyk.plugin.ui.toolwindow.nodes.NavigatableToSourceTreeNode
import io.snyk.plugin.ui.toolwindow.nodes.secondlevel.SnykFileTreeNode
import io.snyk.plugin.ui.toolwindow.panels.IssueDescriptionPanelBase
import io.snyk.plugin.ui.toolwindow.panels.SuggestionDescriptionPanelFromLS
import snyk.common.ProductType
import snyk.common.lsp.ScanIssue
import javax.swing.tree.DefaultMutableTreeNode

class SuggestionTreeNode(
private val issue: ScanIssue,
val project: Project,
val issue: ScanIssue,
override val navigateToSource: () -> Unit
) : DefaultMutableTreeNode(issue), NavigatableToSourceTreeNode, DescriptionHolderTreeNode {

@Suppress("UNCHECKED_CAST")
override fun getDescriptionPanel(): IssueDescriptionPanelBase {
val snykFileTreeNode = this.parent as? SnykFileTreeNode
?: throw IllegalArgumentException(this.toString())

@Suppress("UNCHECKED_CAST")
val entry =
(snykFileTreeNode.userObject as Pair<Map.Entry<SnykFile, List<ScanIssue>>, ProductType>).first
val snykFile = entry.key
return SuggestionDescriptionPanelFromLS(snykFile, issue)
return SuggestionDescriptionPanelFromLS(project, issue)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ package io.snyk.plugin.ui.toolwindow.panels

import com.intellij.openapi.editor.colors.EditorColors
import com.intellij.openapi.editor.colors.EditorColorsManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.uiDesigner.core.GridLayoutManager
import com.intellij.util.ui.JBUI
import com.intellij.util.ui.UIUtil
import io.snyk.plugin.SnykFile
import io.snyk.plugin.toVirtualFile
import io.snyk.plugin.ui.DescriptionHeaderPanel
import io.snyk.plugin.ui.SnykBalloonNotificationHelper
Expand All @@ -31,13 +31,12 @@ import javax.swing.JPanel
import kotlin.collections.set

class SuggestionDescriptionPanelFromLS(
snykFile: SnykFile,
val project: Project,
private val issue: ScanIssue,
) : IssueDescriptionPanelBase(
title = issue.title(),
severity = issue.getSeverityAsEnum(),
) {
val project = snykFile.project
private val unexpectedErrorMessage =
"Snyk encountered an issue while rendering the vulnerability description. Please try again, or contact support if the problem persists. We apologize for any inconvenience caused."

Expand All @@ -57,7 +56,7 @@ class SuggestionDescriptionPanelFromLS(
virtualFiles[dataFlow.filePath] = dataFlow.filePath.toVirtualFile()
}

val openFileLoadHandlerGenerator = OpenFileLoadHandlerGenerator(snykFile.project, virtualFiles)
val openFileLoadHandlerGenerator = OpenFileLoadHandlerGenerator(project, virtualFiles)
loadHandlerGenerators += {
openFileLoadHandlerGenerator.generate(it)
}
Expand All @@ -67,7 +66,7 @@ class SuggestionDescriptionPanelFromLS(
generateAIFixHandler.generateAIFixCommand(it)
}

val applyFixHandler = ApplyFixHandler(snykFile.project)
val applyFixHandler = ApplyFixHandler(project)
loadHandlerGenerators += {
applyFixHandler.generateApplyFixCommand(it)
}
Expand Down Expand Up @@ -161,7 +160,6 @@ class SuggestionDescriptionPanelFromLS(
// TODO: remove custom stylesheets, deliver variables from LS, replace variables with colors
val ideStyle: String = when (issue.filterableIssueType) {
ScanIssue.CODE_SECURITY, ScanIssue.CODE_QUALITY -> SnykStylesheets.SnykCodeSuggestion
ScanIssue.OPEN_SOURCE -> SnykStylesheets.SnykOSSSuggestion
else -> ""
}

Expand All @@ -178,17 +176,27 @@ class SuggestionDescriptionPanelFromLS(
html = html.replace("--default-font: ", "--default-font: \"${JBUI.Fonts.label().asPlain().family}\", ")
html = html.replace("var(--text-color)", UIUtil.getLabelForeground().toHex())
html = html.replace("var(--background-color)", UIUtil.getPanelBackground().toHex())
html =
html.replace("var(--border-color)", JBUI.CurrentTheme.CustomFrameDecorations.separatorForeground().toHex())
val borderColor = JBUI.CurrentTheme.CustomFrameDecorations.separatorForeground().toHex()
html = html.replace("var(--border-color)", borderColor)
html = html.replace("var(--horizontal-border-color)", borderColor)
html = html.replace("var(--link-color)", JBUI.CurrentTheme.Link.Foreground.ENABLED.toHex())

val editorBackground =
editorUiTheme.getColor(EditorColors.GUTTER_BACKGROUND)?.toHex() ?: editorUiTheme.defaultBackground.toHex()
html = html.replace(
"var(--horizontal-border-color)",
JBUI.CurrentTheme.CustomFrameDecorations.separatorForeground().toHex()
"var(--code-background-color)",
editorBackground
)
html = html.replace(
"var(--code-background-color)",
editorUiTheme.getColor(EditorColors.GUTTER_BACKGROUND)?.toHex() ?: editorUiTheme.defaultBackground.toHex()
"var(--container-background-color)",
editorBackground
)

html = html.replace(
"var(--editor-color)",
editorBackground
)

return html
}

Expand Down
Loading
Loading