Permalink
Browse files

SONAR-2792 Import code of JaCoCo plugin from Plugins Forge

Revision 4564.
  • Loading branch information...
1 parent cbccf1e commit a887c65cf1b03d210cea3cf98dc81e6a509ef572 @Godin Godin committed Oct 13, 2011
Showing with 2,551 additions and 0 deletions.
  1. +139 −0 plugins/sonar-jacoco-plugin/pom.xml
  2. +150 −0 plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/AbstractAnalyzer.java
  3. +62 −0 plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/JaCoCoAgentDownloader.java
  4. +93 −0 plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/JaCoCoMavenPluginHandler.java
  5. +132 −0 plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/JaCoCoPlugin.java
  6. +70 −0 plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/JaCoCoSensor.java
  7. +38 −0 plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/JaCoCoUtils.java
  8. +144 −0 plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/JacocoAntInitializer.java
  9. +76 −0 plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/JacocoConfiguration.java
  10. +53 −0 plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/JacocoMavenInitializer.java
  11. +72 −0 ...ar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/AbstractCoverageDecorator.java
  12. +55 −0 ...ar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/ItBranchCoverageDecorator.java
  13. +61 −0 ...ns/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/ItCoverageDecorator.java
  14. +44 −0 plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/ItCoverageWidget.java
  15. +55 −0 ...onar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/ItLineCoverageDecorator.java
  16. +130 −0 plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/JaCoCoItMetrics.java
  17. +103 −0 plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/JaCoCoItSensor.java
  18. +39 −0 ...oco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/viewer/CoverageViewerDefinition.java
  19. +150 −0 ...-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/viewer/client/CoveragePanel.java
  20. +69 −0 ...jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/viewer/client/CoverageViewer.java
  21. +42 −0 .../sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/viewer/client/Metrics.java
  22. +10 −0 ...acoco-plugin/src/main/resources/org/sonar/plugins/jacoco/itcoverage/viewer/CoverageViewer.gwt.xml
  23. +32 −0 plugins/sonar-jacoco-plugin/src/main/resources/org/sonar/plugins/jacoco/itcoverage/widget.html.erb
  24. +40 −0 plugins/sonar-jacoco-plugin/src/test/java/org/sonar/plugins/jacoco/AbstractAnalyzerTest.java
  25. +91 −0 plugins/sonar-jacoco-plugin/src/test/java/org/sonar/plugins/jacoco/JaCoCoMavenPluginHandlerTest.java
  26. +53 −0 plugins/sonar-jacoco-plugin/src/test/java/org/sonar/plugins/jacoco/JaCoCoPluginTest.java
  27. +120 −0 plugins/sonar-jacoco-plugin/src/test/java/org/sonar/plugins/jacoco/JaCoCoSensorTest.java
  28. +93 −0 plugins/sonar-jacoco-plugin/src/test/java/org/sonar/plugins/jacoco/JacocoConfigurationTest.java
  29. +88 −0 plugins/sonar-jacoco-plugin/src/test/java/org/sonar/plugins/jacoco/JacocoMavenInitializerTest.java
  30. +38 −0 ...s/sonar-jacoco-plugin/src/test/java/org/sonar/plugins/jacoco/itcoverage/ItCoverageWidgetTest.java
  31. +34 −0 ...ns/sonar-jacoco-plugin/src/test/java/org/sonar/plugins/jacoco/itcoverage/JaCoCoItMetricsTest.java
  32. +119 −0 ...ins/sonar-jacoco-plugin/src/test/java/org/sonar/plugins/jacoco/itcoverage/JaCoCoItSensorTest.java
  33. +18 −0 ...ar-jacoco-plugin/src/test/resources/org/sonar/plugins/jacoco/JaCoCoMavenPluginHandlerTest/pom.xml
  34. +25 −0 ...r-jacoco-plugin/src/test/resources/org/sonar/plugins/jacoco/JaCoCoMavenPluginHandlerTest/pom2.xml
  35. BIN plugins/sonar-jacoco-plugin/src/test/resources/org/sonar/plugins/jacoco/JaCoCoSensorTest/Hello.class
  36. BIN plugins/sonar-jacoco-plugin/src/test/resources/org/sonar/plugins/jacoco/JaCoCoSensorTest/jacoco.exec
  37. +1 −0 pom.xml
  38. +6 −0 sonar-application/pom.xml
  39. +6 −0 sonar-server/pom.xml
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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</groupId>
+ <artifactId>sonar</artifactId>
+ <version>2.12-SNAPSHOT</version>
+ <relativePath>../..</relativePath>
+ </parent>
+
+ <groupId>org.codehaus.sonar.plugins</groupId>
+ <artifactId>sonar-jacoco-plugin</artifactId>
+ <packaging>sonar-plugin</packaging>
+
+ <name>Sonar :: Plugins :: JaCoCo</name>
+ <description>JaCoCo is an alternative to Clover and Cobertura to measure coverage by unit tests.</description>
+ <url>http://docs.codehaus.org/display/SONAR/JaCoCo+Plugin</url>
+ <inceptionYear>2010</inceptionYear>
+ <organization>
+ <name>SonarSource</name>
+ <url>http://www.sonarsource.com</url>
+ </organization>
+ <licenses>
+ <license>
+ <name>GNU LGPL 3</name>
+ <url>http://www.gnu.org/licenses/lgpl.txt</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+
+ <developers>
+ <developer>
+ <id>godin</id>
+ <name>Evgeny Mandrikov</name>
+ </developer>
+ </developers>
+
+ <properties>
+ <jacoco.version>0.5.3.201107060350</jacoco.version>
+
+ <sonar.pluginName>JaCoCo</sonar.pluginName>
+ <sonar.pluginClass>org.sonar.plugins.jacoco.JaCoCoPlugin</sonar.pluginClass>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.jacoco</groupId>
+ <artifactId>org.jacoco.core</artifactId>
+ <version>${jacoco.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jacoco</groupId>
+ <artifactId>org.jacoco.agent</artifactId>
+ <version>${jacoco.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.sonar</groupId>
+ <artifactId>sonar-plugin-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.sonar</groupId>
+ <artifactId>sonar-gwt-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <!-- Would be provided by environment -->
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.7.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <!-- unit tests -->
+ <dependency>
+ <groupId>org.codehaus.sonar</groupId>
+ <artifactId>sonar-testing-harness</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project</artifactId>
+ <version>2.0.7</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <!-- TODO Godin: investigate why doesn't work without declaration of this plugin here -->
+ <plugin>
+ <groupId>org.codehaus.sonar</groupId>
+ <artifactId>sonar-packaging-maven-plugin</artifactId>
+ <extensions>true</extensions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>gwt-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <configuration>
+ <modules>
+ <module>org.sonar.plugins.jacoco.itcoverage.viewer.CoverageViewer</module>
+ </modules>
+ <skip>${skipGwt}</skip>
+ <webappDirectory>${project.build.directory}/classes</webappDirectory>
+
+ <!-- do not break on two lines -->
+ <extraJvmArgs>${extraJvmArgs}</extraJvmArgs>
+ </configuration>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.sonar</groupId>
+ <artifactId>sonar-dev-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>trim</id>
+ <phase>process-resources</phase>
+ <goals>
+ <goal>trim</goal>
+ </goals>
+ <configuration>
+ <directory>${project.build.outputDirectory}</directory>
+ <includes>
+ <include>**/*.erb</include>
+ </includes>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
@@ -0,0 +1,150 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.plugins.jacoco;
+
+import org.apache.commons.lang.StringUtils;
+import org.jacoco.core.analysis.*;
+import org.jacoco.core.data.ExecutionDataReader;
+import org.jacoco.core.data.ExecutionDataStore;
+import org.jacoco.core.data.SessionInfoStore;
+import org.sonar.api.batch.SensorContext;
+import org.sonar.api.measures.CoverageMeasuresBuilder;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.resources.JavaFile;
+import org.sonar.api.resources.Project;
+import org.sonar.api.utils.SonarException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Collection;
+
+/**
+ * @author Evgeny Mandrikov
+ */
+public abstract class AbstractAnalyzer {
+
+ public final void analyse(Project project, SensorContext context) {
+ final File buildOutputDir = project.getFileSystem().getBuildOutputDir();
+ if (!buildOutputDir.exists()) {
+ JaCoCoUtils.LOG.info("Can't find build output directory: {}. Skipping JaCoCo analysis.", buildOutputDir);
+ return;
+ }
+ String path = getReportPath(project);
+ File jacocoExecutionData = project.getFileSystem().resolvePath(path);
+ try {
+ readExecutionData(jacocoExecutionData, buildOutputDir, context);
+ } catch (IOException e) {
+ throw new SonarException(e);
+ }
+ }
+
+ public final void readExecutionData(File jacocoExecutionData, File buildOutputDir, SensorContext context) throws IOException {
+ SessionInfoStore sessionInfoStore = new SessionInfoStore();
+ ExecutionDataStore executionDataStore = new ExecutionDataStore();
+
+ if (jacocoExecutionData == null || !jacocoExecutionData.exists() || !jacocoExecutionData.isFile()) {
+ JaCoCoUtils.LOG.info("Can't find JaCoCo execution data : {}. Project coverage is set to 0%.", jacocoExecutionData);
+ } else {
+ JaCoCoUtils.LOG.info("Analysing {}", jacocoExecutionData);
+ ExecutionDataReader reader = new ExecutionDataReader(new FileInputStream(jacocoExecutionData));
+ reader.setSessionInfoVisitor(sessionInfoStore);
+ reader.setExecutionDataVisitor(executionDataStore);
+ reader.read();
+ }
+
+ CoverageBuilder coverageBuilder = new CoverageBuilder();
+ Analyzer analyzer = new Analyzer(executionDataStore, coverageBuilder);
+ analyzeAll(analyzer, buildOutputDir);
+
+ int analyzedResources = 0;
+ for (ISourceFileCoverage coverage : coverageBuilder.getSourceFiles()) {
+ JavaFile resource = getResource(coverage);
+ // Do not save measures on resource which doesn't exist in the context
+ if (context.getResource(resource) != null) {
+ analyzeFile(resource, coverage, context);
+ analyzedResources++;
+ }
+ }
+ if (analyzedResources == 0) {
+ JaCoCoUtils.LOG.warn("Coverage information was not collected. Perhaps you forget to include debug information into compiled classes?");
+ }
+ }
+
+ static JavaFile getResource(ISourceFileCoverage coverage) {
+ String packageName = StringUtils.replaceChars(coverage.getPackageName(), '/', '.');
+ String fileName = StringUtils.substringBeforeLast(coverage.getName(), ".");
+ return new JavaFile(packageName, fileName);
+ }
+
+ /**
+ * Copied from {@link Analyzer#analyzeAll(File)} in order to add logging.
+ */
+ private void analyzeAll(Analyzer analyzer, File file) {
+ if (file.isDirectory()) {
+ for (File f : file.listFiles()) {
+ analyzeAll(analyzer, f);
+ }
+ } else {
+ try {
+ analyzer.analyzeAll(file);
+ } catch (Exception e) {
+ JaCoCoUtils.LOG.warn("Exception during analysis of file " + file.getAbsolutePath(), e);
+ }
+ }
+ }
+
+ private void analyzeFile(JavaFile resource, ISourceFileCoverage coverage, SensorContext context) {
+ CoverageMeasuresBuilder builder = CoverageMeasuresBuilder.create();
+ for (int lineId = coverage.getFirstLine(); lineId <= coverage.getLastLine(); lineId++) {
+ final int hits;
+ ILine line = coverage.getLine(lineId);
+ switch (line.getInstructionCounter().getStatus()) {
+ case ICounter.FULLY_COVERED:
+ case ICounter.PARTLY_COVERED:
+ hits = 1;
+ break;
+ case ICounter.NOT_COVERED:
+ hits = 0;
+ break;
+ case ICounter.EMPTY:
+ continue;
+ default:
+ JaCoCoUtils.LOG.warn("Unknown status for line {} in {}", lineId, resource);
+ continue;
+ }
+ builder.setHits(lineId, hits);
+
+ ICounter branchCounter = line.getBranchCounter();
+ int conditions = branchCounter.getTotalCount();
+ if (conditions > 0) {
+ int coveredConditions = branchCounter.getCoveredCount();
+ builder.setConditions(lineId, conditions, coveredConditions);
+ }
+ }
+
+ saveMeasures(context, resource, builder.createMeasures());
+ }
+
+ protected abstract void saveMeasures(SensorContext context, JavaFile resource, Collection<Measure> measures);
+
+ protected abstract String getReportPath(Project project);
+
+}
@@ -0,0 +1,62 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.plugins.jacoco;
+
+import org.apache.commons.io.FileUtils;
+import org.jacoco.agent.AgentJar;
+import org.jacoco.core.JaCoCo;
+import org.sonar.api.BatchExtension;
+import org.sonar.api.utils.SonarException;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * @author Evgeny Mandrikov
+ */
+public class JaCoCoAgentDownloader implements BatchExtension {
+
+ /**
+ * Dirty hack, but it allows to extract agent only once during Sonar analyzes for multi-module project.
+ */
+ private static File agentJarFile;
+
+ public JaCoCoAgentDownloader() {
+ }
+
+ public synchronized File getAgentJarFile() {
+ if (agentJarFile == null) {
+ agentJarFile = extractAgent();
+ }
+ return agentJarFile;
+ }
+
+ private File extractAgent() {
+ try {
+ File agent = File.createTempFile("jacocoagent", ".jar");
+ AgentJar.extractTo(agent);
+ FileUtils.forceDeleteOnExit(agent); // TODO evil method
+ JaCoCoUtils.LOG.info("JaCoCo agent (version " + JaCoCo.VERSION + ") extracted: {}", agent);
+ return agent;
+ } catch (IOException e) {
+ throw new SonarException(e);
+ }
+ }
+}
Oops, something went wrong.

0 comments on commit a887c65

Please sign in to comment.