Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.sonarsource.ruby.plugin;

import org.sonar.api.Plugin;
import org.sonar.api.PropertyType;
import org.sonar.api.SonarProduct;
import org.sonar.api.config.PropertyDefinition;
import org.sonar.api.config.PropertyDefinition.ConfigScope;
Expand Down Expand Up @@ -61,6 +62,16 @@ public void define(Context context) {
RuboCopSensor.class,
SimpleCovSensor.class,

PropertyDefinition.builder(RubySensor.SKIP_PROPERTY_KEY)
.defaultValue("true")
.name("Internal: Skip Ruby Sensor")
.description("Internal property to disable the Ruby sensor. Set to false to re-enable Ruby analysis.")
.type(PropertyType.BOOLEAN)
.category(RUBY_CATEGORY)
.subCategory(GENERAL)
.onlyOnConfigScopes(ConfigScope.PROJECT)
.build(),

PropertyDefinition.builder(RUBY_FILE_SUFFIXES_KEY)
.defaultValue(RUBY_FILE_SUFFIXES_DEFAULT_VALUE)
.name("File Suffixes")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@
*/
package org.sonarsource.ruby.plugin;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.SonarRuntime;
import org.sonar.api.batch.rule.CheckFactory;
import org.sonar.api.batch.rule.Checks;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.SensorDescriptor;
import org.sonar.api.config.Configuration;
import org.sonar.api.issue.NoSonarFilter;
import org.sonar.api.measures.FileLinesContextFactory;
import org.sonarsource.ruby.converter.RubyConverter;
Expand All @@ -29,6 +33,9 @@

public class RubySensor extends SlangSensor {

private static final Logger LOG = LoggerFactory.getLogger(RubySensor.class);
public static final String SKIP_PROPERTY_KEY = "sonar.ruby.internal.skipRubySensor";

private final Checks<SlangCheck> checks;

public RubySensor(SonarRuntime sonarRuntime, CheckFactory checkFactory, FileLinesContextFactory fileLinesContextFactory, NoSonarFilter noSonarFilter, RubyLanguage language) {
Expand All @@ -37,6 +44,21 @@ public RubySensor(SonarRuntime sonarRuntime, CheckFactory checkFactory, FileLine
checks.addAnnotatedChecks((Iterable<?>) RubyCheckList.checks());
}

@Override
public void describe(SensorDescriptor descriptor) {
super.describe(descriptor);
descriptor.onlyWhenConfiguration(configuration -> !shouldSkip(configuration));
}

@Override
public void execute(SensorContext context) {
if (shouldSkip(context.config())) {
LOG.info("Skipping Ruby sensor because '{}' is enabled.", SKIP_PROPERTY_KEY);
return;
}
super.execute(context);
}

@Override
protected ASTConverter astConverter(SensorContext sensorContext) {
return new RubyConverter();
Expand All @@ -52,4 +74,8 @@ protected String repositoryKey() {
return RubyPlugin.RUBY_REPOSITORY_KEY;
}

private static boolean shouldSkip(Configuration configuration) {
return configuration.getBoolean(SKIP_PROPERTY_KEY).orElse(true);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.sonar.api.SonarEdition;
import org.sonar.api.SonarQubeSide;
import org.sonar.api.SonarRuntime;
import org.sonar.api.config.PropertyDefinition;
import org.sonar.api.internal.PluginContextImpl;
import org.sonar.api.internal.SonarRuntimeImpl;
import org.sonar.api.utils.Version;
Expand All @@ -34,7 +35,14 @@ void sonarqube_7_9_extensions() {
SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.create(7, 9), SonarQubeSide.SERVER, SonarEdition.COMMUNITY);
Plugin.Context context = new Plugin.Context(runtime);
new RubyPlugin().define(context);
assertThat(context.getExtensions()).hasSize(12);
assertThat(context.getExtensions()).hasSize(13);
assertThat(context.getExtensions())
.filteredOn(PropertyDefinition.class::isInstance)
.anySatisfy(extension -> {
PropertyDefinition propertyDefinition = (PropertyDefinition) extension;
assertThat(propertyDefinition.key()).isEqualTo(RubySensor.SKIP_PROPERTY_KEY);
assertThat(propertyDefinition.defaultValue()).isEqualTo("true");
});
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class RubySensorTest extends AbstractSensorTest {

@Test
void simple_file() {
setSkipProperty(false);
InputFile inputFile = createInputFile("file1.rb", """
class C
end
Expand All @@ -50,6 +51,7 @@ class C

@Test
void test_access_modifiers_are_highlighted() {
setSkipProperty(false);
String source = """
class Foo
def is_public_by_default()
Expand Down Expand Up @@ -95,6 +97,7 @@ def is_public_again()

@Test
void test_fail_parsing() {
setSkipProperty(false);
InputFile inputFile = createInputFile("file1.rb", "{ <!REDECLARATION!>FOO<!>,<!REDECLARATION!>FOO<!> }");
context.fileSystem().add(inputFile);
CheckFactory checkFactory = checkFactory("S1764");
Expand All @@ -112,6 +115,33 @@ void test_fail_parsing() {
assertThat(logTester.logs()).contains(String.format("Unable to parse file: %s. Parse error at position 1:2", inputFile.uri()));
}

@Test
void skip_sensor_by_default() {
InputFile inputFile = createInputFile("file1.rb", """
class C
end
puts '1 == 1'; puts 'abc'
""");
context.fileSystem().add(inputFile);

sensor(checkFactory()).execute(context);

assertThat(context.highlightingTypeAt(inputFile.key(), 1, 0)).isEmpty();
assertThat(logTester.logs()).contains("Skipping Ruby sensor because 'sonar.ruby.internal.skipRubySensor' is enabled.");
}

@Test
void skip_sensor_when_internal_property_is_enabled() {
InputFile inputFile = createInputFile("file1.rb", "{ <!REDECLARATION!>FOO<!>,<!REDECLARATION!>FOO<!> }");
context.fileSystem().add(inputFile);
setSkipProperty(true);

sensor(checkFactory("S1764")).execute(context);

assertThat(context.allAnalysisErrors()).isEmpty();
assertThat(logTester.logs()).contains("Skipping Ruby sensor because 'sonar.ruby.internal.skipRubySensor' is enabled.");
}


@Override
protected String repositoryKey() {
Expand All @@ -127,4 +157,9 @@ private RubySensor sensor(CheckFactory checkFactory) {
return new RubySensor(SQ_LTS_RUNTIME, checkFactory, fileLinesContextFactory, new DefaultNoSonarFilter(), language());
}

private void setSkipProperty(boolean skip) {
context.setSettings(new MapSettings());
context.settings().setProperty(RubySensor.SKIP_PROPERTY_KEY, Boolean.toString(skip));
}

}
Loading