Skip to content
Open
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
28 changes: 18 additions & 10 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.codehaus.sonar-plugins</groupId>
<artifactId>parent</artifactId>
<version>19</version>
</parent>

<modules>
<module>sonar-elixir-plugin</module>
</modules>
Expand Down Expand Up @@ -51,28 +45,28 @@
<dev.nick>arthepsy</dev.nick>
<dev.name>Andris Raugulis</dev.name>
<dev.mail>[email protected]</dev.mail>
<sonar.version>4.5</sonar.version>
<sonar.version>7.3</sonar.version>
<maven.buildNumber.timestampFormat>{0,date,yyyy-MM-dd HH:mm:ssa}</maven.buildNumber.timestampFormat>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.codehaus.sonar</groupId>
<groupId>org.sonarsource.sonarqube</groupId>
<artifactId>sonar-plugin-api</artifactId>
<version>${sonar.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.codehaus.sonar</groupId>
<groupId>org.sonarsource.sonarqube</groupId>
<artifactId>sonar-core</artifactId>
<version>${sonar.version}</version>
<scope>provided</scope>
</dependency>
<!-- unit tests -->
<dependency>
<groupId>org.codehaus.sonar</groupId>
<groupId>org.sonarsource.sonarqube</groupId>
<artifactId>sonar-testing-harness</artifactId>
<version>${sonar.version}</version>
<scope>test</scope>
Expand All @@ -98,6 +92,8 @@
<arg>-Xlint:unchecked</arg>
<arg>-Xlint:deprecation</arg>
</compilerArgs>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
Expand Down Expand Up @@ -135,6 +131,18 @@
</properties>
</configuration>
</plugin>
<plugin>
<groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId>
<artifactId>sonar-packaging-maven-plugin</artifactId>
<version>1.17</version>
<extensions>true</extensions>
<configuration>
<pluginClass>eu.arthepsy.sonar.plugins.elixir.ElixirPlugin</pluginClass>
<pluginIssueTrackerUrl>https://github.com/arthepsy/sonar-elixir</pluginIssueTrackerUrl>
<pluginSourcesUrl>https://github.com/arthepsy/sonar-elixir</pluginSourcesUrl>
<pluginUrl>https://github.com/arthepsy/sonar-elixir</pluginUrl>
</configuration>
</plugin>
</plugins>
</build>

Expand Down
6 changes: 3 additions & 3 deletions sonar-elixir-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,16 @@

<dependencies>
<dependency>
<groupId>org.codehaus.sonar</groupId>
<groupId>org.sonarsource.sonarqube</groupId>
<artifactId>sonar-plugin-api</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.sonar</groupId>
<groupId>org.sonarsource.sonarqube</groupId>
<artifactId>sonar-core</artifactId>
</dependency>
<!-- unit tests -->
<dependency>
<groupId>org.codehaus.sonar</groupId>
<groupId>org.sonarsource.sonarqube</groupId>
<artifactId>sonar-testing-harness</artifactId>
<scope>test</scope>
</dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,6 @@
*/
package eu.arthepsy.sonar.plugins.elixir;

import com.google.common.collect.ImmutableList;
import org.sonar.api.config.PropertyDefinition;

import java.util.List;

public final class ElixirConfiguration {
public static final String LOG_PREFIX = "[elixir] ";

public static List<PropertyDefinition> getPropertyDefinitions() {
ImmutableList.Builder<PropertyDefinition> properties = ImmutableList.builder();
return properties.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,15 @@
*/
package eu.arthepsy.sonar.plugins.elixir;

import com.google.common.collect.ImmutableList;
import eu.arthepsy.sonar.plugins.elixir.language.Elixir;
import eu.arthepsy.sonar.plugins.elixir.language.ElixirMeasureSensor;
import eu.arthepsy.sonar.plugins.elixir.rule.ElixirQualityProfile;
import org.sonar.api.SonarPlugin;
import org.sonar.api.Plugin;

import java.util.List;

public class ElixirPlugin extends SonarPlugin {
public class ElixirPlugin implements Plugin {

@Override
public List getExtensions() {
ImmutableList.Builder<Object> builder = ImmutableList.builder();
builder.addAll(ElixirConfiguration.getPropertyDefinitions());
builder.add(Elixir.class);
builder.add(ElixirQualityProfile.class);
builder.add(ElixirMeasureSensor.class);
return builder.build();
public void define(Context context) {
context.addExtensions(Elixir.class, ElixirQualityProfile.class, ElixirMeasureSensor.class);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,22 @@
package eu.arthepsy.sonar.plugins.elixir.language;

import eu.arthepsy.sonar.plugins.elixir.ElixirConfiguration;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.FilePredicate;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.Sensor;
import org.sonar.api.batch.SensorContext;
import org.sonar.api.batch.measure.MetricFinder;
import org.sonar.api.batch.sensor.Sensor;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.SensorDescriptor;
import org.sonar.api.batch.sensor.measure.NewMeasure;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.resources.Project;
import org.sonar.api.utils.ParsingUtils;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ElixirMeasureSensor implements Sensor {

Expand All @@ -50,32 +48,33 @@ public class ElixirMeasureSensor implements Sensor {

private final FileSystem fileSystem;
private final FilePredicate mainFilePredicate;
private final MetricFinder metricFinder;


public ElixirMeasureSensor(FileSystem fileSystem) {
public ElixirMeasureSensor(FileSystem fileSystem, MetricFinder metricFinder) {
this.fileSystem = fileSystem;
this.mainFilePredicate = fileSystem.predicates().and(
fileSystem.predicates().hasType(InputFile.Type.MAIN),
fileSystem.predicates().hasLanguage(Elixir.KEY));
this.metricFinder = metricFinder;
}

@Override
public void analyse(Project project, SensorContext context) {
public void describe(SensorDescriptor sensorDescriptor) {
}

public void execute(SensorContext context) {
LOG.info("[elixir] analyse");
for (InputFile file : fileSystem.inputFiles(mainFilePredicate )) {
for (InputFile file : fileSystem.inputFiles(mainFilePredicate)) {
processMainFile(file, context);
}
}

@Override
public boolean shouldExecuteOnProject(Project project) {
return fileSystem.hasFiles(mainFilePredicate);
}

private void processMainFile(InputFile inputFile, SensorContext context) {
List<String> lines;
try {
lines = Files.readAllLines(Paths.get(inputFile.absolutePath()), fileSystem.encoding());
String contents = inputFile.contents();
lines = Arrays.asList(contents.split("\\r?\\n"));
} catch (IOException e) {
LOG.warn(LOG_PREFIX + "could not process file: " + inputFile.toString());
return;
Expand All @@ -84,21 +83,24 @@ private void processMainFile(InputFile inputFile, SensorContext context) {
parser.parse(lines);

LOG.debug(LOG_PREFIX + "processing file: " + inputFile.toString());
double linesOfCode = parser.getLineCount() - parser.getEmptyLineCount() - parser.getCommentLineCount();
context.saveMeasure(inputFile, CoreMetrics.LINES, (double)parser.getLineCount());
context.saveMeasure(inputFile, CoreMetrics.NCLOC, (double)linesOfCode);
context.saveMeasure(inputFile, CoreMetrics.COMMENT_LINES, (double)parser.getCommentLineCount());
int linesOfCode = parser.getLineCount() - parser.getEmptyLineCount() - parser.getCommentLineCount();
saveMeasure(inputFile, context, CoreMetrics.LINES_KEY, parser.getLineCount());
saveMeasure(inputFile, context, CoreMetrics.NCLOC_KEY, linesOfCode);
saveMeasure(inputFile, context, CoreMetrics.COMMENT_LINES_KEY, parser.getCommentLineCount());

int functionCount = parser.getPublicFunctionCount() + parser.getPrivateFunctionCount();
saveMeasure(inputFile, context, CoreMetrics.FUNCTIONS_KEY, functionCount);
saveMeasure(inputFile, context, CoreMetrics.CLASSES_KEY, parser.getClassCount());

double publicApi = parser.getPublicFunctionCount() + parser.getClassCount();
double documentedApi = parser.getDocumentedPublicFunctionCount() + parser.getDocumentedClassCount();
double undocumentedApi = publicApi - documentedApi;
double documentedApiDensity = (publicApi == 0 ? 100.0 : ParsingUtils.scaleValue(documentedApi / publicApi * 100, 2));
context.saveMeasure(inputFile, CoreMetrics.PUBLIC_API, publicApi);
context.saveMeasure(inputFile, CoreMetrics.PUBLIC_UNDOCUMENTED_API, undocumentedApi);
context.saveMeasure(inputFile, CoreMetrics.PUBLIC_DOCUMENTED_API_DENSITY, documentedApiDensity);
}

double functionCount = parser.getPublicFunctionCount() + parser.getPrivateFunctionCount();
context.saveMeasure(inputFile, CoreMetrics.CLASSES, (double)parser.getClassCount());
context.saveMeasure(inputFile, CoreMetrics.FUNCTIONS, (double)(functionCount));
private void saveMeasure(InputFile inputFile, SensorContext context, String metricKey, Serializable value) {
org.sonar.api.batch.measure.Metric<Serializable> metric = metricFinder.findByKey(metricKey);
if (metric == null) {
throw new IllegalStateException("Unknown metric with key: " + metricKey);
}
NewMeasure<Serializable> measure = context.newMeasure().forMetric(metric).on(inputFile);
measure.withValue(value);
measure.save();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ public class ElixirParser {
private int classCount = 0;
private int publicFunctionCount = 0;
private int privateFunctionCount = 0;
private int documentedClassCount = 0;
private int documentedPrivateFunctionCount = 0;
private int documentedPublicFunctionCount = 0;

private final Pattern defPattern = Pattern.compile("^\\s*def(|p|module|struct)\\s(.*)$");
private final Matcher defMatcher = defPattern.matcher("");
Expand All @@ -47,29 +44,20 @@ public class ElixirParser {
private final Pattern docPattern = Pattern.compile("^\\s*@(doc|moduledoc|typedoc)([\"\\s].*)$");
private final Matcher docMatcher = docPattern.matcher("");

private boolean hasDoc = false;
private boolean inClass = false;
ElixirParser() { }

public ElixirParser() { }
int getLineCount() { return lineCount; }
int getEmptyLineCount() { return emptyLineCount; }
int getCommentLineCount() { return commentLineCount; }
int getClassCount() { return classCount; }
int getPublicFunctionCount() { return publicFunctionCount; }
int getPrivateFunctionCount() { return privateFunctionCount; }

public int getLineCount() { return lineCount; }
public int getEmptyLineCount() { return emptyLineCount; }
public int getCommentLineCount() { return commentLineCount; }
public int getClassCount() { return classCount; }
public int getPublicFunctionCount() { return publicFunctionCount; }
public int getPrivateFunctionCount() { return privateFunctionCount; }
public int getDocumentedClassCount() { return documentedClassCount; }
public int getDocumentedPublicFunctionCount() { return documentedPublicFunctionCount; }
public int getDocumentedPrivateFunctionCount() { return documentedPrivateFunctionCount; }

public void parse(List<String> lines) {
void parse(List<String> lines) {
this.parseLines(lines);
}

private void parseLines(List<String> lines) {
hasDoc = false;
inClass = false;

lineCount = lines.size();
for (int i = 0; i < lineCount; i++) {
String line = lines.get(i);
Expand All @@ -80,21 +68,6 @@ private void parseLines(List<String> lines) {
boolean inDoc = docMatcher.find();
if (inDoc) {
commentLineCount++;
String docHead = docMatcher.group(2).trim();
if (! (StringUtils.equalsIgnoreCase(docHead, "false") || StringUtils.equalsIgnoreCase(docHead, "nil"))) {
switch (docMatcher.group(1)) {
case "doc":
hasDoc = true;
break;
case "moduledoc":
if (inClass) {
documentedClassCount++;
}
break;
case "typedoc":
break;
}
}
}
heredocMatcher.reset(line);
if (heredocMatcher.find()) {
Expand All @@ -116,22 +89,14 @@ private void parseLines(List<String> lines) {
switch (defMatcher.group(1)) {
case "module":
classCount++;
inClass = true;
break;
case "":
publicFunctionCount++;
if (hasDoc) {
documentedPublicFunctionCount++;
}
break;
case "p":
privateFunctionCount++;
if (hasDoc) {
documentedPrivateFunctionCount++;
}
break;
}
hasDoc = false;
}
if (line.matches("^\\s*#.*$")) {
commentLineCount++;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,15 @@
package eu.arthepsy.sonar.plugins.elixir.rule;

import eu.arthepsy.sonar.plugins.elixir.language.Elixir;
import org.sonar.api.profiles.ProfileDefinition;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.utils.ValidationMessages;
import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition;

public class ElixirQualityProfile extends ProfileDefinition {
public class ElixirQualityProfile implements BuiltInQualityProfilesDefinition {
private static final String DEFAULT_PROFILE = "Sonar way";

@Override
public RulesProfile createProfile(ValidationMessages validationMessages) {
final RulesProfile profile = RulesProfile.create(DEFAULT_PROFILE, Elixir.KEY);
//parser.parse(profile);
//parser.log(LoggerFactory.getLogger(ScapegoatQualityProfile.class), ScapegoatConfiguration.LOG_PREFIX);
return profile;
public void define(Context context) {
NewBuiltInQualityProfile profile = context.createBuiltInQualityProfile(DEFAULT_PROFILE, Elixir.KEY);
profile.setDefault(true);
profile.done();
}
}
Loading