From a8659d1551c494f1110d728e95d019ac5e309072 Mon Sep 17 00:00:00 2001 From: jycr Date: Wed, 12 Apr 2023 01:01:11 +0200 Subject: [PATCH] green-code-initiative/ecoCode#92 refactor(rule/php): moves PHP rules into `ecocode-rule-specification` module --- .../src/main/assembly/php.xml | 22 ++++ .../ecocode/rules/php/PhpRulesRepository.java | 8 ++ .../src/main/rules/EC22/EC22.json | 15 +++ .../src/main/rules/EC22/php/EC22.asciidoc | 0 .../src/main/rules/EC34/EC34.json | 15 +++ .../src/main/rules/EC34/php/EC34.asciidoc | 0 .../src/main/rules/EC4/php/EC4.asciidoc | 0 .../src/main/rules/EC66/EC66.json | 15 +++ .../src/main/rules/EC66/php/EC66.asciidoc | 0 .../src/main/rules/EC67/php/EC67.asciidoc | 0 .../src/main/rules/EC69/php/EC69.asciidoc | 0 .../src/main/rules/EC72/php/EC72.asciidoc | 0 .../src/main/rules/EC74/php/EC74.asciidoc | 4 +- ecocode-rules-specifications/pom.xml | 19 +++ php-plugin/pom.xml | 66 +++++----- .../php/PhpRuleRepository.java | 118 +++++++----------- .../php/PhpRuleRepositoryTest.java | 6 +- 17 files changed, 179 insertions(+), 109 deletions(-) create mode 100644 ecocode-rule-specification/src/main/assembly/php.xml create mode 100644 ecocode-rule-specification/src/main/java/io/ecocode/rules/php/PhpRulesRepository.java create mode 100644 ecocode-rule-specification/src/main/rules/EC22/EC22.json rename php-plugin/src/main/resources/fr/greencodeinitiative/l10n/php/rules/custom/EC22.html => ecocode-rule-specification/src/main/rules/EC22/php/EC22.asciidoc (100%) create mode 100644 ecocode-rule-specification/src/main/rules/EC34/EC34.json rename php-plugin/src/main/resources/fr/greencodeinitiative/l10n/php/rules/custom/EC34.html => ecocode-rule-specification/src/main/rules/EC34/php/EC34.asciidoc (100%) rename php-plugin/src/main/resources/fr/greencodeinitiative/l10n/php/rules/custom/EC4.html => ecocode-rule-specification/src/main/rules/EC4/php/EC4.asciidoc (100%) create mode 100644 ecocode-rule-specification/src/main/rules/EC66/EC66.json rename php-plugin/src/main/resources/fr/greencodeinitiative/l10n/php/rules/custom/EC66.html => ecocode-rule-specification/src/main/rules/EC66/php/EC66.asciidoc (100%) rename php-plugin/src/main/resources/fr/greencodeinitiative/l10n/php/rules/custom/EC67.html => ecocode-rule-specification/src/main/rules/EC67/php/EC67.asciidoc (100%) rename php-plugin/src/main/resources/fr/greencodeinitiative/l10n/php/rules/custom/EC69.html => ecocode-rule-specification/src/main/rules/EC69/php/EC69.asciidoc (100%) rename php-plugin/src/main/resources/fr/greencodeinitiative/l10n/php/rules/custom/EC72.html => ecocode-rule-specification/src/main/rules/EC72/php/EC72.asciidoc (100%) rename php-plugin/src/main/resources/fr/greencodeinitiative/l10n/php/rules/custom/EC74.html => ecocode-rule-specification/src/main/rules/EC74/php/EC74.asciidoc (97%) diff --git a/ecocode-rule-specification/src/main/assembly/php.xml b/ecocode-rule-specification/src/main/assembly/php.xml new file mode 100644 index 000000000..512f82bba --- /dev/null +++ b/ecocode-rule-specification/src/main/assembly/php.xml @@ -0,0 +1,22 @@ + + php + + jar + + false + + + ${project.build.outputDirectory} + + io/ecocode/rules/php/*.class + + + + + ${project.build.directory}/php + io/ecocode/rules/php/specifications + + + diff --git a/ecocode-rule-specification/src/main/java/io/ecocode/rules/php/PhpRulesRepository.java b/ecocode-rule-specification/src/main/java/io/ecocode/rules/php/PhpRulesRepository.java new file mode 100644 index 000000000..10e56f85d --- /dev/null +++ b/ecocode-rule-specification/src/main/java/io/ecocode/rules/php/PhpRulesRepository.java @@ -0,0 +1,8 @@ +package io.ecocode.rules.php; + +public class PhpRulesRepository { + public static final String REPOSITORY_KEY = "ecocode-php"; + public static final String NAME = "ecoCode"; + public static final String LANGUAGE = "php"; + public static final String RESOURCE_BASE_PATH = PhpRulesRepository.class.getPackageName().replace('.', '/') + "/specifications"; +} diff --git a/ecocode-rule-specification/src/main/rules/EC22/EC22.json b/ecocode-rule-specification/src/main/rules/EC22/EC22.json new file mode 100644 index 000000000..9d3ed8c36 --- /dev/null +++ b/ecocode-rule-specification/src/main/rules/EC22/EC22.json @@ -0,0 +1,15 @@ +{ + "title": "Use of methods for basic operations", + "type": "CODE_SMELL", + "status": "ready", + "remediation": { + "func": "Constant\/Issue", + "constantCost": "5min" + }, + "tags": [ + "eco-design", + "performance", + "ecocode" + ], + "defaultSeverity": "Minor" +} diff --git a/php-plugin/src/main/resources/fr/greencodeinitiative/l10n/php/rules/custom/EC22.html b/ecocode-rule-specification/src/main/rules/EC22/php/EC22.asciidoc similarity index 100% rename from php-plugin/src/main/resources/fr/greencodeinitiative/l10n/php/rules/custom/EC22.html rename to ecocode-rule-specification/src/main/rules/EC22/php/EC22.asciidoc diff --git a/ecocode-rule-specification/src/main/rules/EC34/EC34.json b/ecocode-rule-specification/src/main/rules/EC34/EC34.json new file mode 100644 index 000000000..4191cbb71 --- /dev/null +++ b/ecocode-rule-specification/src/main/rules/EC34/EC34.json @@ -0,0 +1,15 @@ +{ + "title": "Avoid using try-catch-finally statement", + "type": "CODE_SMELL", + "status": "ready", + "remediation": { + "func": "Constant\/Issue", + "constantCost": "5min" + }, + "tags": [ + "eco-design", + "performance", + "ecocode" + ], + "defaultSeverity": "Minor" +} diff --git a/php-plugin/src/main/resources/fr/greencodeinitiative/l10n/php/rules/custom/EC34.html b/ecocode-rule-specification/src/main/rules/EC34/php/EC34.asciidoc similarity index 100% rename from php-plugin/src/main/resources/fr/greencodeinitiative/l10n/php/rules/custom/EC34.html rename to ecocode-rule-specification/src/main/rules/EC34/php/EC34.asciidoc diff --git a/php-plugin/src/main/resources/fr/greencodeinitiative/l10n/php/rules/custom/EC4.html b/ecocode-rule-specification/src/main/rules/EC4/php/EC4.asciidoc similarity index 100% rename from php-plugin/src/main/resources/fr/greencodeinitiative/l10n/php/rules/custom/EC4.html rename to ecocode-rule-specification/src/main/rules/EC4/php/EC4.asciidoc diff --git a/ecocode-rule-specification/src/main/rules/EC66/EC66.json b/ecocode-rule-specification/src/main/rules/EC66/EC66.json new file mode 100644 index 000000000..6ed6137dc --- /dev/null +++ b/ecocode-rule-specification/src/main/rules/EC66/EC66.json @@ -0,0 +1,15 @@ +{ + "title": "Avoid using double quote (\"), prefer using simple quote (')", + "type": "CODE_SMELL", + "status": "ready", + "remediation": { + "func": "Constant\/Issue", + "constantCost": "5min" + }, + "tags": [ + "eco-design", + "performance", + "ecocode" + ], + "defaultSeverity": "Minor" +} diff --git a/php-plugin/src/main/resources/fr/greencodeinitiative/l10n/php/rules/custom/EC66.html b/ecocode-rule-specification/src/main/rules/EC66/php/EC66.asciidoc similarity index 100% rename from php-plugin/src/main/resources/fr/greencodeinitiative/l10n/php/rules/custom/EC66.html rename to ecocode-rule-specification/src/main/rules/EC66/php/EC66.asciidoc diff --git a/php-plugin/src/main/resources/fr/greencodeinitiative/l10n/php/rules/custom/EC67.html b/ecocode-rule-specification/src/main/rules/EC67/php/EC67.asciidoc similarity index 100% rename from php-plugin/src/main/resources/fr/greencodeinitiative/l10n/php/rules/custom/EC67.html rename to ecocode-rule-specification/src/main/rules/EC67/php/EC67.asciidoc diff --git a/php-plugin/src/main/resources/fr/greencodeinitiative/l10n/php/rules/custom/EC69.html b/ecocode-rule-specification/src/main/rules/EC69/php/EC69.asciidoc similarity index 100% rename from php-plugin/src/main/resources/fr/greencodeinitiative/l10n/php/rules/custom/EC69.html rename to ecocode-rule-specification/src/main/rules/EC69/php/EC69.asciidoc diff --git a/php-plugin/src/main/resources/fr/greencodeinitiative/l10n/php/rules/custom/EC72.html b/ecocode-rule-specification/src/main/rules/EC72/php/EC72.asciidoc similarity index 100% rename from php-plugin/src/main/resources/fr/greencodeinitiative/l10n/php/rules/custom/EC72.html rename to ecocode-rule-specification/src/main/rules/EC72/php/EC72.asciidoc diff --git a/php-plugin/src/main/resources/fr/greencodeinitiative/l10n/php/rules/custom/EC74.html b/ecocode-rule-specification/src/main/rules/EC74/php/EC74.asciidoc similarity index 97% rename from php-plugin/src/main/resources/fr/greencodeinitiative/l10n/php/rules/custom/EC74.html rename to ecocode-rule-specification/src/main/rules/EC74/php/EC74.asciidoc index 3b1edba30..a961f1d6d 100644 --- a/php-plugin/src/main/resources/fr/greencodeinitiative/l10n/php/rules/custom/EC74.html +++ b/ecocode-rule-specification/src/main/rules/EC74/php/EC74.asciidoc @@ -12,7 +12,7 @@

Compliant Solution

     public function foo() {
         ...
-        $baseQuery = "SELECT id,name, adress FROM users ";
+        $baseQuery = "SELECT id,name, address FROM users ";
         ...
    }
 
@@ -98,4 +98,4 @@

Total:

- \ No newline at end of file + diff --git a/ecocode-rules-specifications/pom.xml b/ecocode-rules-specifications/pom.xml index f8f8fdd09..3d3d93d25 100644 --- a/ecocode-rules-specifications/pom.xml +++ b/ecocode-rules-specifications/pom.xml @@ -74,6 +74,13 @@ + + + + + + + @@ -99,6 +106,18 @@ + + assembly-php + prepare-package + + single + + + + ${project.basedir}/src/main/assembly/php.xml + + + true diff --git a/php-plugin/pom.xml b/php-plugin/pom.xml index a79f181ef..31bfd7790 100644 --- a/php-plugin/pom.xml +++ b/php-plugin/pom.xml @@ -16,21 +16,30 @@ https://github.com/green-code-initiative/ecoCode/tree/main/php-plugin + + ${project.groupId} + ecocode-rules-specifications + ${project.version} + php + org.sonarsource.php sonar-php-plugin sonar-plugin + provided org.sonarsource.sonarqube sonar-plugin-api + provided org.sonarsource.sonarqube sonar-plugin-api-impl + test @@ -73,41 +82,28 @@ ${java.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + org.apache.maven.plugins + maven-shade-plugin + + + package + + shade + + + + + *:ecocode-rules-specifications + + META-INF/** + + + + + + + org.apache.maven.plugins maven-dependency-plugin diff --git a/php-plugin/src/main/java/fr/greencodeinitiative/php/PhpRuleRepository.java b/php-plugin/src/main/java/fr/greencodeinitiative/php/PhpRuleRepository.java index a8cd4fd70..7eb3c6f03 100644 --- a/php-plugin/src/main/java/fr/greencodeinitiative/php/PhpRuleRepository.java +++ b/php-plugin/src/main/java/fr/greencodeinitiative/php/PhpRuleRepository.java @@ -1,5 +1,5 @@ /* - * SonarQube Python Plugin + * SonarQube PHP Plugin * Copyright (C) 2012-2019 SonarSource SA * mailto:info AT sonarsource DOT com * @@ -19,17 +19,6 @@ */ package fr.greencodeinitiative.php; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.google.common.collect.ImmutableList; import fr.greencodeinitiative.php.checks.AvoidDoubleQuoteCheck; import fr.greencodeinitiative.php.checks.AvoidFullSQLRequestCheck; import fr.greencodeinitiative.php.checks.AvoidSQLRequestInLoopCheck; @@ -38,46 +27,61 @@ import fr.greencodeinitiative.php.checks.IncrementCheck; import fr.greencodeinitiative.php.checks.NoFunctionCallWhenDeclaringForLoop; import fr.greencodeinitiative.php.checks.UseOfMethodsForBasicOperations; +import org.sonar.api.SonarEdition; +import org.sonar.api.SonarProduct; +import org.sonar.api.SonarQubeSide; +import org.sonar.api.SonarRuntime; import org.sonar.api.server.rule.RulesDefinition; -import org.sonar.api.server.rule.RulesDefinitionAnnotationLoader; +import org.sonar.api.utils.Version; import org.sonar.plugins.php.api.visitors.PHPCustomRuleRepository; +import org.sonarsource.analyzer.commons.RuleMetadataLoader; -public class PhpRuleRepository implements RulesDefinition, PHPCustomRuleRepository { +import java.util.List; - public static final String LANGUAGE = "php"; - public static final String NAME = "ecoCode"; - public static final String RESOURCE_BASE_PATH = "/fr/greencodeinitiative/l10n/php/rules/custom/"; - public static final String REPOSITORY_KEY = "ecocode-php"; +import static io.ecocode.rules.php.PhpRulesRepository.LANGUAGE; +import static io.ecocode.rules.php.PhpRulesRepository.NAME; +import static io.ecocode.rules.php.PhpRulesRepository.REPOSITORY_KEY; +import static io.ecocode.rules.php.PhpRulesRepository.RESOURCE_BASE_PATH; - @Override - public void define(Context context) { - NewRepository repository = context.createRepository(repositoryKey(), LANGUAGE).setName(NAME); - - new RulesDefinitionAnnotationLoader().load(repository, checkClasses().toArray(new Class[] {})); +public class PhpRuleRepository implements RulesDefinition, PHPCustomRuleRepository { + private static final List> ANNOTATED_RULE_CLASSES = List.of( + AvoidDoubleQuoteCheck.class, + AvoidFullSQLRequestCheck.class, + AvoidSQLRequestInLoopCheck.class, + AvoidTryCatchFinallyCheck_NOK_failsAllTryStatements.class, + AvoidUsingGlobalVariablesCheck.class, + IncrementCheck.class, + NoFunctionCallWhenDeclaringForLoop.class, + UseOfMethodsForBasicOperations.class + ); + private static final Version SONARQUBE_RUNTIME_VERSION = Version.create(9, 8); + private static final SonarRuntime SONARQUBE_RUNTIME = new SonarRuntime() { + @Override + public Version getApiVersion() { + return SONARQUBE_RUNTIME_VERSION; + } - // technical debt - Map remediationCosts = new HashMap<>(); - remediationCosts.put(AvoidSQLRequestInLoopCheck.RULE_KEY, "10min"); - remediationCosts.put(AvoidFullSQLRequestCheck.RULE_KEY, "20min"); - repository.rules().forEach(rule -> { - String debt = remediationCosts.get(rule.key()); + @Override + public SonarProduct getProduct() { + return SonarProduct.SONARQUBE; + } - // TODO DDC : create support to use org.apache.commons.lang.StringUtils -// if (StringUtils.isBlank(debt)) { - if (debt == null || debt.trim().equals("")) { - // default debt to 5min for issue correction - rule.setDebtRemediationFunction( - rule.debtRemediationFunctions().constantPerIssue("5min")); - } else { - rule.setDebtRemediationFunction( - rule.debtRemediationFunctions().constantPerIssue(debt)); - } - }); + @Override + public SonarQubeSide getSonarQubeSide() { + return SonarQubeSide.SCANNER; + } - // HTML description - repository.rules().forEach(rule -> - rule.setHtmlDescription(loadResource(RESOURCE_BASE_PATH + rule.key() + ".html"))); + @Override + public SonarEdition getEdition() { + return SonarEdition.COMMUNITY; + } + }; + @Override + public void define(Context context) { + NewRepository repository = context.createRepository(REPOSITORY_KEY, LANGUAGE).setName(NAME); + RuleMetadataLoader ruleMetadataLoader = new RuleMetadataLoader(RESOURCE_BASE_PATH, SONARQUBE_RUNTIME); + ruleMetadataLoader.addRulesByAnnotatedClass(repository, ANNOTATED_RULE_CLASSES); repository.done(); } @@ -88,32 +92,6 @@ public String repositoryKey() { @Override public List> checkClasses() { - return ImmutableList.of( - AvoidDoubleQuoteCheck.class, - AvoidFullSQLRequestCheck.class, - AvoidSQLRequestInLoopCheck.class, - AvoidTryCatchFinallyCheck_NOK_failsAllTryStatements.class, - AvoidUsingGlobalVariablesCheck.class, - IncrementCheck.class, - NoFunctionCallWhenDeclaringForLoop.class, - UseOfMethodsForBasicOperations.class - ); - } - - private String loadResource(String path) { - URL resource = getClass().getResource(path); - if (resource == null) { - throw new IllegalStateException("Resource not found: " + path); - } - ByteArrayOutputStream result = new ByteArrayOutputStream(); - try (InputStream in = resource.openStream()) { - byte[] buffer = new byte[1024]; - for (int len = in.read(buffer); len != -1; len = in.read(buffer)) { - result.write(buffer, 0, len); - } - return new String(result.toByteArray(), StandardCharsets.UTF_8); - } catch (IOException e) { - throw new IllegalStateException("Failed to read resource: " + path, e); - } + return ANNOTATED_RULE_CLASSES; } } diff --git a/php-plugin/src/test/java/fr/greencodeinitiative/php/PhpRuleRepositoryTest.java b/php-plugin/src/test/java/fr/greencodeinitiative/php/PhpRuleRepositoryTest.java index f2345716d..58e8e12e7 100644 --- a/php-plugin/src/test/java/fr/greencodeinitiative/php/PhpRuleRepositoryTest.java +++ b/php-plugin/src/test/java/fr/greencodeinitiative/php/PhpRuleRepositoryTest.java @@ -20,6 +20,8 @@ package fr.greencodeinitiative.php; import static org.assertj.core.api.Assertions.assertThat; + +import io.ecocode.rules.php.PhpRulesRepository; import org.assertj.core.api.SoftAssertions; import org.junit.Before; import org.junit.Test; @@ -39,7 +41,7 @@ public void init() { @Test public void test() { - assertThat(phpRuleRepository.repositoryKey()).isEqualTo(PhpRuleRepository.REPOSITORY_KEY); + assertThat(phpRuleRepository.repositoryKey()).isEqualTo(PhpRulesRepository.REPOSITORY_KEY); assertThat(context.repositories()).hasSize(1).extracting("key").containsExactly(phpRuleRepository.repositoryKey()); assertThat(context.repositories().get(0).rules()).hasSize(8); assertThat(phpRuleRepository.checkClasses()).hasSize(8); @@ -50,7 +52,7 @@ public void test() { */ @Test() public void testRuleKeyPrefix() { - RulesDefinition.Repository repository = context.repository(PhpRuleRepository.REPOSITORY_KEY); + RulesDefinition.Repository repository = context.repository(PhpRulesRepository.REPOSITORY_KEY); SoftAssertions assertions = new SoftAssertions(); repository.rules().forEach( rule -> assertions.assertThat(rule.key()).startsWith("EC")