Skip to content

CM-48118 - Add detection sorting by line number in addition to severity #87

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

Merged
merged 2 commits into from
May 12, 2025
Merged
Show file tree
Hide file tree
Changes from all 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
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

## [Unreleased]

## [2.6.0] - 2025-05-12

- Add detection sorting by line number in addition to severity

## [2.5.0] - 2025-02-24

- Add proper support for disabled modules
Expand Down Expand Up @@ -147,6 +151,8 @@

The first public release of the plugin.

[2.6.0]: https://github.com/cycodehq/intellij-platform-plugin/releases/tag/v2.6.0

[2.5.0]: https://github.com/cycodehq/intellij-platform-plugin/releases/tag/v2.5.0

[2.4.1]: https://github.com/cycodehq/intellij-platform-plugin/releases/tag/v2.4.1
Expand Down Expand Up @@ -207,4 +213,4 @@ The first public release of the plugin.

[1.0.0]: https://github.com/cycodehq/intellij-platform-plugin/releases/tag/v1.0.0

[Unreleased]: https://github.com/cycodehq/intellij-platform-plugin/compare/v2.5.0...HEAD
[Unreleased]: https://github.com/cycodehq/intellij-platform-plugin/compare/v2.6.0...HEAD
2 changes: 1 addition & 1 deletion CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1 +1 @@
* @MarshalX @MichalBor @MaorDavidzon @artem-fedorov @elsapet @gotbadger @cfabianski
* @MarshalX @elsapet @gotbadger @cfabianski
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ pluginGroup = com.cycode.plugin
pluginName = Cycode
pluginRepositoryUrl = https://github.com/cycodehq/intellij-platform-plugin
# SemVer format -> https://semver.org
pluginVersion = 2.5.0
pluginVersion = 2.6.0

# Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
pluginSinceBuild = 231
pluginUntilBuild = 251.*
pluginUntilBuild = 252.*

# IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension
platformType = IC
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class IacApplier(private val scanResults: ScanResultsService) : AnnotationApplie
val severity = convertSeverity(detection.severity)

// IaC doesn't provide start and end positions, so we have to calculate them from the line number
val line = detection.detectionDetails.lineInFile - 1
val line = detection.detectionDetails.getLineNumber() - 1
val startOffset = psiFile.text.lines().take(line).sumOf { it.length + 1 }
val endOffset = startOffset + psiFile.text.lines()[line].length

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class SastApplier(private val scanResults: ScanResultsService) : AnnotationAppli
val severity = convertSeverity(detection.severity)

// SAST doesn't provide start and end positions, so we have to calculate them from the line number
val line = detection.detectionDetails.lineInFile - 1
val line = detection.detectionDetails.getLineNumber() - 1
val startOffset = psiFile.text.lines().take(line).sumOf { it.length + 1 }
val endOffset = startOffset + psiFile.text.lines()[line].length

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class ScaApplier(private val scanResults: ScanResultsService) : AnnotationApplie
val severity = convertSeverity(detection.severity)

// SCA doesn't provide start and end positions, so we have to calculate them from the line number
val line = detection.detectionDetails.lineInFile - 1
val line = detection.detectionDetails.getLineNumber() - 1
val startOffset = psiFile.text.lines().take(line).sumOf { it.length + 1 }
val endOffset = startOffset + psiFile.text.lines()[line].length

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@ package com.cycode.plugin.cli.models.scanResult

interface ScanDetectionDetailsBase {
fun getFilepath(): String
/**
* Gets the line number.
* @return The 1-based line number (first line is 1, not 0)
*/
fun getLineNumber(): Int
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ data class IacDetection(
}

override fun getFormattedNodeTitle(): String {
return CycodeBundle.message("iacNodeTitle", detectionDetails.lineInFile, getFormattedMessage())
return CycodeBundle.message("iacNodeTitle", detectionDetails.getLineNumber(), getFormattedMessage())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,8 @@ data class IacDetectionDetails(
override fun getFilepath(): String {
return fileName
}

override fun getLineNumber(): Int {
return lineInFile
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ data class SastDetection(
}

override fun getFormattedNodeTitle(): String {
return CycodeBundle.message("sastNodeTitle", detectionDetails.lineInFile, getFormattedMessage())
return CycodeBundle.message("sastNodeTitle", detectionDetails.getLineNumber(), getFormattedMessage())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,8 @@ data class SastDetectionDetails(
override fun getFilepath(): String {
return if (filePath.startsWith("/")) filePath else "/$filePath"
}

override fun getLineNumber(): Int {
return lineInFile
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ data class ScaDetection(
override fun getFormattedNodeTitle(): String {
return CycodeBundle.message(
"scaNodeTitle",
detectionDetails.lineInFile,
detectionDetails.getLineNumber(),
getFormattedTitle(),
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,8 @@ data class ScaDetectionDetails(
override fun getFilepath(): String {
return fileName
}

override fun getLineNumber(): Int {
return lineInFile
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package com.cycode.plugin.cli.models.scanResult.secret
import com.cycode.plugin.CycodeBundle
import com.cycode.plugin.cli.models.scanResult.DetectionBase

const val IDE_ENTRY_LINE_NUMBER = 1

data class SecretDetection(
override val id: String,
override val severity: String,
Expand All @@ -23,6 +21,6 @@ data class SecretDetection(
}

override fun getFormattedNodeTitle(): String {
return CycodeBundle.message("secretsNodeTitle", detectionDetails.line + IDE_ENTRY_LINE_NUMBER, type)
return CycodeBundle.message("secretsNodeTitle", detectionDetails.getLineNumber(), type)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.cycode.plugin.cli.models.scanResult.secret

import com.cycode.plugin.cli.models.scanResult.ScanDetectionDetailsBase

const val IDE_ENTRY_LINE_NUMBER = 1

data class SecretDetectionDetails(
val sha512: String,
val provider: String,
Expand All @@ -22,4 +24,8 @@ data class SecretDetectionDetails(
override fun getFilepath(): String {
return "$filePath$fileName"
}

override fun getLineNumber(): Int {
return line + IDE_ENTRY_LINE_NUMBER
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,11 @@ class TreeView(
createNodeCallback: (detection: DetectionBase) -> DefaultMutableTreeNode
) {
val filteredDetections = scanResults.detections.filter {
severityFilter?.getOrDefault(it.severity.lowercase(), true) ?: true
severityFilter?.getOrDefault(it.severity.lowercase(), true) != false
}
val sortedDetections = filteredDetections.sortedByDescending { getSeverityWeight(it.severity) }
val detectionsByFile = sortedDetections.groupBy { it.detectionDetails.getFilepath() }
val detectionsByFile = filteredDetections.groupBy { it.detectionDetails.getFilepath() }

rootNodes.setNodeSummary(scanType, getDetectionSummary(sortedDetections))
rootNodes.setNodeSummary(scanType, getDetectionSummary(filteredDetections))

val projectRoot = project.basePath?.let { File(it) } ?: File("")

Expand All @@ -173,7 +172,13 @@ class TreeView(
AllIcons.Actions.Annotate

val fileNode = createNode(FileNode(projectRelativePath, summary, icon))
for (detection in detections) {

val sortedDetections = detections.sortedWith(
compareByDescending<DetectionBase> { getSeverityWeight(it.severity) }
.thenBy { it.detectionDetails.getLineNumber() }
)

for (detection in sortedDetections) {
fileNode.add(createNodeCallback(detection))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ import com.intellij.psi.PsiFile
import com.intellij.psi.PsiManager
import java.io.File

const val DIFFERENCE_BETWEEN_SCA_LINE_NUMBERS = 1
const val DIFFERENCE_BETWEEN_IAC_LINE_NUMBERS = 1
const val DIFFERENCE_BETWEEN_SAST_LINE_NUMBERS = 1
const val DIFFERENCE_BETWEEN_CYCODE_AND_IDE_LINE_NUMBER = 1

fun getPsiFile(project: Project, filePath: String): PsiFile? {
val virtualFile = VirtualFileManager.getInstance().findFileByUrl("file://$filePath") ?: return null
Expand All @@ -31,25 +29,25 @@ private fun openFileInEditor(project: Project, filePath: String, lineNumber: Int

private fun openSecretDetectionInFile(project: Project, node: SecretDetectionNode) {
val filePath = node.detection.detectionDetails.getFilepath()
val line = node.detection.detectionDetails.line
val line = node.detection.detectionDetails.getLineNumber() - DIFFERENCE_BETWEEN_CYCODE_AND_IDE_LINE_NUMBER
openFileInEditor(project, filePath, line)
}

private fun openScaDetectionInFile(project: Project, node: ScaDetectionNode) {
val filePath = node.detection.detectionDetails.getFilepath()
val line = node.detection.detectionDetails.lineInFile - DIFFERENCE_BETWEEN_SCA_LINE_NUMBERS
val line = node.detection.detectionDetails.getLineNumber() - DIFFERENCE_BETWEEN_CYCODE_AND_IDE_LINE_NUMBER
openFileInEditor(project, filePath, line)
}

private fun openIacDetectionInFile(project: Project, node: IacDetectionNode) {
val filePath = node.detection.detectionDetails.getFilepath()
val line = node.detection.detectionDetails.lineInFile - DIFFERENCE_BETWEEN_IAC_LINE_NUMBERS
val line = node.detection.detectionDetails.getLineNumber() - DIFFERENCE_BETWEEN_CYCODE_AND_IDE_LINE_NUMBER
openFileInEditor(project, filePath, line)
}

private fun openSastDetectionInFile(project: Project, node: SastDetectionNode) {
val filePath = node.detection.detectionDetails.getFilepath()
val line = node.detection.detectionDetails.lineInFile - DIFFERENCE_BETWEEN_SAST_LINE_NUMBERS
val line = node.detection.detectionDetails.getLineNumber() - DIFFERENCE_BETWEEN_CYCODE_AND_IDE_LINE_NUMBER
openFileInEditor(project, filePath, line)
}

Expand Down