Sonar 质量扫描的输出日志--对应源码的跟踪(二){sonar engine源码}
一个project下面module完整的sonar分析日志:
[INFO] --- sonar-maven-plugin:3.2:sonar (default-cli) @ pcaic-parent ---
[INFO] User cache: /root/.sonar/cache
5.475: [GC (Metadata GC Threshold) [PSYoungGen: 124155K->16378K(212992K)] 125048K->20534K(337920K), 0.0249154 secs] [Times: user=0.08 sys=0.00, real=0.03 secs]
5.500: [Full GC (Metadata GC Threshold) [PSYoungGen: 16378K->0K(212992K)] [ParOldGen: 4156K->19951K(172032K)] 20534K->19951K(385024K), [Metaspace: 20709K->20709K(1069056K)], 0.1078064 secs] [Times: user=0.46 sys=0.01, real=0.11 secs]
[INFO] Load global repositories
[INFO] Load global repositories (done) | time=143ms
[WARNING] Property 'sonar.jdbc.url' is not supported any more. It will be ignored. There is no longer any DB connection to the SQ database.
[WARNING] Property 'sonar.jdbc.username' is not supported any more. It will be ignored. There is no longer any DB connection to the SQ database.
[WARNING] Property 'sonar.jdbc.password' is not supported any more. It will be ignored. There is no longer any DB connection to the SQ database.
[INFO] User cache: /root/.sonar/cache
[INFO] Load plugins index
[INFO] Load plugins index (done) | time=2ms
[INFO] Plugin [l10nzh] defines 'l10nen' as base plugin. This metadata can be removed from manifest of l10n plugins since version 5.2.
[INFO] SonarQube version: 6.2
7.243: [GC (Allocation Failure) [PSYoungGen: 196608K->21479K(318976K)] 216559K->73599K(491008K), 0.0467409 secs] [Times: user=0.14 sys=0.04, real=0.05 secs]
[WARNING] Missing POM for com.suning.framework:snf-zk-client:jar:1.1.1
[WARNING] Missing POM for com.suning.framework:snf-zk-client:jar:1.1.1
8.358: [GC (Allocation Failure) [PSYoungGen: 318951K->25791K(394240K)] 371071K->77919K(566272K), 0.0259672 secs] [Times: user=0.11 sys=0.02, real=0.02 secs]
[INFO] artifact org.jxls:jxls: checking for updates from suning_maven_repo
[INFO] artifact org.webjars.bower:jquery: checking for updates from suning_maven_repo
[INFO] artifact org.webjars.bower:angular: checking for updates from suning_maven_repo
[INFO] artifact org.webjars.bower:angular: checking for updates from suning_maven_repo
[INFO] artifact org.webjars.bower:eonasdan-bootstrap-datetimepicker: checking for updates from suning_maven_repo
[INFO] artifact org.webjars.bower:moment: checking for updates from suning_maven_repo
[INFO] artifact org.webjars.bower:moment: checking for updates from suning_maven_repo
[INFO] artifact org.webjars.bower:bootstrap: checking for updates from suning_maven_repo
[INFO] artifact org.webjars.bower:jquery: checking for updates from suning_maven_repo
[INFO] artifact org.webjars.bower:bootstrap: checking for updates from suning_maven_repo
[INFO] artifact org.webjars.bower:jquery: checking for updates from suning_maven_repo
[INFO] artifact org.webjars.bower:angular: checking for updates from suning_maven_repo
[INFO] artifact org.webjars.bower:codemirror: checking for updates from suning_maven_repo
[INFO] artifact org.webjars.bower:angular: checking for updates from suning_maven_repo
[INFO] artifact org.webjars.bower:angular: checking for updates from suning_maven_repo
[INFO] artifact org.webjars.bower:angular: checking for updates from suning_maven_repo
[INFO] artifact org.webjars.bower:js-xlsx: checking for updates from suning_maven_repo
10.054: [GC (Allocation Failure) [PSYoungGen: 378047K->29227K(494080K)] 430175K->81362K(666112K), 0.0336199 secs] [Times: user=0.21 sys=0.02, real=0.04 secs]
[INFO] Default locale: "zh_CN", source code encoding: "UTF-8"
[INFO] Process project properties
[INFO] Load project repositories
[INFO] Load project repositories (done) | time=305ms
11.048: [GC (Metadata GC Threshold) [PSYoungGen: 125853K->36969K(494592K)] 177989K->89113K(666624K), 0.0228080 secs] [Times: user=0.09 sys=0.02, real=0.02 secs]
11.071: [Full GC (Metadata GC Threshold) [PSYoungGen: 36969K->0K(494592K)] [ParOldGen: 52143K->75639K(318976K)] 89113K->75639K(813568K), [Metaspace: 34292K->34292K(1081344K)], 0.1395758 secs] [Times: user=0.60 sys=0.03, real=0.14 secs]
[INFO] Load quality profiles
[INFO] Load quality profiles (done) | time=22ms
[INFO] Load active rules
[INFO] Load active rules (done) | time=647ms
[INFO] Publish mode
[INFO] ------------- Scan suning's pcids caic common 20180509
[INFO] Language is forced to java
[INFO] Load server rules
[INFO] Load server rules (done) | time=142ms
[INFO] Initializer GenericCoverageSensor
[INFO] Initializer GenericCoverageSensor (done) | time=1ms
[INFO] Base dir: /data/jenkinsslave/workspace/pcids_caic20180509/pcaic-common
[INFO] Working dir: /data/jenkinsslave/workspace/pcids_caic20180509/pcaic-common/target/sonar
[INFO] Source paths: pom.xml, src/main/java
[INFO] Source encoding: UTF-8, default locale: zh_CN
[INFO] Index files
[INFO] 47 files indexed
[INFO] Quality profile for java: Sonarway54
[INFO] Sensor Lines Sensor
[INFO] Sensor Lines Sensor (done) | time=17ms
[INFO] Sensor JavaSquidSensor
[INFO] Configured Java source version (sonar.java.source): 8
[INFO] JavaClasspath initialization
[INFO] JavaClasspath initialization (done) | time=13ms
[INFO] JavaTestClasspath initialization
[INFO] JavaTestClasspath initialization (done) | time=3ms
[INFO] Java Main Files AST scan
[INFO] 47 source files to be analyzed
[WARNING] Metric 'lines' is an internal metric computed by SonarQube. Provided value is ignored.
16.331: [GC (Allocation Failure) [PSYoungGen: 452608K->28914K(606208K)] 528247K->104581K(925184K), 0.0573675 secs] [Times: user=0.20 sys=0.02, real=0.06 secs]
[INFO] [INFO] 47/47 source files have been analyzed
Java Main Files AST scan (done) | time=3857ms
[INFO] Java Test Files AST scan
[INFO] 0 source files to be analyzed
[INFO] Java Test Files AST scan (done) | time=0ms
[INFO] Sensor JavaSquidSensor (done) | time=4341ms
[INFO] [INFO] Sensor SCM Sensor
0/0 source files have been analyzed
[INFO] Sensor SCM Sensor (done) | time=9ms
[INFO] Sensor Coverage Report Import
[INFO] Sensor Coverage Report Import (done) | time=0ms
[INFO] Sensor Coverage Report Import
[INFO] Sensor Coverage Report Import (done) | time=0ms
[INFO] Sensor Unit Test Results Import
[INFO] Sensor Unit Test Results Import (done) | time=0ms
[INFO] Sensor FindBugs Sensor
18.146: [GC (Metadata GC Threshold) [PSYoungGen: 298260K->13640K(625152K)] 373927K->89315K(944128K), 0.0345552 secs] [Times: user=0.14 sys=0.01, real=0.04 secs]
18.181: [Full GC (Metadata GC Threshold) [PSYoungGen: 13640K->0K(625152K)] [ParOldGen: 75674K->81834K(407040K)] 89315K->81834K(1032192K), [Metaspace: 57175K->57175K(1099776K)], 0.3274191 secs] [Times: user=1.63 sys=0.02, real=0.33 secs]
[INFO] Findbugs output report: /data/jenkinsslave/workspace/pcids_caic20180509/pcaic-common/target/sonar/findbugs-result.xml
23.374: [GC (Allocation Failure) [PSYoungGen: 580096K->34117K(734208K)] 661930K->115976K(1141248K), 0.0345130 secs] [Times: user=0.14 sys=0.01, real=0.04 secs]
[INFO] Sensor FindBugs Sensor (done) | time=6416ms
[INFO] Sensor SurefireSensor
[INFO] parsing /data/jenkinsslave/workspace/pcids_caic20180509/pcaic-common/target/surefire-reports
[INFO] Sensor SurefireSensor (done) | time=1ms
[INFO] Sensor JaCoCoSensor
[INFO] JaCoCoSensor: JaCoCo report not found : /data/jenkinsslave/workspace/pcids_caic20180509/pcaic-common/target/jacoco.exec
[INFO] Sensor JaCoCoSensor (done) | time=0ms
[INFO] Sensor JaCoCoItSensor
[INFO] JaCoCoItSensor: JaCoCo IT report not found: /data/jenkinsslave/workspace/pcids_caic20180509/pcaic-common/target/jacoco-it.exec
[INFO] Sensor JaCoCoItSensor (done) | time=0ms
[INFO] Sensor JaCoCoOverallSensor
[INFO] Sensor JaCoCoOverallSensor (done) | time=1ms
[INFO] Sensor XmlFileSensor
[INFO] Sensor XmlFileSensor (done) | time=0ms
[INFO] Sensor Zero Coverage Sensor
[INFO] Sensor Zero Coverage Sensor (done) | time=38ms
[INFO] Sensor Code Colorizer Sensor
[INFO] Sensor Code Colorizer Sensor (done) | time=2ms
[INFO] Sensor CPD Block Indexer
[INFO] JavaCpdBlockIndexer is used for java
[INFO] Sensor CPD Block Indexer (done) | time=68ms
load global repositories-> load plugin index -> load/process project properties -> Load project repositories
-> Load quality profiles -> Load active rules -> Language is forced to java ->Load server rules ->
Initializer GenericCoverageSensor
先看 sonar-scanner-protocol
GlobalRepositories bean:
public class GlobalRepositories {private long timestamp;private Collection<Metric> metrics = new ArrayList<>();private Map<String, String> globalSettings = new HashMap<>();public Map<String, String> globalSettings() {return globalSettings;}public GlobalRepositories addGlobalSetting(String key, String value) {globalSettings.put(key, value);return this;}public Collection<Metric> metrics() {return metrics;}public GlobalRepositories addMetric(Metric metric) {metrics.add(metric);return this;}public long timestamp() {return timestamp;}public void setTimestamp(long timestamp) {this.timestamp = timestamp;}public String toJson() {return GsonHelper.create().toJson(this);}public static GlobalRepositories fromJson(String json) {return GsonHelper.create().fromJson(json, GlobalRepositories.class);}}
ProjectRepositories bean 类:
public class ProjectRepositories {private long timestamp;private boolean exists;private Map<String, Map<String, String>> settingsByModule = new HashMap<>();private Map<String, Map<String, FileData>> fileDataByModuleAndPath = new HashMap<>();private Date lastAnalysisDate;public Map<String, String> settings(String moduleKey) {return settingsByModule.containsKey(moduleKey) ? settingsByModule.get(moduleKey) : Collections.<String, String>emptyMap();}public Map<String, Map<String, String>> settings() {return settingsByModule;}public ProjectRepositories addSettings(String moduleKey, Map<String, String> settings) {Map<String, String> existingSettings = settingsByModule.get(moduleKey);if (existingSettings == null) {existingSettings = new HashMap<>();settingsByModule.put(moduleKey, existingSettings);}existingSettings.putAll(settings);return this;}public boolean exists() {return exists;}public Map<String, Map<String, FileData>> fileDataByModuleAndPath() {return fileDataByModuleAndPath;}public Map<String, FileData> fileDataByPath(String moduleKey) {return fileDataByModuleAndPath.containsKey(moduleKey) ? fileDataByModuleAndPath.get(moduleKey) : Collections.<String, FileData>emptyMap();}public ProjectRepositories addFileData(String moduleKey, @Nullable String path, FileData fileData) {if (path == null || (fileData.hash() == null && fileData.revision() == null)) {return this;}Map<String, FileData> existingFileDataByPath = fileDataByModuleAndPath.get(moduleKey);if (existingFileDataByPath == null) {existingFileDataByPath = new HashMap<>();fileDataByModuleAndPath.put(moduleKey, existingFileDataByPath);}existingFileDataByPath.put(path, fileData);return this;}@CheckForNullpublic FileData fileData(String projectKey, String path) {return fileDataByPath(projectKey).get(path);}public long timestamp() {return timestamp;}public void setTimestamp(long timestamp) {this.timestamp = timestamp;}@CheckForNullpublic Date lastAnalysisDate() {return lastAnalysisDate;}public void setLastAnalysisDate(@Nullable Date lastAnalysisDate) {this.lastAnalysisDate = lastAnalysisDate;}public String toJson() {return GsonHelper.create().toJson(this);}public static ProjectRepositories fromJson(String json) {return GsonHelper.create().fromJson(json, ProjectRepositories.class);}
}
sonar scanner 扫描文件读取类ScannerReportReader
public class ScannerReportReader {private final FileStructure fileStructure;public ScannerReportReader(File dir) {this.fileStructure = new FileStructure(dir);}public ScannerReport.Metadata readMetadata() {File file = fileStructure.metadataFile();if (!fileExists(file)) {throw new IllegalStateException("Metadata file is missing in analysis report: " + file);}return Protobuf.read(file, ScannerReport.Metadata.parser());}public CloseableIterator<ScannerReport.ActiveRule> readActiveRules() {File file = fileStructure.activeRules();if (!fileExists(file)) {return emptyCloseableIterator();}return Protobuf.readStream(file, ScannerReport.ActiveRule.parser());}public CloseableIterator<ScannerReport.Measure> readComponentMeasures(int componentRef) {File file = fileStructure.fileFor(FileStructure.Domain.MEASURES, componentRef);if (fileExists(file)) {return Protobuf.readStream(file, ScannerReport.Measure.parser());}return emptyCloseableIterator();}@CheckForNullpublic ScannerReport.Changesets readChangesets(int componentRef) {File file = fileStructure.fileFor(FileStructure.Domain.CHANGESETS, componentRef);if (fileExists(file)) {return Protobuf.read(file, ScannerReport.Changesets.parser());}return null;}public ScannerReport.Component readComponent(int componentRef) {File file = fileStructure.fileFor(FileStructure.Domain.COMPONENT, componentRef);if (!fileExists(file)) {throw new IllegalStateException("Unable to find report for component #" + componentRef + ". File does not exist: " + file);}return Protobuf.read(file, ScannerReport.Component.parser());}public CloseableIterator<ScannerReport.Issue> readComponentIssues(int componentRef) {File file = fileStructure.fileFor(FileStructure.Domain.ISSUES, componentRef);if (fileExists(file)) {return Protobuf.readStream(file, ScannerReport.Issue.parser());}return emptyCloseableIterator();}public CloseableIterator<ScannerReport.Duplication> readComponentDuplications(int componentRef) {File file = fileStructure.fileFor(FileStructure.Domain.DUPLICATIONS, componentRef);if (fileExists(file)) {return Protobuf.readStream(file, ScannerReport.Duplication.parser());}return emptyCloseableIterator();}public CloseableIterator<ScannerReport.CpdTextBlock> readCpdTextBlocks(int componentRef) {File file = fileStructure.fileFor(FileStructure.Domain.CPD_TEXT_BLOCKS, componentRef);if (fileExists(file)) {return Protobuf.readStream(file, ScannerReport.CpdTextBlock.parser());}return emptyCloseableIterator();}public CloseableIterator<ScannerReport.Symbol> readComponentSymbols(int componentRef) {File file = fileStructure.fileFor(FileStructure.Domain.SYMBOLS, componentRef);if (fileExists(file)) {return Protobuf.readStream(file, ScannerReport.Symbol.parser());}return emptyCloseableIterator();}public boolean hasSyntaxHighlighting(int componentRef) {File file = fileStructure.fileFor(FileStructure.Domain.SYNTAX_HIGHLIGHTINGS, componentRef);return file.exists();}public CloseableIterator<ScannerReport.SyntaxHighlightingRule> readComponentSyntaxHighlighting(int fileRef) {File file = fileStructure.fileFor(FileStructure.Domain.SYNTAX_HIGHLIGHTINGS, fileRef);if (fileExists(file)) {return Protobuf.readStream(file, ScannerReport.SyntaxHighlightingRule.parser());}return emptyCloseableIterator();}public boolean hasCoverage(int componentRef) {File file = fileStructure.fileFor(FileStructure.Domain.COVERAGES, componentRef);return file.exists();}public CloseableIterator<ScannerReport.LineCoverage> readComponentCoverage(int fileRef) {File file = fileStructure.fileFor(FileStructure.Domain.COVERAGES, fileRef);if (fileExists(file)) {return Protobuf.readStream(file, ScannerReport.LineCoverage.parser());}return emptyCloseableIterator();}@CheckForNullpublic File readFileSource(int fileRef) {File file = fileStructure.fileFor(FileStructure.Domain.SOURCE, fileRef);if (fileExists(file)) {return file;}return null;}@CheckForNullpublic File readTests(int testFileRef) {File file = fileStructure.fileFor(FileStructure.Domain.TESTS, testFileRef);if (fileExists(file)) {return file;}return null;}@CheckForNullpublic File readCoverageDetails(int testFileRef) {File file = fileStructure.fileFor(FileStructure.Domain.COVERAGE_DETAILS, testFileRef);if (fileExists(file)) {return file;}return null;}public CloseableIterator<ScannerReport.ContextProperty> readContextProperties() {File file = fileStructure.contextProperties();if (!fileExists(file)) {return emptyCloseableIterator();}return Protobuf.readStream(file, ScannerReport.ContextProperty.parser());}private static boolean fileExists(File file) {return file.exists() && file.isFile();}public FileStructure getFileStructure() {return fileStructure;}
}
sonar 扫描生成的数据文件 写类 ScannerReportWriter
public class ScannerReportWriter {private final FileStructure fileStructure;public ScannerReportWriter(File dir) {if (!dir.exists() && !dir.mkdirs()) {throw new IllegalStateException("Unable to create directory: " + dir);}this.fileStructure = new FileStructure(dir);}public FileStructure getFileStructure() {return fileStructure;}public boolean hasComponentData(FileStructure.Domain domain, int componentRef) {File file = fileStructure.fileFor(domain, componentRef);return file.exists() && file.isFile();}/*** Metadata is mandatory*/public File writeMetadata(ScannerReport.Metadata metadata) {Protobuf.write(metadata, fileStructure.metadataFile());return fileStructure.metadataFile();}public File writeActiveRules(Iterable<ScannerReport.ActiveRule> activeRules) {Protobuf.writeStream(activeRules, fileStructure.activeRules(), false);return fileStructure.metadataFile();}public File writeComponent(ScannerReport.Component component) {File file = fileStructure.fileFor(FileStructure.Domain.COMPONENT, component.getRef());Protobuf.write(component, file);return file;}public File writeComponentIssues(int componentRef, Iterable<ScannerReport.Issue> issues) {File file = fileStructure.fileFor(FileStructure.Domain.ISSUES, componentRef);Protobuf.writeStream(issues, file, false);return file;}public void appendComponentIssue(int componentRef, ScannerReport.Issue issue) {File file = fileStructure.fileFor(FileStructure.Domain.ISSUES, componentRef);try (OutputStream out = new BufferedOutputStream(new FileOutputStream(file, true))) {issue.writeDelimitedTo(out);} catch (Exception e) {throw ContextException.of("Unable to write issue", e).addContext("file", file);}}public File writeComponentMeasures(int componentRef, Iterable<ScannerReport.Measure> measures) {File file = fileStructure.fileFor(FileStructure.Domain.MEASURES, componentRef);Protobuf.writeStream(measures, file, false);return file;}public File writeComponentChangesets(ScannerReport.Changesets changesets) {File file = fileStructure.fileFor(FileStructure.Domain.CHANGESETS, changesets.getComponentRef());Protobuf.write(changesets, file);return file;}public File writeComponentDuplications(int componentRef, Iterable<ScannerReport.Duplication> duplications) {File file = fileStructure.fileFor(FileStructure.Domain.DUPLICATIONS, componentRef);Protobuf.writeStream(duplications, file, false);return file;}public File writeCpdTextBlocks(int componentRef, Iterable<ScannerReport.CpdTextBlock> blocks) {File file = fileStructure.fileFor(FileStructure.Domain.CPD_TEXT_BLOCKS, componentRef);Protobuf.writeStream(blocks, file, false);return file;}public File writeComponentSymbols(int componentRef, Iterable<ScannerReport.Symbol> symbols) {File file = fileStructure.fileFor(FileStructure.Domain.SYMBOLS, componentRef);Protobuf.writeStream(symbols, file, false);return file;}public File writeComponentSyntaxHighlighting(int componentRef, Iterable<ScannerReport.SyntaxHighlightingRule> syntaxHighlightingRules) {File file = fileStructure.fileFor(FileStructure.Domain.SYNTAX_HIGHLIGHTINGS, componentRef);Protobuf.writeStream(syntaxHighlightingRules, file, false);return file;}public File writeComponentCoverage(int componentRef, Iterable<ScannerReport.LineCoverage> coverageList) {File file = fileStructure.fileFor(FileStructure.Domain.COVERAGES, componentRef);Protobuf.writeStream(coverageList, file, false);return file;}public File writeTests(int componentRef, Iterable<ScannerReport.Test> tests) {File file = fileStructure.fileFor(FileStructure.Domain.TESTS, componentRef);Protobuf.writeStream(tests, file, false);return file;}public File writeCoverageDetails(int componentRef, Iterable<ScannerReport.CoverageDetail> tests) {File file = fileStructure.fileFor(FileStructure.Domain.COVERAGE_DETAILS, componentRef);Protobuf.writeStream(tests, file, false);return file;}public File writeContextProperties(Iterable<ScannerReport.ContextProperty> properties) {File file = fileStructure.contextProperties();Protobuf.writeStream(properties, file, false);return file;}public File getSourceFile(int componentRef) {return fileStructure.fileFor(FileStructure.Domain.SOURCE, componentRef);}}
InitializersExecutor类:
/** SonarQube* Copyright (C) 2009-2016 SonarSource SA* mailto:contact 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.scanner.phases;import com.google.common.collect.Lists;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.batch.Initializer;
import org.sonar.api.resources.Project;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.api.utils.log.Profiler;
import org.sonar.scanner.bootstrap.BatchExtensionDictionnary;
import org.sonar.scanner.events.EventBus;
import java.util.Collection;public class InitializersExecutor {private static final Logger LOG = Loggers.get(SensorsExecutor.class);private Project project;private BatchExtensionDictionnary selector;private EventBus eventBus;public InitializersExecutor(BatchExtensionDictionnary selector, Project project, EventBus eventBus) {this.selector = selector;this.project = project;this.eventBus = eventBus;}public void execute() {Collection<Initializer> initializers = selector.select(Initializer.class, project, true, null);eventBus.fireEvent(new InitializersPhaseEvent(Lists.newArrayList(initializers), true));if (LOG.isDebugEnabled()) {LOG.debug("Initializers : {}", StringUtils.join(initializers, " -> "));}for (Initializer initializer : initializers) {eventBus.fireEvent(new InitializerExecutionEvent(initializer, true));Profiler profiler = Profiler.create(LOG).startInfo("Initializer " + initializer);initializer.execute(project);profiler.stopInfo();eventBus.fireEvent(new InitializerExecutionEvent(initializer, false));}eventBus.fireEvent(new InitializersPhaseEvent(Lists.newArrayList(initializers), false));}}
GenericCoverageSensor类:
package org.sonar.scanner.genericcoverage;import com.google.common.collect.ImmutableList;
import java.io.File;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.stream.Collectors;
import org.sonar.api.batch.Initializer;
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.config.PropertyDefinition;
import org.sonar.api.config.Settings;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;import static org.sonar.api.CoreProperties.CATEGORY_CODE_COVERAGE;public class GenericCoverageSensor extends Initializer implements Sensor {private static final Logger LOG = Loggers.get(GenericCoverageSensor.class);static final String REPORT_PATHS_PROPERTY_KEY = "sonar.coverageReportPaths";/*** @deprecated since 6.2*/@Deprecatedstatic final String OLD_REPORT_PATH_PROPERTY_KEY = "sonar.genericcoverage.reportPath";/*** @deprecated since 6.2*/@Deprecatedstatic final String OLD_COVERAGE_REPORT_PATHS_PROPERTY_KEY = "sonar.genericcoverage.reportPaths";/*** @deprecated since 6.2*/@Deprecatedstatic final String OLD_IT_COVERAGE_REPORT_PATHS_PROPERTY_KEY = "sonar.genericcoverage.itReportPaths";/*** @deprecated since 6.2*/@Deprecatedstatic final String OLD_OVERALL_COVERAGE_REPORT_PATHS_PROPERTY_KEY = "sonar.genericcoverage.overallReportPaths";private final Settings settings;public GenericCoverageSensor(Settings settings) {this.settings = settings;}public static ImmutableList<PropertyDefinition> properties() {return ImmutableList.of(PropertyDefinition.builder(REPORT_PATHS_PROPERTY_KEY).name("Coverage report paths").description("List of comma-separated paths (absolute or relative) containing coverage report.").category(CATEGORY_CODE_COVERAGE).onQualifiers(Qualifiers.PROJECT).deprecatedKey(OLD_COVERAGE_REPORT_PATHS_PROPERTY_KEY).build());}/*** Use an initializer to migrate old properties to the new one before Sensor phase so that* Sensor will not be executed if there is no report (thanks to SensorDescriptor.requireProperty(REPORT_PATH_PROPERTY_KEY))*/@Overridepublic void execute() {Set<String> reportPaths = new LinkedHashSet<>();reportPaths.addAll(Arrays.asList(settings.getStringArray(REPORT_PATHS_PROPERTY_KEY)));loadDeprecated(reportPaths, OLD_REPORT_PATH_PROPERTY_KEY);loadDeprecated(reportPaths, OLD_COVERAGE_REPORT_PATHS_PROPERTY_KEY);loadDeprecated(reportPaths, OLD_IT_COVERAGE_REPORT_PATHS_PROPERTY_KEY);loadDeprecated(reportPaths, OLD_OVERALL_COVERAGE_REPORT_PATHS_PROPERTY_KEY);if (!reportPaths.isEmpty()) {settings.setProperty(REPORT_PATHS_PROPERTY_KEY, reportPaths.stream().collect(Collectors.joining(",")));}}private void loadDeprecated(Set<String> reportPaths, String propertyKey) {if (settings.hasKey(propertyKey)) {LOG.warn("Property '{}' is deprecated. Please use '{}' instead.", propertyKey, REPORT_PATHS_PROPERTY_KEY);reportPaths.addAll(Arrays.asList(settings.getStringArray(propertyKey)));}}@Overridepublic void describe(SensorDescriptor descriptor) {descriptor.name("Generic Coverage Report").requireProperty(REPORT_PATHS_PROPERTY_KEY);}@Overridepublic void execute(SensorContext context) {for (String reportPath : settings.getStringArray(REPORT_PATHS_PROPERTY_KEY)) {File reportFile = context.fileSystem().resolvePath(reportPath);LOG.info("Parsing {}", reportFile);GenericCoverageReportParser parser = new GenericCoverageReportParser();parser.parse(reportFile, context);LOG.info("Imported coverage data for {} files", parser.numberOfMatchedFiles());int numberOfUnknownFiles = parser.numberOfUnknownFiles();if (numberOfUnknownFiles > 0) {LOG.info("Coverage data ignored for " + numberOfUnknownFiles + " unknown files, including:\n" + parser.firstUnknownFiles().stream().collect(Collectors.joining("\n")));}}}}
Sonar 质量扫描的输出日志--对应源码的跟踪(二){sonar engine源码}相关推荐
- Sonar 质量扫描的输出日志--对应源码的跟踪(一){源码解析sonar-scanner-maven3.2}
整个包的类目录: 类文件并不是很多,主入口类ScannerBootstrapper package org.sonarsource.scanner.maven.bootstrap;import jav ...
- 【FFmpeg】ffmpeg工具源码分析(二):转码核心函数 transcode
1.转码流程 1)转码前初始化:打开输入输出文件,初始化编码器.解码器.过滤器,创建多线程,设置串口终端等: 2)while循环处理每一包数据,核心函数 transcode_step(稍后分析): 3 ...
- Java源码详解二:HashMap源码分析--openjdk java 11源码
文章目录 HashMap.java介绍 1.HashMap的get和put操作平均时间复杂度和最坏时间复杂度 2.为什么链表长度超过8才转换为红黑树 3.红黑树中的节点如何排序 本系列是Java详解, ...
- ARouter 源码历险记 (二)
2019独角兽企业重金招聘Python工程师标准>>> 目录 ARouter 源码历险记 (一) ARouter 源码历险记 (二) ARouter 源码历险记 (三) ARoute ...
- Licode入门学习:MediaStream源码分析(二)
Licode服务与启动过程分析 MediaStream源码分析(一) MediaStream源码分析(二) MediaStream源码分析(三) WebRtcConnection源码分析(一) Web ...
- Licode入门学习:WebRtcConnection源码分析(二)
Licode服务与启动过程分析 WebRtcConnection源码分析(一) WebRtcConnection源码分析(二) WebRtcConnection源码分析(三) MediaStream源 ...
- Docker、Jenkins 结合 SonarQube 和 Sonar scanner 进行代码质量扫描
SonarQube是一个用于管理代码质量的开放平台,可以快速的定位代码中潜在的或者明显的错误.目前支持java,C#,C/C++,Python,PL/SQL,Cobol,JavaScrip,Groov ...
- DevOps之持续集成SonarQube代码质量扫描
SonarQube是一个用于代码质量检测管理的开放平台,可以集成不同的检测工具,代码分析工具,以及持续集成工具.SonarQube 并不是简单地把不同的代码检查工具结果直接显示在 Web ...
- log4j 禁止类输出日志_SpringBoot统一日志处理原理
阅读推荐 程序员跳槽时机已到,闲聊中面试官无意泄题 SpringBoot作为日常开发利器,开箱即用,大量的star等已经成为节省开发的重要框架之一,但是各个框架的star中引入的日志框架却不尽相同,有 ...
最新文章
- C# 利用WMI对象获取物理内存和可用内存大小
- python报错:UnicodeDecodeError: ‘ascii‘ codec can‘t decode byte 0xe0 in position 0: ordinal not in rang
- 20145237第六周学习总结
- HTC 败诉对 Android 意味着什么?
- Linux内核调试sysfs
- HCL安装和使用模拟器中遇到的问题
- 在用户空间加载和卸载驱动
- 633.平方数之和(力扣leetcode) 博主可答疑该问题
- 计算机字体安装按钮灰色,win10系统无法安装字体安装按钮灰色的的解决方法
- 管理信息系统期末测试题
- Python调用摄像头
- “十一”逃离京城的十五条自驾线路
- 论坛20大经典变态楼主主题和回复
- 离散数学知识点及错题集合 第一章
- 【SVA学习】01. 什么是断言(SVA)?
- mysql读写分离的完整配置
- java中available用法,java – 使用available()时没有获取整个数据
- 山东省电子政务云平台顶层设计进一步完善
- 50元学习MicroPython物联网开发,最便宜方案!
- 10分钟教你用Python玩转微信之抓取好友个性签名制作词云
热门文章
- python基于happybase对hbase增删改查-thrift1
- 37 Reasons why your Neural Network is not working
- 5.2 最优近似解 $\mathbf{\hat{x}} = A^{-1}_L\mathbf{b}$ 是最小二乘解
- 【机器学习基础知识】各类熵总结
- Linux shell利用sed如何批量更改文件名详解
- 设置eclipse启动时使用的jdk
- Jquery 禁用元素的所有属性
- Android性能调优利器StrictMode
- NYOJ10: skiing(DFS + DP)
- ASP.NET MVC SignalR(1):背景