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

JS-155 SonarJS exposes entry point to the parser for testing #4734

Merged
merged 9 commits into from
Jun 14, 2024
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"_:plugin:prepare-bridge": "npm pack && node tools/check-distribution-filepath-length.js && npm run _:plugin:copy-bridge",
"_:plugin-fetch-node": "node tools/fetch-node/scripts/wrapper.mjs",
"_:plugin:pre-build": "npm run bridge:build && npm run _:plugin:prepare-bridge && npm run _:plugin-fetch-node",
"_:plugin:copy-bridge": "cpy sonarjs-1.0.0.tgz sonar-plugin/sonar-javascript-plugin/target/classes"
"_:plugin:copy-bridge": "cpy sonarjs-1.0.0.tgz sonar-plugin/sonar-javascript-plugin/target/classes && cpy sonarjs-1.0.0.tgz sonar-plugin/standalone/target/classes"
},
"repository": {
"type": "git",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import org.sonar.api.Startable;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.TextRange;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.scanner.ScannerSide;
import org.sonar.plugins.javascript.bridge.protobuf.Node;
import org.sonarsource.api.sonarlint.SonarLintSide;
Expand All @@ -35,7 +34,7 @@
@ScannerSide
@SonarLintSide(lifespan = INSTANCE)
public interface BridgeServer extends Startable {
void startServerLazily(SensorContext context) throws IOException;
void startServerLazily(BridgeServerConfig context) throws IOException;

void initLinter(List<EslintRule> rules, List<String> environments, List<String> globals, AnalysisMode analysisMode, String baseDir,
List<String> exclusions) throws IOException;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* SonarQube JavaScript Plugin
* Copyright (C) 2011-2024 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program 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 3 of the License, or (at your option) any later version.
*
* This program 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 program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.plugins.javascript.bridge;

import org.sonar.api.SonarProduct;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.config.Configuration;

/**
* {@link BridgeServerImpl} requires information from {@link org.sonar.api.batch.sensor.SensorContext}.
* Hovewer, {@link org.sonar.api.batch.sensor.SensorContext} is a big object, containing more than what we need.
* This class will contain only information required by {@link BridgeServerImpl}.
* This will reduce the dependency on external API, and ease the testing.
*/
public record BridgeServerConfig(Configuration config, String workDirAbsolutePath, SonarProduct product) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a first step toward removing the dependency over sonar.api in the Bridge. I failed to remove everything, as we rely deeply on the Configuration object. I tried to wrap the object, store only the result that we need, but both solution result in a lot of non-trivial changes.

It is a bit annoying, as it means you will need to have the classes from sonar.api when using the standalone... But I'm afraid we will have to deal with it for now.


public static BridgeServerConfig fromSensorContext(SensorContext context) {
return new BridgeServerConfig(context.config(), context.fileSystem().workDir().getAbsolutePath(), context.runtime().getProduct());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@
*/
package org.sonar.plugins.javascript.bridge;

import static java.util.Collections.emptyList;
import static org.sonar.plugins.javascript.bridge.NetUtils.findOpenPort;
import static org.sonar.plugins.javascript.nodejs.NodeCommandBuilderImpl.NODE_EXECUTABLE_PROPERTY;

import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import java.io.File;
Expand Down Expand Up @@ -51,13 +47,16 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.SonarProduct;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.config.Configuration;
import org.sonar.api.utils.TempFolder;
import org.sonar.plugins.javascript.nodejs.NodeCommand;
import org.sonar.plugins.javascript.nodejs.NodeCommandBuilder;
import org.sonar.plugins.javascript.nodejs.NodeCommandException;

import static java.util.Collections.emptyList;
import static org.sonar.plugins.javascript.bridge.NetUtils.findOpenPort;
import static org.sonar.plugins.javascript.nodejs.NodeCommandBuilderImpl.NODE_EXECUTABLE_PROPERTY;

public class BridgeServerImpl implements BridgeServer {

private enum Status {
Expand Down Expand Up @@ -176,7 +175,7 @@ void deploy(Configuration configuration) throws IOException {
embeddedNode.deploy();
}

void startServer(SensorContext context, List<Path> deployedBundles) throws IOException {
void startServer(BridgeServerConfig serverConfig, List<Path> deployedBundles) throws IOException {
LOG.debug("Starting server");
long start = System.currentTimeMillis();
port = findOpenPort();
Expand All @@ -193,7 +192,7 @@ void startServer(SensorContext context, List<Path> deployedBundles) throws IOExc
.stream()
.map(Path::toString)
.collect(Collectors.joining(File.pathSeparator));
nodeCommand = initNodeCommand(context, scriptFile, bundles);
nodeCommand = initNodeCommand(serverConfig, scriptFile, bundles);
nodeCommand.start();

if (!waitServerToStart(timeoutSeconds * 1000)) {
Expand Down Expand Up @@ -226,12 +225,12 @@ boolean waitServerToStart(int timeoutMs) {
return true;
}

private NodeCommand initNodeCommand(SensorContext context, File scriptFile, String bundles)
private NodeCommand initNodeCommand(BridgeServerConfig serverConfig, File scriptFile, String bundles)
throws IOException {
var workdir = context.fileSystem().workDir().getAbsolutePath();
var config = context.config();
var workdir = serverConfig.workDirAbsolutePath();
var config = serverConfig.config();
var allowTsParserJsFiles = config.getBoolean(ALLOW_TS_PARSER_JS_FILES).orElse(true);
var isSonarLint = context.runtime().getProduct() == SonarProduct.SONARLINT;
var isSonarLint = serverConfig.product() == SonarProduct.SONARLINT;
if (isSonarLint) {
LOG.info("Running in SonarLint context, metrics will not be computed.");
}
Expand All @@ -243,7 +242,7 @@ private NodeCommand initNodeCommand(SensorContext context, File scriptFile, Stri
.embeddedNode(embeddedNode)
.pathResolver(bundle)
.minNodeVersion(NodeDeprecationWarning.MIN_SUPPORTED_NODE_VERSION)
.configuration(context.config())
.configuration(serverConfig.config())
.script(scriptFile.getAbsolutePath())
.scriptArgs(
String.valueOf(port),
Expand All @@ -256,7 +255,7 @@ private NodeCommand initNodeCommand(SensorContext context, File scriptFile, Stri
)
.env(getEnv());

context
serverConfig
.config()
.getInt(MAX_OLD_SPACE_SIZE_PROPERTY)
.ifPresent(nodeCommandBuilder::maxOldSpaceSize);
Expand All @@ -275,7 +274,7 @@ private static Map<String, String> getEnv() {
}

@Override
public void startServerLazily(SensorContext context) throws IOException {
public void startServerLazily(BridgeServerConfig serverConfig) throws IOException {
if (status == Status.FAILED) {
// required for SonarLint context to avoid restarting already failed server
throw new ServerAlreadyFailedException();
Expand All @@ -296,12 +295,12 @@ public void startServerLazily(SensorContext context) throws IOException {
status = Status.FAILED;
throw new ServerAlreadyFailedException();
}
deploy(context.config());
deploy(serverConfig.config());
List<Path> deployedBundles = rulesBundles.deploy(temporaryDeployLocation.resolve("package"));
rulesBundles
.getUcfgRulesBundle()
.ifPresent(rulesBundle -> PluginInfo.setUcfgPluginVersion(rulesBundle.bundleVersion()));
startServer(context, deployedBundles);
startServer(serverConfig, deployedBundles);
} catch (NodeCommandException e) {
status = Status.FAILED;
throw e;
Expand Down
Loading