From e784be7017b611b3b32a2e683602740ef9bbd1b7 Mon Sep 17 00:00:00 2001 From: Catalina Oyaneder Date: Thu, 21 Mar 2024 07:36:57 +0000 Subject: [PATCH] fix: fetch feature flag status during LanguageServerWrapper initialisation --- .../SnykApplicationSettingsStateService.kt | 1 + .../settings/SnykProjectSettingsConfigurable.kt | 5 +++-- .../snyk/common/lsp/LanguageServerWrapper.kt | 17 +++++++++++------ .../snyk/common/lsp/SnykLanguageClient.kt | 3 ++- .../common/lsp/LanguageServerWrapperTest.kt | 13 ++++++++++--- 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/main/kotlin/io/snyk/plugin/services/SnykApplicationSettingsStateService.kt b/src/main/kotlin/io/snyk/plugin/services/SnykApplicationSettingsStateService.kt index facf7d5f5..bf6438dae 100644 --- a/src/main/kotlin/io/snyk/plugin/services/SnykApplicationSettingsStateService.kt +++ b/src/main/kotlin/io/snyk/plugin/services/SnykApplicationSettingsStateService.kt @@ -27,6 +27,7 @@ import java.util.UUID ) class SnykApplicationSettingsStateService : PersistentStateComponent { + var isGlobalIgnoresFeatureEnabled = false var cliBaseDownloadURL: String = "https://static.snyk.io" var cliPath: String = getPluginPath() + separator + Platform.current().snykWrapperFileName var manageBinariesAutomatically: Boolean = true diff --git a/src/main/kotlin/io/snyk/plugin/settings/SnykProjectSettingsConfigurable.kt b/src/main/kotlin/io/snyk/plugin/settings/SnykProjectSettingsConfigurable.kt index 74b17b27d..704d3f901 100644 --- a/src/main/kotlin/io/snyk/plugin/settings/SnykProjectSettingsConfigurable.kt +++ b/src/main/kotlin/io/snyk/plugin/settings/SnykProjectSettingsConfigurable.kt @@ -99,8 +99,9 @@ class SnykProjectSettingsConfigurable(val project: Project) : SearchableConfigur snykProjectSettingsService?.additionalParameters = snykSettingsDialog.getAdditionalParameters() } - val params = DidChangeConfigurationParams(LanguageServerWrapper.getInstance().getSettings()) - LanguageServerWrapper.getInstance().languageServer.workspaceService.didChangeConfiguration(params) + val wrapper = LanguageServerWrapper.getInstance() + val params = DidChangeConfigurationParams(wrapper.getSettings()) + wrapper.languageServer.workspaceService.didChangeConfiguration(params) if (rescanNeeded) { getSnykToolWindowPanel(project)?.cleanUiAndCaches() diff --git a/src/main/kotlin/snyk/common/lsp/LanguageServerWrapper.kt b/src/main/kotlin/snyk/common/lsp/LanguageServerWrapper.kt index 1d10634bc..530146264 100644 --- a/src/main/kotlin/snyk/common/lsp/LanguageServerWrapper.kt +++ b/src/main/kotlin/snyk/common/lsp/LanguageServerWrapper.kt @@ -1,6 +1,7 @@ package snyk.common.lsp import com.intellij.ide.impl.ProjectUtil +import com.intellij.openapi.application.invokeLater import com.intellij.openapi.components.service import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.project.Project @@ -98,8 +99,8 @@ class LanguageServerWrapper( isInitializing = true val snykLanguageClient = SnykLanguageClient() languageClient = snykLanguageClient - val logLevel = if (snykLanguageClient.logger.isDebugEnabled) "debug" else "info" - val cmd = listOf(lsPath, "language-server", "-l", logLevel, "-f", "/tmp/snyk-ls.log") + val logLevel = if (snykLanguageClient.logger.isDebugEnabled) "trace" else "info" + val cmd = listOf(lsPath, "language-server", "-l", logLevel) val processBuilder = ProcessBuilder(cmd) pluginSettings().token?.let { EnvironmentHelper.updateEnvironment(processBuilder.environment(), it) } @@ -120,6 +121,9 @@ class LanguageServerWrapper( } finally { isInitializing = false } + // update feature flags + pluginSettings().isGlobalIgnoresFeatureEnabled = + sendFeatureFlagCommand("snykCodeConsistentIgnores") } fun shutdown(): Future<*> { @@ -232,11 +236,12 @@ class LanguageServerWrapper( val param = ExecuteCommandParams() param.command = "snyk.getFeatureFlagStatus" param.arguments = listOf(featureFlag) - val result = languageServer.workspaceService.executeCommand(param).get() + val result = languageServer.workspaceService.executeCommand(param).get(5, TimeUnit.SECONDS) + + val resultMap = result as? Map<*, *> + val ok = resultMap?.get("ok") as? Boolean ?: false + val userMessage = resultMap?.get("userMessage") as? String ?: "No message provided" - val resultJson = JSONObject(result.toString()) - val ok = resultJson.getBoolean("ok") - val userMessage = resultJson.optString("userMessage") if (ok) { logger.info("Feature flag $featureFlag is enabled.") diff --git a/src/main/kotlin/snyk/common/lsp/SnykLanguageClient.kt b/src/main/kotlin/snyk/common/lsp/SnykLanguageClient.kt index 856135950..aa79c9af0 100644 --- a/src/main/kotlin/snyk/common/lsp/SnykLanguageClient.kt +++ b/src/main/kotlin/snyk/common/lsp/SnykLanguageClient.kt @@ -176,7 +176,8 @@ class SnykLanguageClient : LanguageClient { val includeIgnoredIssues = pluginSettings().ignoredIssuesEnabled val includeOpenedIssues = pluginSettings().openIssuesEnabled - val isFeatureFlagEnabled = LanguageServerWrapper.getInstance().sendFeatureFlagCommand("snykCodeConsistentIgnores") + // get enablement status from settings + val isFeatureFlagEnabled = pluginSettings().isGlobalIgnoresFeatureEnabled val processedIssues = if (isFeatureFlagEnabled) { snykScan.issues.filter { it.isVisible(includeOpenedIssues, includeIgnoredIssues) } diff --git a/src/test/java/snyk/common/lsp/LanguageServerWrapperTest.kt b/src/test/java/snyk/common/lsp/LanguageServerWrapperTest.kt index 78ebae89b..56d269b76 100644 --- a/src/test/java/snyk/common/lsp/LanguageServerWrapperTest.kt +++ b/src/test/java/snyk/common/lsp/LanguageServerWrapperTest.kt @@ -111,15 +111,22 @@ class LanguageServerWrapperTest { @Test fun `sendFeatureFlagCommand should return true if feature flag is enabled`() { // Arrange + cut.languageClient = mockk(relaxed = true) + val processMock = mockk(relaxed = true) + cut.process = processMock val featureFlag = "testFeatureFlag" - val commandResponse = CompletableFuture.completedFuture("{\"ok\": true}" as Any) - every { lsMock.workspaceService.executeCommand(any()) } returns commandResponse + every { processMock.info().startInstant().isPresent } returns true + every { processMock.isAlive } returns true + + every { + lsMock.workspaceService.executeCommand(any()) + } returns CompletableFuture.completedFuture(mapOf("ok" to true)) // Act val result = cut.sendFeatureFlagCommand(featureFlag) // Assert - verify { lsMock.workspaceService.executeCommand(match { it.arguments.contains(featureFlag) }) } assertEquals(true, result) + } }