From 4053336b49626d95e0f1917006038e3885c77be2 Mon Sep 17 00:00:00 2001 From: Elena Vilchik Date: Fri, 29 Jun 2018 12:09:51 +0200 Subject: Factorize external report import (#100) --- .../org/sonar/css/plugin/CssRulesDefinition.java | 8 +- .../java/org/sonar/css/plugin/SonarWayProfile.java | 2 +- .../sonar/css/plugin/StylelintReportSensor.java | 112 ++++----------------- .../org/sonar/l10n/css/rules/stylelint/rules.json | 42 +++++--- 4 files changed, 52 insertions(+), 112 deletions(-) (limited to 'sonar-css-plugin/src') diff --git a/sonar-css-plugin/src/main/java/org/sonar/css/plugin/CssRulesDefinition.java b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/CssRulesDefinition.java index 203dcb8..c03e261 100644 --- a/sonar-css-plugin/src/main/java/org/sonar/css/plugin/CssRulesDefinition.java +++ b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/CssRulesDefinition.java @@ -29,9 +29,9 @@ public class CssRulesDefinition implements RulesDefinition { public static final String REPOSITORY_KEY = "css"; public static final String RULE_REPOSITORY_NAME = "SonarAnalyzer"; - public static final String RESOURCE_FOLDER = "org/sonar/l10n/css/rules/css"; + public static final String RESOURCE_FOLDER = "org/sonar/l10n/css/rules/"; - private boolean externalIssuesSupported; + private final boolean externalIssuesSupported; public CssRulesDefinition(boolean externalIssuesSupported) { this.externalIssuesSupported = externalIssuesSupported; @@ -43,12 +43,12 @@ public class CssRulesDefinition implements RulesDefinition { .createRepository(REPOSITORY_KEY, CssLanguage.KEY) .setName(RULE_REPOSITORY_NAME); - RuleMetadataLoader ruleMetadataLoader = new RuleMetadataLoader(RESOURCE_FOLDER, PROFILE_PATH); + RuleMetadataLoader ruleMetadataLoader = new RuleMetadataLoader(RESOURCE_FOLDER + REPOSITORY_KEY, PROFILE_PATH); ruleMetadataLoader.addRulesByAnnotatedClass(repository, CssRules.getRuleClasses()); repository.done(); if (externalIssuesSupported) { - StylelintReportSensor.createExternalRuleRepository(context); + StylelintReportSensor.getStylelintRuleLoader().createExternalRuleRepository(context); } } } diff --git a/sonar-css-plugin/src/main/java/org/sonar/css/plugin/SonarWayProfile.java b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/SonarWayProfile.java index 01f6d83..4784189 100644 --- a/sonar-css-plugin/src/main/java/org/sonar/css/plugin/SonarWayProfile.java +++ b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/SonarWayProfile.java @@ -28,7 +28,7 @@ import static org.sonar.css.plugin.CssRulesDefinition.RESOURCE_FOLDER; public class SonarWayProfile implements BuiltInQualityProfilesDefinition { public static final String PROFILE_NAME = "Sonar way"; - public static final String PROFILE_PATH = RESOURCE_FOLDER + "/Sonar_way_profile.json"; + public static final String PROFILE_PATH = RESOURCE_FOLDER + CssRulesDefinition.REPOSITORY_KEY + "/Sonar_way_profile.json"; @Override public void define(Context context) { diff --git a/sonar-css-plugin/src/main/java/org/sonar/css/plugin/StylelintReportSensor.java b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/StylelintReportSensor.java index a2225b3..21e6aa2 100644 --- a/sonar-css-plugin/src/main/java/org/sonar/css/plugin/StylelintReportSensor.java +++ b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/StylelintReportSensor.java @@ -26,9 +26,7 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; +import java.util.List; import javax.annotation.Nullable; import org.sonar.api.batch.fs.FilePredicates; import org.sonar.api.batch.fs.InputFile; @@ -40,49 +38,30 @@ import org.sonar.api.batch.sensor.SensorDescriptor; import org.sonar.api.batch.sensor.issue.NewExternalIssue; import org.sonar.api.batch.sensor.issue.NewIssueLocation; import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.RuleType; -import org.sonar.api.server.rule.RulesDefinition.Context; -import org.sonar.api.server.rule.RulesDefinition.NewRepository; -import org.sonar.api.server.rule.RulesDefinition.NewRule; -import org.sonar.api.utils.Version; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.css.plugin.StylelintReport.Issue; import org.sonar.css.plugin.StylelintReport.IssuesPerFile; +import org.sonarsource.analyzer.commons.ExternalReportProvider; +import org.sonarsource.analyzer.commons.ExternalRuleLoader; + +import static org.sonar.css.plugin.CssRulesDefinition.RESOURCE_FOLDER; public class StylelintReportSensor implements Sensor { - private static final Logger LOG = Loggers.get(StylelintReportSensor.class); + public static final String STYLELINT = "stylelint"; - private static final String REPOSITORY = "stylelint"; + private static final Logger LOG = Loggers.get(StylelintReportSensor.class); private static final long DEFAULT_REMEDIATION_COST = 5L; private static final Severity DEFAULT_SEVERITY = Severity.MAJOR; private static final String FILE_EXCEPTION_MESSAGE = "No issues information will be saved as the report file can't be read."; - private static final Set BUG_RULES = new HashSet<>(Arrays.asList( - "selector-type-no-unknown", - "no-invalid-double-slash-comments", - "no-descending-specificity", - "at-rule-no-unknown", - "selector-type-no-unknown", - "selector-pseudo-element-no-unknown", - "selector-pseudo-class-no-unknown", - "declaration-block-no-shorthand-property-overrides", - "declaration-block-no-duplicate-properties", - "keyframe-declaration-no-important", - "property-no-unknown", - "unit-no-unknown", - "function-linear-gradient-no-nonstandard-direction", - "function-calc-no-unspaced-operator", - "font-family-no-missing-generic-family-keyword", - "color-no-invalid-hex" - )); - private final CssRules cssRules; + private ExternalRuleLoader stylelintRuleLoader = getStylelintRuleLoader(); public StylelintReportSensor(CheckFactory checkFactory) { - cssRules = new CssRules(checkFactory); + this.cssRules = new CssRules(checkFactory); } @Override @@ -94,22 +73,8 @@ public class StylelintReportSensor implements Sensor { @Override public void execute(SensorContext context) { - boolean externalIssuesSupported = context.getSonarQubeVersion().isGreaterThanOrEqual(Version.create(7, 2)); - String[] reportPaths = context.config().getStringArray(CssPlugin.STYLELINT_REPORT_PATHS); - - if (reportPaths.length == 0) { - return; - } - - if (!externalIssuesSupported) { - LOG.error("Import of external issues requires SonarQube 7.2 or greater."); - return; - } - - for (String reportPath : reportPaths) { - File report = getIOFile(context.fileSystem().baseDir(), reportPath); - importReport(report, context); - } + List reportFiles = ExternalReportProvider.getReportFiles(context, CssPlugin.STYLELINT_REPORT_PATHS); + reportFiles.forEach(report -> importReport(report, context)); } private void importReport(File report, SensorContext context) { @@ -162,58 +127,19 @@ public class StylelintReportSensor implements Sensor { newExternalIssue .at(primaryLocation) - .forRule(RuleKey.of(REPOSITORY, stylelintKey)) - .type(ruleType(stylelintKey)) + .forRule(RuleKey.of(STYLELINT, stylelintKey)) + .type(stylelintRuleLoader.ruleType(stylelintKey)) .severity(DEFAULT_SEVERITY) .remediationEffortMinutes(DEFAULT_REMEDIATION_COST) .save(); } - private static RuleType ruleType(String stylelintKey) { - return BUG_RULES.contains(stylelintKey) - ? RuleType.BUG - : RuleType.CODE_SMELL; + public static ExternalRuleLoader getStylelintRuleLoader() { + return new ExternalRuleLoader( + StylelintReportSensor.STYLELINT, + StylelintReportSensor.STYLELINT, + RESOURCE_FOLDER + StylelintReportSensor.STYLELINT + "/rules.json", + CssLanguage.KEY); } - /** - * Returns a java.io.File for the given path. - * If path is not absolute, returns a File with module base directory as parent path. - */ - private static File getIOFile(File baseDir, String path) { - File file = new File(path); - if (!file.isAbsolute()) { - file = new File(baseDir, path); - } - - return file; - } - - static void createExternalRuleRepository(Context context) { - NewRepository externalRepo = context.createExternalRepository(REPOSITORY, CssLanguage.KEY).setName(REPOSITORY); - String pathToRulesMeta = "org/sonar/l10n/css/rules/" + REPOSITORY + "/rules.json"; - String description = "See the description of %s rule %s at %s website."; - - try (InputStreamReader inputStreamReader = new InputStreamReader(StylelintReportSensor.class.getClassLoader().getResourceAsStream(pathToRulesMeta), StandardCharsets.UTF_8)) { - ExternalRule[] rules = new Gson().fromJson(inputStreamReader, ExternalRule[].class); - for (ExternalRule rule : rules) { - NewRule newRule = externalRepo.createRule(rule.key).setName(rule.name); - newRule.setHtmlDescription(String.format(description, REPOSITORY, rule.key, rule.url, REPOSITORY)); - newRule.setDebtRemediationFunction(newRule.debtRemediationFunctions().constantPerIssue(DEFAULT_REMEDIATION_COST + "min")); - if (BUG_RULES.contains(rule.key)) { - newRule.setType(RuleType.BUG); - } - } - - } catch (IOException e) { - throw new IllegalStateException("Can't read resource: " + pathToRulesMeta, e); - } - - externalRepo.done(); - } - - private static class ExternalRule { - String url; - String key; - String name; - } } diff --git a/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/stylelint/rules.json b/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/stylelint/rules.json index 4cd1ee0..b927de5 100644 --- a/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/stylelint/rules.json +++ b/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/stylelint/rules.json @@ -2,7 +2,8 @@ { "key": "color-no-invalid-hex", "url": "https://stylelint.io/user-guide/rules/color-no-invalid-hex/", - "name": "Disallow invalid hex colors" + "name": "Disallow invalid hex colors", + "type": "BUG" }, { "key": "font-family-no-duplicate-names", @@ -12,17 +13,20 @@ { "key": "font-family-no-missing-generic-family-keyword", "url": "https://stylelint.io/user-guide/rules/font-family-no-missing-generic-family-keyword/", - "name": "Disallow missing generic families in lists of font family names" + "name": "Disallow missing generic families in lists of font family names", + "type": "BUG" }, { "key": "function-calc-no-unspaced-operator", "url": "https://stylelint.io/user-guide/rules/function-calc-no-unspaced-operator/", - "name": "Disallow an unspaced operator within `calc` functions" + "name": "Disallow an unspaced operator within `calc` functions", + "type": "BUG" }, { "key": "function-linear-gradient-no-nonstandard-direction", "url": "https://stylelint.io/user-guide/rules/function-linear-gradient-no-nonstandard-direction/", - "name": "Disallow direction values in `linear-gradient()` calls that are not valid according to the [standard syntax](https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient#Syntax)" + "name": "Disallow direction values in `linear-gradient()` calls that are not valid according to the [standard syntax](https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient#Syntax)", + "type": "BUG" }, { "key": "string-no-newline", @@ -32,27 +36,32 @@ { "key": "unit-no-unknown", "url": "https://stylelint.io/user-guide/rules/unit-no-unknown/", - "name": "Disallow unknown units" + "name": "Disallow unknown units", + "type": "BUG" }, { "key": "property-no-unknown", "url": "https://stylelint.io/user-guide/rules/property-no-unknown/", - "name": "Disallow unknown properties" + "name": "Disallow unknown properties", + "type": "BUG" }, { "key": "keyframe-declaration-no-important", "url": "https://stylelint.io/user-guide/rules/keyframe-declaration-no-important/", - "name": "Disallow `!important` within keyframe declarations" + "name": "Disallow `!important` within keyframe declarations", + "type": "BUG" }, { "key": "declaration-block-no-duplicate-properties", "url": "https://stylelint.io/user-guide/rules/declaration-block-no-duplicate-properties/", - "name": "Disallow duplicate properties within declaration blocks" + "name": "Disallow duplicate properties within declaration blocks", + "type": "BUG" }, { "key": "declaration-block-no-shorthand-property-overrides", "url": "https://stylelint.io/user-guide/rules/declaration-block-no-shorthand-property-overrides/", - "name": "Disallow shorthand properties that override related longhand properties within declaration blocks" + "name": "Disallow shorthand properties that override related longhand properties within declaration blocks", + "type": "BUG" }, { "key": "block-no-empty", @@ -62,17 +71,20 @@ { "key": "selector-pseudo-class-no-unknown", "url": "https://stylelint.io/user-guide/rules/selector-pseudo-class-no-unknown/", - "name": "Disallow unknown pseudo-class selectors" + "name": "Disallow unknown pseudo-class selectors", + "type": "BUG" }, { "key": "selector-pseudo-element-no-unknown", "url": "https://stylelint.io/user-guide/rules/selector-pseudo-element-no-unknown/", - "name": "Disallow unknown pseudo-element selectors" + "name": "Disallow unknown pseudo-element selectors", + "type": "BUG" }, { "key": "selector-type-no-unknown", "url": "https://stylelint.io/user-guide/rules/selector-type-no-unknown/", - "name": "Disallow unknown type selectors" + "name": "Disallow unknown type selectors", + "type": "BUG" }, { "key": "media-feature-name-no-unknown", @@ -82,7 +94,8 @@ { "key": "at-rule-no-unknown", "url": "https://stylelint.io/user-guide/rules/at-rule-no-unknown/", - "name": "Disallow unknown at-rules" + "name": "Disallow unknown at-rules", + "type": "BUG" }, { "key": "comment-no-empty", @@ -117,7 +130,8 @@ { "key": "no-invalid-double-slash-comments", "url": "https://stylelint.io/user-guide/rules/no-invalid-double-slash-comments/", - "name": "Disallow double-slash comments (`//...`) which are not supported by CSS" + "name": "Disallow double-slash comments (`//...`) which are not supported by CSS", + "type": "BUG" }, { "key": "color-named", -- cgit v1.2.3