Skip to content

Commit

Permalink
TypeScript sensor should skip analysis if no input files are found (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
saberduck authored May 11, 2021
1 parent 1d73e96 commit 9860112
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package com.sonar.javascript.it.plugin;

import com.sonar.orchestrator.Orchestrator;
import com.sonar.orchestrator.build.BuildResult;
import com.sonar.orchestrator.build.SonarScanner;
import com.sonar.orchestrator.locator.FileLocation;
import java.io.File;
Expand Down Expand Up @@ -67,7 +68,8 @@ public void testProject(File projectDir, String projectKey) {

Tests.setProfile(projectKey, "rules", "js");

orchestrator.executeBuild(build);
BuildResult buildResult = orchestrator.executeBuild(build);
assertThat(buildResult.getLogsLines(l -> l.startsWith("ERROR"))).isEmpty();

SearchRequest request = new SearchRequest();
request.setComponentKeys(singletonList(projectKey)).setRules(singletonList("javascript:S3923"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,13 @@ public void execute(SensorContext context) {
environments = Arrays.asList(context.config().getStringArray(ENVIRONMENTS_PROPERTY_KEY));
globals = Arrays.asList(context.config().getStringArray(GLOBALS_PROPERTY_KEY));
try {
List<InputFile> inputFiles = getInputFiles();
if (inputFiles.isEmpty()) {
LOG.info("No input files found for analysis");
return;
}
startBridge(context);
analyzeFiles();
analyzeFiles(inputFiles);
} catch (CancellationException e) {
// do not propagate the exception
LOG.info(e.toString());
Expand Down Expand Up @@ -145,7 +150,9 @@ private void startBridge(SensorContext context) throws IOException {
eslintBridgeServer.startServerLazily(context);
}

abstract void analyzeFiles() throws IOException, InterruptedException;
abstract void analyzeFiles(List<InputFile> inputFiles) throws IOException;

protected abstract List<InputFile> getInputFiles();

private void processParsingError(SensorContext sensorContext, InputFile inputFile, ParsingError parsingError) {
Integer line = parsingError.line;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ public JavaScriptEslintBasedSensor(JavaScriptChecks checks, NoSonarFilter noSona
}

@Override
void analyzeFiles() throws IOException, InterruptedException {
runEslintAnalysis(provideDefaultTsConfig());
void analyzeFiles(List<InputFile> inputFiles) throws IOException {
runEslintAnalysis(provideDefaultTsConfig(), inputFiles);
if (checks.hasLegacyCustomChecks()) {
PROFILER.startInfo("Java-based frontend sensor [javascript] for custom rules");
LOG.warn("Custom JavaScript rules are deprecated and API will be removed in future version.");
Expand All @@ -97,11 +97,10 @@ private List<String> provideDefaultTsConfig() throws IOException {
return provider.tsconfigs(context);
}

private void runEslintAnalysis(List<String> tsConfigs) throws IOException, InterruptedException {
private void runEslintAnalysis(List<String> tsConfigs, List<InputFile> inputFiles) throws IOException {
ProgressReport progressReport = new ProgressReport("Analysis progress", TimeUnit.SECONDS.toMillis(10));
boolean success = false;
try {
List<InputFile> inputFiles = getInputFiles();
progressReport.start(inputFiles.stream().map(InputFile::toString).collect(Collectors.toList()));
eslintBridgeServer.initLinter(rules, environments, globals);
for (InputFile inputFile : inputFiles) {
Expand Down Expand Up @@ -137,7 +136,8 @@ private void analyze(InputFile file, List<String> tsConfigs) throws IOException
}
}

private List<InputFile> getInputFiles() {
@Override
protected List<InputFile> getInputFiles() {
FileSystem fileSystem = context.fileSystem();
FilePredicate mainFilePredicate = JavaScriptFilePredicate.getJavaScriptPredicate(fileSystem);
return StreamSupport.stream(fileSystem.inputFiles(mainFilePredicate).spliterator(), false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,23 +85,24 @@ public TypeScriptSensor(TypeScriptChecks typeScriptChecks, NoSonarFilter noSonar
@Override
public void describe(SensorDescriptor descriptor) {
descriptor
// JavaScriptLanguage.KEY is required for Vue single file components, bc .vue is considered as JS language
.onlyOnLanguages(JavaScriptLanguage.KEY, TypeScriptLanguage.KEY)
.name("TypeScript analysis")
.onlyOnFileType(Type.MAIN);
}

private List<InputFile> getInputFiles() {
@Override
protected List<InputFile> getInputFiles() {
FileSystem fileSystem = context.fileSystem();
FilePredicate mainFilePredicate = JavaScriptFilePredicate.getTypeScriptPredicate(fileSystem);
return StreamSupport.stream(fileSystem.inputFiles(mainFilePredicate).spliterator(), false)
.collect(Collectors.toList());
}

@Override
void analyzeFiles() throws IOException, InterruptedException {
void analyzeFiles(List<InputFile> inputFiles) throws IOException {
boolean success = false;
ProgressReport progressReport = new ProgressReport("Progress of TypeScript analysis", TimeUnit.SECONDS.toMillis(10));
List<InputFile> inputFiles = getInputFiles();
eslintBridgeServer.initLinter(rules, environments, globals);
List<String> tsConfigs = new TsConfigProvider(tempFolder).tsconfigs(context);
if (tsConfigs.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,19 @@ public void should_have_configured_rules() throws Exception {
assertThat(rules.get(2).configurations).isEmpty();
}

@Test
public void should_skip_analysis_when_no_files() throws Exception {
JavaScriptEslintBasedSensor javaScriptEslintBasedSensor = new JavaScriptEslintBasedSensor(checks(ESLINT_BASED_RULE),
new NoSonarFilter(),
fileLinesContextFactory,
eslintBridgeServerMock,
mock(AnalysisWarnings.class),
tempFolder
);
javaScriptEslintBasedSensor.execute(context);
assertThat(logTester.logs(LoggerLevel.INFO)).contains("No input files found for analysis");
}

@Test
public void handle_missing_node() throws Exception {
doThrow(new NodeCommandException("Exception Message", new IOException())).when(eslintBridgeServerMock).startServerLazily(any());
Expand All @@ -364,7 +377,7 @@ public void handle_missing_node() throws Exception {
analysisWarnings,
tempFolder
);

createInputFile(context);
javaScriptEslintBasedSensor.execute(context);
assertThat(logTester.logs(LoggerLevel.ERROR)).contains("Exception Message");
verify(analysisWarnings).addUnique("JavaScript and/or TypeScript rules were not executed. Exception Message");
Expand All @@ -374,6 +387,7 @@ public void handle_missing_node() throws Exception {
public void log_debug_if_already_failed_server() throws Exception {
doThrow(new ServerAlreadyFailedException()).when(eslintBridgeServerMock).startServerLazily(any());
JavaScriptEslintBasedSensor javaScriptEslintBasedSensor = createSensor();
createInputFile(context);
javaScriptEslintBasedSensor.execute(context);

assertThat(logTester.logs()).contains("Skipping start of eslint-bridge server due to the failure during first analysis",
Expand Down Expand Up @@ -475,6 +489,7 @@ public void should_fail_fast_with_nodecommandexception() throws Exception {
JavaScriptEslintBasedSensor sensor = createSensor();
MapSettings settings = new MapSettings().setProperty("sonar.internal.analysis.failFast", true);
context.setSettings(settings);
createInputFile(context);
assertThatThrownBy(() -> sensor.execute(context))
.isInstanceOf(IllegalStateException.class)
.hasMessage("Analysis failed (\"sonar.internal.analysis.failFast\"=true)");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -426,13 +426,23 @@ private DefaultInputFile inputFileFromResource(SensorContextTester context, Path
}

@Test
public void should_stop_without_tsconfig() {
public void should_stop_without_tsconfig() throws Exception {
Path baseDir = Paths.get("src/test/resources/solution-tsconfig");
SensorContextTester context = SensorContextTester.create(tempFolder.newDir());
inputFileFromResource(context, baseDir, "src/file.ts");

context.setRuntime(SonarRuntimeImpl.forSonarLint(Version.create(4, 4)));
createSensor().execute(context);
assertThat(logTester.logs(LoggerLevel.WARN)).contains("No tsconfig.json file found, analysis will be skipped.");
}

@Test
public void should_stop_when_no_input_files() throws Exception {
SensorContextTester context = SensorContextTester.create(tempFolder.newDir());
createSensor().execute(context);
assertThat(logTester.logs()).containsOnly("No input files found for analysis");
}

@Test
public void should_fail_fast() throws Exception {
when(eslintBridgeServerMock.analyzeTypeScript(any())).thenThrow(new IOException("error"));
Expand Down

0 comments on commit 9860112

Please sign in to comment.