Skip to content

Commit

Permalink
green-code-initiative#92 refactor(rule/php): moves PHP rules into `ec…
Browse files Browse the repository at this point in the history
…ocode-rules-specifications` module
  • Loading branch information
jycr committed Apr 14, 2023
1 parent 22bbe67 commit a12c61f
Show file tree
Hide file tree
Showing 17 changed files with 167 additions and 99 deletions.
19 changes: 19 additions & 0 deletions ecocode-rules-specifications/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@
</fileset>
<flattenmapper/>
</copy>
<copy todir="${project.build.directory}/php">
<fileset dir="${project.build.directory}/rules">
<include name="*/php/EC*.html"/>
<include name="*/EC*.json"/>
</fileset>
<flattenmapper/>
</copy>
</target>
</configuration>
<goals>
Expand All @@ -99,6 +106,18 @@
</descriptors>
</configuration>
</execution>
<execution>
<id>assembly-php</id>
<phase>prepare-package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>${project.basedir}/src/main/assembly/php.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
<configuration>
<appendAssemblyId>true</appendAssemblyId>
Expand Down
22 changes: 22 additions & 0 deletions ecocode-rules-specifications/src/main/assembly/php.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.1 https://maven.apache.org/xsd/assembly-2.1.1.xsd">
<id>php</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.build.outputDirectory}</directory>
<includes>
<include>io/ecocode/rules/php/*.class</include>
</includes>
<outputDirectory/>
</fileSet>
<fileSet>
<directory>${project.build.directory}/php</directory>
<outputDirectory>io/ecocode/rules/php/specifications</outputDirectory>
</fileSet>
</fileSets>
</assembly>
Original file line number Diff line number Diff line change
@@ -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";
}
15 changes: 15 additions & 0 deletions ecocode-rules-specifications/src/main/rules/EC22/EC22.json
Original file line number Diff line number Diff line change
@@ -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"
}
15 changes: 15 additions & 0 deletions ecocode-rules-specifications/src/main/rules/EC34/EC34.json
Original file line number Diff line number Diff line change
@@ -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"
}
15 changes: 15 additions & 0 deletions ecocode-rules-specifications/src/main/rules/EC66/EC66.json
Original file line number Diff line number Diff line change
@@ -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"
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ <h2>Compliant Solution</h2>
<pre>
public function foo() {
...
$baseQuery = "SELECT id,name, adress FROM users ";
$baseQuery = "SELECT id,name, address FROM users ";
...
}
</pre>
Expand Down Expand Up @@ -98,4 +98,4 @@ <h2>Total:</h2>
</td>
</tr>
</tbody>
</table>
</table>
66 changes: 31 additions & 35 deletions php-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,30 @@
<url>https://github.com/green-code-initiative/ecoCode/tree/main/php-plugin</url>

<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>ecocode-rules-specifications</artifactId>
<version>${project.version}</version>
<classifier>php</classifier>
</dependency>

<dependency>
<groupId>org.sonarsource.php</groupId>
<artifactId>sonar-php-plugin</artifactId>
<type>sonar-plugin</type>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.sonarsource.sonarqube</groupId>
<artifactId>sonar-plugin-api</artifactId>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.sonarsource.sonarqube</groupId>
<artifactId>sonar-plugin-api-impl</artifactId>
<scope>test</scope>
</dependency>

<!-- for security on regex patterns : https://github.com/google/re2j -->
Expand Down Expand Up @@ -66,41 +75,28 @@
<jreMinVersion>${java.version}</jreMinVersion>
</configuration>
</plugin>
<!-- <plugin>-->
<!-- <groupId>org.apache.maven.plugins</groupId>-->
<!-- <artifactId>maven-shade-plugin</artifactId>-->
<!-- <executions>-->
<!-- <execution>-->
<!-- <phase>package</phase>-->
<!-- <goals>-->
<!-- <goal>shade</goal>-->
<!-- </goals>-->
<!-- <configuration>-->
<!-- <filters>-->
<!-- <filter>-->
<!-- <artifact>commons-*:*</artifact>-->
<!-- <excludes>-->
<!-- <exclude>META-INF/**</exclude>-->
<!-- </excludes>-->
<!-- </filter>-->
<!-- <filter>-->
<!-- <artifact>org.*:*</artifact>-->
<!-- <excludes>-->
<!-- <exclude>META-INF/**</exclude>-->
<!-- <exclude>org/sonar/api/batch/sensor/**</exclude>-->
<!-- </excludes>-->
<!-- </filter>-->
<!-- <filter>-->
<!-- <artifact>com.*:*</artifact>-->
<!-- <excludes>-->
<!-- <exclude>META-INF/**</exclude>-->
<!-- </excludes>-->
<!-- </filter>-->
<!-- </filters>-->
<!-- </configuration>-->
<!-- </execution>-->
<!-- </executions>-->
<!-- </plugin>-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:ecocode-rules-specifications</artifact>
<excludes>
<exclude>META-INF/**</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SonarQube Python Plugin
* SonarQube PHP Plugin
* Copyright (C) 2012-2019 SonarSource SA
* mailto:info AT sonarsource DOT com
*
Expand All @@ -19,15 +19,7 @@
*/
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;
Expand All @@ -38,48 +30,49 @@
import fr.greencodeinitiative.php.checks.IncrementCheck;
import fr.greencodeinitiative.php.checks.NoFunctionCallWhenDeclaringForLoop;
import fr.greencodeinitiative.php.checks.UseOfMethodsForBasicOperations;
import org.sonar.api.rules.RuleType;
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 {

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";

@Override
public void define(Context context) {
NewRepository repository = context.createRepository(repositoryKey(), LANGUAGE).setName(NAME);
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;

new RulesDefinitionAnnotationLoader().load(repository, checkClasses().toArray(new Class[] {}));
public class PhpRuleRepository implements RulesDefinition, PHPCustomRuleRepository {
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<String, String> remediationCosts = new HashMap<>();
remediationCosts.put(AvoidSQLRequestInLoopCheck.RULE_KEY, "10min");
remediationCosts.put(AvoidFullSQLRequestCheck.RULE_KEY, "20min");
repository.rules().forEach(rule -> {
rule.setType(RuleType.CODE_SMELL);
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, checkClasses());
repository.done();
}

Expand All @@ -101,21 +94,4 @@ public List<Class<?>> checkClasses() {
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);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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")
Expand Down

0 comments on commit a12c61f

Please sign in to comment.