Skip to content

Commit e213cca

Browse files
mithfindeljblievremont
authored andcommitted
SLVSCODE-152 Read Node path from settings in standalone engine
1 parent 2f7c8a4 commit e213cca

File tree

13 files changed

+281
-56
lines changed

13 files changed

+281
-56
lines changed

src/main/java/org/sonarsource/sonarlint/ls/AnalysisManager.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,12 @@ private void analyzeAllOpenJavaFiles() {
504504
}
505505
}
506506

507+
private void analyzeAllOpenFiles() {
508+
for (URI fileUri : fileContentPerFileURI.keySet()) {
509+
analyzeAsync(fileUri, false);
510+
}
511+
}
512+
507513
private Map<String, String> configureJavaProperties(URI fileUri) {
508514
Optional<GetJavaConfigResponse> cachedJavaConfigOpt = ofNullable(javaConfigPerFileURI.get(fileUri)).orElse(empty());
509515
return cachedJavaConfigOpt.map(cachedJavaConfig -> {

src/main/java/org/sonarsource/sonarlint/ls/EnginesFactory.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import org.sonar.api.utils.log.Logger;
3333
import org.sonar.api.utils.log.Loggers;
3434
import org.sonarsource.sonarlint.core.ConnectedSonarLintEngineImpl;
35-
import org.sonarsource.sonarlint.core.NodeJsHelper;
3635
import org.sonarsource.sonarlint.core.StandaloneSonarLintEngineImpl;
3736
import org.sonarsource.sonarlint.core.client.api.common.Language;
3837
import org.sonarsource.sonarlint.core.client.api.connected.ConnectedGlobalConfiguration;
@@ -63,12 +62,12 @@ public class EnginesFactory {
6362
Language.PLSQL
6463
};
6564

66-
private final NodeJsHelper nodeJsHelper;
65+
private final NodeJsRuntime nodeJsRuntime;
6766

68-
public EnginesFactory(Collection<URL> standaloneAnalyzers, LanguageClientLogOutput lsLogOutput, NodeJsHelper nodeJsHelper) {
67+
public EnginesFactory(Collection<URL> standaloneAnalyzers, LanguageClientLogOutput lsLogOutput, NodeJsRuntime nodeJsRuntime) {
6968
this.standaloneAnalyzers = standaloneAnalyzers;
7069
this.lsLogOutput = lsLogOutput;
71-
this.nodeJsHelper = nodeJsHelper;
70+
this.nodeJsRuntime = nodeJsRuntime;
7271
}
7372

7473
public StandaloneSonarLintEngine createStandaloneEngine() {
@@ -79,8 +78,7 @@ public StandaloneSonarLintEngine createStandaloneEngine() {
7978
StandaloneGlobalConfiguration configuration = StandaloneGlobalConfiguration.builder()
8079
.setExtraProperties(prepareExtraProps())
8180
.addEnabledLanguages(STANDALONE_LANGUAGES)
82-
// TODO Use version from configuration
83-
.setNodeJs(nodeJsHelper.getNodeJsPath(), nodeJsHelper.getNodeJsVersion())
81+
.setNodeJs(nodeJsRuntime.getNodeJsPath(), nodeJsRuntime.getNodeJsVersion())
8482
.addPlugins(standaloneAnalyzers.toArray(new URL[0]))
8583
.setLogOutput(lsLogOutput)
8684
.build();
@@ -104,8 +102,7 @@ public ConnectedSonarLintEngine createConnectedEngine(String serverId) {
104102
.setExtraProperties(prepareExtraProps())
105103
.addEnabledLanguages(STANDALONE_LANGUAGES)
106104
.addEnabledLanguages(CONNECTED_ADDITIONAL_LANGUAGES)
107-
// TODO Use version from configuration
108-
.setNodeJs(nodeJsHelper.getNodeJsPath(), nodeJsHelper.getNodeJsVersion())
105+
.setNodeJs(nodeJsRuntime.getNodeJsPath(), nodeJsRuntime.getNodeJsVersion())
109106
.setLogOutput(lsLogOutput)
110107
.build();
111108

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* SonarLint Language Server
3+
* Copyright (C) 2009-2020 SonarSource SA
4+
* mailto:info AT sonarsource DOT com
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 3 of the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with this program; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*/
20+
package org.sonarsource.sonarlint.ls;
21+
22+
import java.nio.file.Path;
23+
import java.nio.file.Paths;
24+
import java.util.Objects;
25+
import java.util.Optional;
26+
import java.util.function.Supplier;
27+
import javax.annotation.CheckForNull;
28+
import javax.annotation.Nullable;
29+
import org.apache.commons.lang.StringUtils;
30+
import org.sonarsource.sonarlint.core.NodeJsHelper;
31+
import org.sonarsource.sonarlint.core.client.api.common.Version;
32+
import org.sonarsource.sonarlint.ls.settings.SettingsManager;
33+
import org.sonarsource.sonarlint.ls.settings.WorkspaceSettings;
34+
import org.sonarsource.sonarlint.ls.settings.WorkspaceSettingsChangeListener;
35+
36+
public class NodeJsRuntime implements WorkspaceSettingsChangeListener {
37+
38+
private final SettingsManager settingsManager;
39+
private final Supplier<NodeJsHelper> nodeJsHelperFactory;
40+
private boolean init = false;
41+
private Path nodeJsPath = null;
42+
private Version nodeJsVersion = null;
43+
44+
NodeJsRuntime(SettingsManager settingsManager) {
45+
this(settingsManager, NodeJsHelper::new);
46+
}
47+
48+
NodeJsRuntime(SettingsManager settingsManager, Supplier<NodeJsHelper> nodeJsHelperFactory) {
49+
this.settingsManager = settingsManager;
50+
this.nodeJsHelperFactory = nodeJsHelperFactory;
51+
}
52+
53+
private void init() {
54+
WorkspaceSettings currentSettings = settingsManager.getCurrentSettings();
55+
NodeJsHelper helper = nodeJsHelperFactory.get();
56+
helper.detect(Optional.ofNullable(currentSettings.pathToNodeExecutable())
57+
.filter(StringUtils::isNotEmpty)
58+
.map(Paths::get)
59+
.orElse(null));
60+
this.nodeJsPath = helper.getNodeJsPath();
61+
this.nodeJsVersion = helper.getNodeJsVersion();
62+
this.init = true;
63+
}
64+
65+
@Nullable
66+
String nodeVersion() {
67+
return Optional.ofNullable(getNodeJsVersion())
68+
.map(Version::toString)
69+
.orElse(null);
70+
}
71+
72+
public Path getNodeJsPath() {
73+
if (!init) {
74+
init();
75+
}
76+
return nodeJsPath;
77+
}
78+
79+
public Version getNodeJsVersion() {
80+
if (!init) {
81+
init();
82+
}
83+
return nodeJsVersion;
84+
}
85+
86+
@Override
87+
public void onChange(@CheckForNull WorkspaceSettings oldValue, WorkspaceSettings newValue) {
88+
if (oldValue == null || !(Objects.equals(oldValue.pathToNodeExecutable(), newValue.pathToNodeExecutable()))) {
89+
init = false;
90+
nodeJsPath = null;
91+
nodeJsVersion = null;
92+
}
93+
}
94+
}

src/main/java/org/sonarsource/sonarlint/ls/SonarLintLanguageServer.java

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
import java.util.concurrent.CompletableFuture;
3434
import java.util.concurrent.ExecutorService;
3535
import java.util.concurrent.Executors;
36-
import java.util.function.Supplier;
3736
import javax.annotation.Nullable;
3837
import org.eclipse.lsp4j.CodeAction;
3938
import org.eclipse.lsp4j.CodeActionParams;
@@ -61,8 +60,6 @@
6160
import org.eclipse.lsp4j.services.TextDocumentService;
6261
import org.eclipse.lsp4j.services.WorkspaceService;
6362
import org.sonar.api.utils.log.Loggers;
64-
import org.sonarsource.sonarlint.core.NodeJsHelper;
65-
import org.sonarsource.sonarlint.core.client.api.common.Version;
6663
import org.sonarsource.sonarlint.ls.connected.ProjectBindingManager;
6764
import org.sonarsource.sonarlint.ls.folders.WorkspaceFoldersManager;
6865
import org.sonarsource.sonarlint.ls.log.LanguageClientLogOutput;
@@ -82,8 +79,7 @@ public class SonarLintLanguageServer implements SonarLintExtendedLanguageServer,
8279
private final SettingsManager settingsManager;
8380
private final ProjectBindingManager bindingManager;
8481
private final AnalysisManager analysisManager;
85-
// TODO Cleanup
86-
private final NodeJsHelper nodeJsHelper;
82+
private final NodeJsRuntime nodeJsRuntime;
8783
private final EnginesFactory enginesFactory;
8884
private final CommandManager commandManager;
8985
private final ExecutorService threadPool;
@@ -108,12 +104,11 @@ public class SonarLintLanguageServer implements SonarLintExtendedLanguageServer,
108104
LanguageClientLogOutput lsLogOutput = new LanguageClientLogOutput(this.client);
109105
Loggers.setTarget(lsLogOutput);
110106
this.telemetry = new SonarLintTelemetry();
111-
this.nodeJsHelper = new NodeJsHelper();
112-
// TODO Add property to configure Node
113-
nodeJsHelper.detect(null);
114-
this.enginesFactory = new EnginesFactory(analyzers, lsLogOutput, nodeJsHelper);
115107
this.workspaceFoldersManager = new WorkspaceFoldersManager();
116108
this.settingsManager = new SettingsManager(this.client, this.workspaceFoldersManager);
109+
this.nodeJsRuntime = new NodeJsRuntime(settingsManager);
110+
this.settingsManager.addListener(nodeJsRuntime);
111+
this.enginesFactory = new EnginesFactory(analyzers, lsLogOutput, nodeJsRuntime);
117112
this.settingsManager.addListener(telemetry);
118113
this.settingsManager.addListener(lsLogOutput);
119114
this.bindingManager = new ProjectBindingManager(enginesFactory, workspaceFoldersManager, settingsManager, client);
@@ -155,17 +150,8 @@ public CompletableFuture<InitializeResult> initialize(InitializeParams params) {
155150
enginesFactory.initialize(typeScriptPath.map(Paths::get).orElse(null));
156151
analysisManager.initialize();
157152

158-
// TODO Cleanup
159-
Supplier<String> nodeVersion = () -> {
160-
Version nodeJsVersion = nodeJsHelper.getNodeJsVersion();
161-
if (nodeJsVersion != null) {
162-
return nodeJsVersion.toString();
163-
} else {
164-
return null;
165-
}
166-
};
167-
168-
telemetry.init(productKey, telemetryStorage, productName, productVersion, ideVersion, bindingManager::usesConnectedMode, bindingManager::usesSonarCloud, nodeVersion);
153+
telemetry.init(productKey, telemetryStorage, productName, productVersion, ideVersion,
154+
bindingManager::usesConnectedMode, bindingManager::usesSonarCloud, nodeJsRuntime::nodeVersion);
169155

170156
InitializeResult result = new InitializeResult();
171157
ServerCapabilities c = new ServerCapabilities();

src/main/java/org/sonarsource/sonarlint/ls/settings/SettingsManager.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ public class SettingsManager implements WorkspaceFolderLifecycleListener {
6666
private static final String OUTPUT = "output";
6767
private static final String SHOW_ANALYZER_LOGS = "showAnalyzerLogs";
6868
private static final String SHOW_VERBOSE_LOGS = "showVerboseLogs";
69+
private static final String PATH_TO_NODE_EXECUTABLE = "pathToNodeExecutable";
6970

7071
private static final Logger LOG = Loggers.get(SettingsManager.class);
7172

@@ -161,7 +162,7 @@ CompletableFuture<Map<String, Object>> requestSonarLintConfigurationAsync(@Nulla
161162
if (uri != null) {
162163
configurationItem.setScopeUri(uri.toString());
163164
}
164-
params.setItems(Arrays.asList(configurationItem));
165+
params.setItems(Collections.singletonList(configurationItem));
165166
return client.configuration(params)
166167
.handle((r, t) -> {
167168
if (t != null) {
@@ -193,13 +194,14 @@ private void updateWorkspaceFolderSettings(WorkspaceFolderWrapper f, boolean not
193194

194195
private static WorkspaceSettings parseSettings(Map<String, Object> params) {
195196
boolean disableTelemetry = (Boolean) params.getOrDefault(DISABLE_TELEMETRY, false);
197+
String pathToNodeExecutable = (String) params.get(PATH_TO_NODE_EXECUTABLE);
196198
Map<String, ServerConnectionSettings> serverConnections = parseServerConnections(params);
197199
RulesConfiguration rulesConfiguration = RulesConfiguration.parse(((Map<String, Object>) params.getOrDefault(RULES, Collections.emptyMap())));
198200
Map<String, Object> consoleParams = ((Map<String, Object>) params.getOrDefault(OUTPUT, Collections.emptyMap()));
199201
boolean showAnalyzerLogs = (Boolean) consoleParams.getOrDefault(SHOW_ANALYZER_LOGS, false);
200202
boolean showVerboseLogs = (Boolean) consoleParams.getOrDefault(SHOW_VERBOSE_LOGS, false);
201203
return new WorkspaceSettings(disableTelemetry, serverConnections, rulesConfiguration.excludedRules(), rulesConfiguration.includedRules(), rulesConfiguration.ruleParameters(),
202-
showAnalyzerLogs, showVerboseLogs);
204+
showAnalyzerLogs, showVerboseLogs, pathToNodeExecutable);
203205
}
204206

205207
private static Map<String, ServerConnectionSettings> parseServerConnections(Map<String, Object> params) {

src/main/java/org/sonarsource/sonarlint/ls/settings/WorkspaceSettings.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,19 @@ public class WorkspaceSettings {
4141
private final Map<RuleKey, Map<String, String>> ruleParameters;
4242
private final boolean showAnalyzerLogs;
4343
private final boolean showVerboseLogs;
44+
private final String pathToNodeExecutable;
4445

4546
public WorkspaceSettings(boolean disableTelemetry, Map<String, ServerConnectionSettings> servers,
4647
Collection<RuleKey> excludedRules, Collection<RuleKey> includedRules, Map<RuleKey, Map<String, String>> ruleParameters,
47-
boolean showAnalyzerLogs, boolean showVerboseLogs) {
48+
boolean showAnalyzerLogs, boolean showVerboseLogs, String pathToNodeExecutable) {
4849
this.disableTelemetry = disableTelemetry;
4950
this.servers = servers;
5051
this.excludedRules = excludedRules;
5152
this.includedRules = includedRules;
5253
this.ruleParameters = ruleParameters;
5354
this.showAnalyzerLogs = showAnalyzerLogs;
5455
this.showVerboseLogs = showVerboseLogs;
56+
this.pathToNodeExecutable = pathToNodeExecutable;
5557
}
5658

5759
public boolean isDisableTelemetry() {
@@ -86,9 +88,13 @@ public boolean showVerboseLogs() {
8688
return showVerboseLogs;
8789
}
8890

91+
public String pathToNodeExecutable() {
92+
return pathToNodeExecutable;
93+
}
94+
8995
@Override
9096
public int hashCode() {
91-
return Objects.hash(disableTelemetry, servers, excludedRules, includedRules, showAnalyzerLogs, showVerboseLogs);
97+
return Objects.hash(disableTelemetry, servers, excludedRules, includedRules, showAnalyzerLogs, showVerboseLogs, pathToNodeExecutable);
9298
}
9399

94100
@Override
@@ -105,7 +111,8 @@ public boolean equals(Object obj) {
105111
WorkspaceSettings other = (WorkspaceSettings) obj;
106112
return disableTelemetry == other.disableTelemetry && Objects.equals(servers, other.servers) && Objects.equals(excludedRules, other.excludedRules)
107113
&& Objects.equals(includedRules, other.includedRules) && Objects.equals(ruleParameters, other.ruleParameters)
108-
&& Objects.equals(showAnalyzerLogs, other.showAnalyzerLogs) && Objects.equals(showVerboseLogs, other.showVerboseLogs);
114+
&& Objects.equals(showAnalyzerLogs, other.showAnalyzerLogs) && Objects.equals(showVerboseLogs, other.showVerboseLogs)
115+
&& Objects.equals(pathToNodeExecutable, other.pathToNodeExecutable);
109116
}
110117

111118
@Override

src/test/java/org/sonarsource/sonarlint/ls/EnginesFactoryTests.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import org.junit.jupiter.api.BeforeEach;
2525
import org.junit.jupiter.api.Test;
2626
import org.mockito.ArgumentCaptor;
27-
import org.sonarsource.sonarlint.core.NodeJsHelper;
2827
import org.sonarsource.sonarlint.core.client.api.common.Language;
2928
import org.sonarsource.sonarlint.core.client.api.connected.ConnectedGlobalConfiguration;
3029
import org.sonarsource.sonarlint.core.client.api.connected.ConnectedSonarLintEngine;
@@ -46,7 +45,7 @@ public class EnginesFactoryTests {
4645

4746
@BeforeEach
4847
public void prepare() throws Exception {
49-
underTest = new EnginesFactory(asList(create("file://plugin1.jar").toURL(), create("file://plugin2.jar").toURL()), mock(LanguageClientLogOutput.class), mock(NodeJsHelper.class));
48+
underTest = new EnginesFactory(asList(create("file://plugin1.jar").toURL(), create("file://plugin2.jar").toURL()), mock(LanguageClientLogOutput.class), mock(NodeJsRuntime.class));
5049
underTest = spy(underTest);
5150
}
5251

0 commit comments

Comments
 (0)