diff --git a/pom.xml b/pom.xml
index 237d7c8..0d9d37d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -149,6 +149,11 @@
sonarlint-core
6.3.0.36253
+
+ org.sonarsource.javascript
+ nodejs-utils
+ 8.3.0.16208
+
com.google.code.gson
gson
diff --git a/src/main/java/com/github/philippefichet/sonarlint4netbeans/NodeProcessWrapper.java b/src/main/java/com/github/philippefichet/sonarlint4netbeans/NodeProcessWrapper.java
new file mode 100644
index 0000000..02433e9
--- /dev/null
+++ b/src/main/java/com/github/philippefichet/sonarlint4netbeans/NodeProcessWrapper.java
@@ -0,0 +1,85 @@
+/*
+ * sonarlint4netbeans: SonarLint integration for Apache Netbeans
+ * Copyright (C) 2020 Philippe FICHET.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package com.github.philippefichet.sonarlint4netbeans;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+import org.sonarsource.nodejs.ProcessWrapper;
+import org.sonarsource.nodejs.ProcessWrapperImpl;
+
+/**
+ * Used to intercept nodejs path in NodeCommandBuilderImpl
+ * @author FICHET Philippe <philippe.fichet@laposte.net>
+ */
+public class NodeProcessWrapper implements ProcessWrapper {
+
+ private final ProcessWrapperImpl processWrapper = new ProcessWrapperImpl();
+ private List commandLineUsed = null;
+
+ @Override
+ public Process startProcess(List commandLine, Map env, Consumer outputConsumer, Consumer errorConsumer) throws IOException {
+ commandLineUsed = new ArrayList<>(commandLine);
+ return processWrapper.startProcess(commandLine, env, outputConsumer, errorConsumer);
+ }
+
+ @Override
+ public boolean waitFor(Process process, long timeout, TimeUnit unit) throws InterruptedException {
+ return processWrapper.waitFor(process, timeout, unit);
+ }
+
+ @Override
+ public void interrupt() {
+ processWrapper.interrupt();
+ }
+
+ @Override
+ public void destroyForcibly(Process process) {
+ processWrapper.destroyForcibly(process);
+ }
+
+ @Override
+ public boolean isMac() {
+ return processWrapper.isMac();
+ }
+
+ @Override
+ public boolean isWindows() {
+ return processWrapper.isWindows();
+ }
+
+ @Override
+ public String getenv(String name) {
+ return processWrapper.getenv(name);
+ }
+
+ @Override
+ public int exitValue(Process process) {
+ return processWrapper.exitValue(process);
+ }
+
+ public Optional> getCommandLineUsed() {
+ return Optional.ofNullable(commandLineUsed);
+ }
+}
diff --git a/src/main/java/com/github/philippefichet/sonarlint4netbeans/SonarLintEngineImpl.java b/src/main/java/com/github/philippefichet/sonarlint4netbeans/SonarLintEngineImpl.java
index a83f44a..17f3ada 100644
--- a/src/main/java/com/github/philippefichet/sonarlint4netbeans/SonarLintEngineImpl.java
+++ b/src/main/java/com/github/philippefichet/sonarlint4netbeans/SonarLintEngineImpl.java
@@ -20,6 +20,7 @@
package com.github.philippefichet.sonarlint4netbeans;
import com.google.gson.Gson;
+import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Path;
@@ -35,6 +36,9 @@
import java.util.logging.Logger;
import java.util.prefs.Preferences;
import org.openide.util.NbPreferences;
+import org.sonarsource.nodejs.NodeCommand;
+import org.sonarsource.nodejs.NodeCommandBuilderImpl;
+import org.sonarsource.nodejs.NodeCommandException;
import org.sonarsource.sonarlint.core.StandaloneSonarLintEngineImpl;
import org.sonarsource.sonarlint.core.client.api.common.Language;
import org.sonarsource.sonarlint.core.client.api.common.LogOutput;
@@ -109,17 +113,40 @@ private void createInternalEngine() {
StandaloneGlobalConfiguration.Builder configBuilder = StandaloneGlobalConfiguration.builder()
.addEnabledLanguages(Language.values())
.addPlugins(pluginURLs.values().toArray(new URL[pluginURLs.values().size()]));
- getNodeJSPath().ifPresent(nodeJSPath -> {
- getNodeJSVersion().ifPresent(nodeJSVersion -> {
- Path nodeJS = Paths.get(nodeJSPath);
- configBuilder.setNodeJs(nodeJS, nodeJSVersion);
- });
- });
+ if (getNodeJSPath().isPresent() && getNodeJSVersion().isPresent()) {
+ String nodeJSPath = getNodeJSPath().get();
+ Version nodeJSVersion = getNodeJSVersion().get();
+ Path nodeJS = Paths.get(nodeJSPath);
+ configBuilder.setNodeJs(nodeJS, nodeJSVersion);
+ } else {
+ tryToSetDefaultNodeJS(configBuilder);
+ }
standaloneSonarLintEngineImpl = new StandaloneSonarLintEngineImpl(configBuilder.build());
consumerWaitingInitialization.forEach(consumer -> consumer.accept(this));
consumerWaitingInitialization.clear();
}).start();
}
+
+ private void tryToSetDefaultNodeJS(StandaloneGlobalConfiguration.Builder configBuilder) {
+ try {
+ NodeProcessWrapper nodeProcessWrapper = new NodeProcessWrapper();
+ NodeCommand nodeCommandVersion = new NodeCommandBuilderImpl(nodeProcessWrapper)
+ .nodeJsArgs("--version")
+ .build();
+ nodeCommandVersion.start();
+ if (nodeCommandVersion.waitFor() == 0 && nodeProcessWrapper.getCommandLineUsed().isPresent()) {
+ String nodeJSPath = nodeProcessWrapper.getCommandLineUsed().get().get(0);
+ Optional detectNodeJSVersion = SonarLintUtils.detectNodeJSVersion(nodeJSPath);
+ if (detectNodeJSVersion.isPresent()) {
+ configBuilder.setNodeJs(Paths.get(nodeJSPath), detectNodeJSVersion.get());
+ Logger.getLogger(SonarLintEngineImpl.class.getName()).log(Level.SEVERE, "Use default nodejs path");
+ }
+ }
+ } catch (NodeCommandException | IOException ex) {
+ Logger.getLogger(SonarLintEngineImpl.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
@Override
public Optional getNodeJSPath() {