Skip to content

Commit

Permalink
checkstyle#191 - add SQ 7.6 compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Muehlbachler authored and romani committed Feb 12, 2019
1 parent 3612321 commit 3bcbe9d
Show file tree
Hide file tree
Showing 13 changed files with 420 additions and 46 deletions.
6 changes: 3 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ version: 2
jobs:
build:
docker:
- image: checkstyle/sonarqube-maven-git:7.4-community
- image: checkstyle/sonarqube-maven-git:7.6-community-3612321

working_directory: ~/repo

Expand Down Expand Up @@ -41,8 +41,8 @@ jobs:
rm -f logs/*.*
echo "run sonarqube web service"
./bin/run.sh &
echo "sleeping 40 to let sonar start up ..."
sleep 40
echo "sleeping 60 to let sonar start up ..."
sleep 60
echo "check that sonar service is up ..."
grep "SonarQube is up" logs/sonar.log
echo "switching back to repository code"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
import org.sonar.api.batch.fs.FilePredicates;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.batch.rule.ActiveRules;

import com.google.common.annotations.VisibleForTesting;
import com.puppycrawl.tools.checkstyle.ConfigurationLoader;
Expand All @@ -54,18 +54,18 @@ public class CheckstyleConfiguration {
private static final Logger LOG = LoggerFactory.getLogger(CheckstyleConfiguration.class);

private final CheckstyleProfileExporter confExporter;
private final RulesProfile profile;
private final ActiveRules activeRules;
private final org.sonar.api.config.Configuration conf;
private final FileSystem fileSystem;

public CheckstyleConfiguration(
org.sonar.api.config.Configuration conf,
CheckstyleProfileExporter confExporter,
RulesProfile profile,
ActiveRules activeRules,
FileSystem fileSystem) {
this.conf = conf;
this.confExporter = confExporter;
this.profile = profile;
this.activeRules = activeRules;
this.fileSystem = fileSystem;
}

Expand All @@ -74,7 +74,7 @@ public File getXmlDefinitionFile() {
try (Writer writer = new OutputStreamWriter(new FileOutputStream(xmlFile, false),
StandardCharsets.UTF_8)) {

confExporter.exportProfile(profile, writer);
confExporter.exportProfile(activeRules, writer);
writer.flush();
return xmlFile;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
Expand All @@ -31,11 +32,14 @@
import org.apache.commons.lang.StringUtils;
import org.sonar.api.ExtensionPoint;
import org.sonar.api.batch.ScannerSide;
import org.sonar.api.batch.rule.ActiveRules;
import org.sonar.api.config.Configuration;
import org.sonar.api.profiles.ProfileExporter;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.rules.ActiveRule;
import org.sonar.api.rules.RuleParam;
import org.sonar.plugins.checkstyle.rule.ActiveRuleWrapper;
import org.sonar.plugins.checkstyle.rule.ActiveRuleWrapperScannerImpl;
import org.sonar.plugins.checkstyle.rule.ActiveRuleWrapperServerImpl;

import com.google.common.annotations.VisibleForTesting;

Expand Down Expand Up @@ -63,19 +67,39 @@ public void exportProfile(RulesProfile profile, Writer writer) {
final List<ActiveRule> activeRules = profile
.getActiveRulesByRepository(CheckstyleConstants.REPOSITORY_KEY);
if (activeRules != null) {
final Map<String, List<ActiveRule>> activeRulesByConfigKey =
arrangeByConfigKey(activeRules);
final List<ActiveRuleWrapper> activeRuleWrappers = new ArrayList<>();
for (ActiveRule activeRule : activeRules) {
activeRuleWrappers.add(new ActiveRuleWrapperServerImpl(activeRule));
}
final Map<String, List<ActiveRuleWrapper>> activeRulesByConfigKey =
arrangeByConfigKey(activeRuleWrappers);
generateXml(writer, activeRulesByConfigKey);
}
}
catch (IOException ex) {
throw new IllegalStateException("Fail to export the profile " + profile, ex);
}
}

public void exportProfile(ActiveRules activeRules, Writer writer) {
try {
final List<ActiveRuleWrapper> activeRuleWrappers = new ArrayList<>();
for (org.sonar.api.batch.rule.ActiveRule activeRule : activeRules
.findByRepository(CheckstyleConstants.REPOSITORY_KEY)) {
activeRuleWrappers.add(new ActiveRuleWrapperScannerImpl(activeRule));
}
final Map<String, List<ActiveRuleWrapper>> activeRulesByConfigKey =
arrangeByConfigKey(activeRuleWrappers);
generateXml(writer, activeRulesByConfigKey);
}
catch (IOException ex) {
throw new IllegalStateException("Fail to export active rules.", ex);
}

}

private void generateXml(Writer writer, Map<String, List<ActiveRule>> activeRulesByConfigKey)
throws IOException {
private void generateXml(Writer writer, Map<String,
List<ActiveRuleWrapper>> activeRulesByConfigKey) throws IOException {
appendXmlHeader(writer);
appendCustomFilters(writer);
appendCheckerModules(writer, activeRulesByConfigKey);
Expand All @@ -95,20 +119,20 @@ private void appendCustomFilters(Writer writer) throws IOException {
}

private static void appendCheckerModules(Writer writer,
Map<String, List<ActiveRule>> activeRulesByConfigKey) throws IOException {
for (Map.Entry<String, List<ActiveRule>> entry : activeRulesByConfigKey.entrySet()) {
Map<String, List<ActiveRuleWrapper>> activeRulesByConfigKey) throws IOException {
for (Map.Entry<String, List<ActiveRuleWrapper>> entry : activeRulesByConfigKey.entrySet()) {
final String configKey = entry.getKey();
if (!isInTreeWalker(configKey)) {
final List<ActiveRule> activeRules = entry.getValue();
for (ActiveRule activeRule : activeRules) {
final List<ActiveRuleWrapper> activeRules = entry.getValue();
for (ActiveRuleWrapper activeRule : activeRules) {
appendModule(writer, activeRule);
}
}
}
}

private void appendTreeWalker(Writer writer,
Map<String, List<ActiveRule>> activeRulesByConfigKey) throws IOException {
Map<String, List<ActiveRuleWrapper>> activeRulesByConfigKey) throws IOException {
writer.append("<module name=\"TreeWalker\">");
if (isSuppressWarningsEnabled()) {
writer.append("<module name=\"SuppressWarningsHolder\"/> ");
Expand All @@ -117,8 +141,8 @@ private void appendTreeWalker(Writer writer,
Collections.sort(ruleSet);
for (String configKey : ruleSet) {
if (isInTreeWalker(configKey)) {
final List<ActiveRule> activeRules = activeRulesByConfigKey.get(configKey);
for (ActiveRule activeRule : activeRules) {
final List<ActiveRuleWrapper> activeRules = activeRulesByConfigKey.get(configKey);
for (ActiveRuleWrapper activeRule : activeRules) {
appendModule(writer, activeRule);
}
}
Expand Down Expand Up @@ -151,43 +175,43 @@ static boolean isInTreeWalker(String configKey) {
return StringUtils.startsWithIgnoreCase(configKey, "Checker/TreeWalker/");
}

private static Map<String, List<ActiveRule>> arrangeByConfigKey(List<ActiveRule> activeRules) {
final Map<String, List<ActiveRule>> result = new HashMap<>();
for (ActiveRule activeRule : activeRules) {
final String key = activeRule.getConfigKey();
private static Map<String, List<ActiveRuleWrapper>> arrangeByConfigKey(
Collection<ActiveRuleWrapper> activeRules) {
final Map<String, List<ActiveRuleWrapper>> result = new HashMap<>();
for (ActiveRuleWrapper activeRule : activeRules) {
final String key = activeRule.getInternalKey();
if (result.containsKey(key)) {
final List<ActiveRule> rules = result.get(key);
final List<ActiveRuleWrapper> rules = result.get(key);
rules.add(activeRule);
}
else {
final List<ActiveRule> rules = new ArrayList<>();
final List<ActiveRuleWrapper> rules = new ArrayList<>();
rules.add(activeRule);
result.put(key, rules);
}
}
return result;
}

private static void appendModule(Writer writer, ActiveRule activeRule) throws IOException {
final String moduleName = StringUtils.substringAfterLast(activeRule.getConfigKey(), "/");
private static void appendModule(Writer writer, ActiveRuleWrapper activeRule)
throws IOException {
final String moduleName = StringUtils.substringAfterLast(activeRule.getInternalKey(), "/");
writer.append("<module name=\"");
StringEscapeUtils.escapeXml(writer, moduleName);
writer.append("\">");
if (activeRule.getRule().getTemplate() != null) {
if (activeRule.getTemplateRuleKey() != null) {
appendModuleProperty(writer, "id", activeRule.getRuleKey());
}
appendModuleProperty(writer, "severity",
CheckstyleSeverityUtils.toSeverity(activeRule.getSeverity()));
appendModuleProperty(writer, "severity", activeRule.getSeverity());
appendRuleParameters(writer, activeRule);
writer.append(CLOSE_MODULE);
}

private static void appendRuleParameters(Writer writer, ActiveRule activeRule)
private static void appendRuleParameters(Writer writer, ActiveRuleWrapper activeRule)
throws IOException {
for (RuleParam ruleParam : activeRule.getRule().getParams()) {
final String value = activeRule.getParameter(ruleParam.getKey());
if (StringUtils.isNotBlank(value)) {
appendModuleProperty(writer, ruleParam.getKey(), value);
for (Map.Entry<String, String> param : activeRule.getParams().entrySet()) {
if (StringUtils.isNotBlank(param.getValue())) {
appendModuleProperty(writer, param.getKey(), param.getValue());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,22 @@ private CheckstyleSeverityUtils() {
}

public static String toSeverity(RulePriority priority) {
return toSeverity(priority.name());
}

public static String toSeverity(String priority) {
final String result;

switch (priority) {
case BLOCKER:
case CRITICAL:
case "BLOCKER":
case "CRITICAL":
result = SeverityLevel.ERROR.getName();
break;
case MAJOR:
case "MAJOR":
result = SeverityLevel.WARNING.getName();
break;
case MINOR:
case INFO:
case "MINOR":
case "INFO":
result = SeverityLevel.INFO.getName();
break;
default:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2017 the original author or authors.
//
// This library 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 library 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 library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
////////////////////////////////////////////////////////////////////////////////

package org.sonar.plugins.checkstyle.rule;

import java.util.Map;

/**
* Due to our usage of {@link org.sonar.plugins.checkstyle.CheckstyleProfileExporter}
* on the {@link org.sonar.api.batch.ScannerSide} for generating CheckStyle configurations,
* we must make it compatible for the new {@link org.sonar.api.batch.rule.ActiveRules}.
*
* Hence, to gain compatibility with server and scanner side in the exporter,
* we have to wrap either {@link org.sonar.api.batch.rule.ActiveRule} or
* {@link org.sonar.api.rules.ActiveRule} for usage in the exporter.
*/
public interface ActiveRuleWrapper {
String getInternalKey();

String getRuleKey();

String getTemplateRuleKey();

String getSeverity();

Map<String, String> getParams();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2017 the original author or authors.
//
// This library 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 library 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 library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
////////////////////////////////////////////////////////////////////////////////

package org.sonar.plugins.checkstyle.rule;

import java.util.Map;

import org.sonar.api.batch.rule.ActiveRule;
import org.sonar.plugins.checkstyle.CheckstyleSeverityUtils;

/**
* Wrapper as per {@link ActiveRuleWrapper} for the new scanner side {@link ActiveRule}.
*/
public class ActiveRuleWrapperScannerImpl implements ActiveRuleWrapper {
private final ActiveRule activeRule;

public ActiveRuleWrapperScannerImpl(ActiveRule activeRule) {
this.activeRule = activeRule;
}

@Override
public String getInternalKey() {
return activeRule.internalKey();
}

@Override
public String getRuleKey() {
return activeRule.ruleKey().rule();
}

@Override
public String getTemplateRuleKey() {
return activeRule.templateRuleKey();
}

@Override
public String getSeverity() {
return CheckstyleSeverityUtils.toSeverity(activeRule.severity());
}

@Override
public Map<String, String> getParams() {
return activeRule.params();
}
}

0 comments on commit 3bcbe9d

Please sign in to comment.