Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 1 addition & 2 deletions its/plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</parent>

<artifactId>it-python-plugin</artifactId>

<packaging>pom</packaging>
<name>Python :: ITs :: Plugin</name>
<inceptionYear>2012</inceptionYear>
<organization>
Expand All @@ -20,7 +20,6 @@
<properties>
<surefire.argLine>-server</surefire.argLine>
</properties>

<dependencies>
<dependency>
<groupId>org.sonarsource.orchestrator</groupId>
Expand Down
17 changes: 17 additions & 0 deletions its/plugin/profiles/profile-python-custom-rules.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<profile>
<name>python-custom-rules-profile</name>
<language>py</language>
<rules>
<rule>
<repositoryKey>python-custom-rules</repositoryKey>
<key>visitor</key>
<priority>MAJOR</priority>
</rule>
<rule>
<repositoryKey>python-custom-rules</repositoryKey>
<key>subscription</key>
<priority>MAJOR</priority>
</rule>
</rules>
</profile>
10 changes: 10 additions & 0 deletions its/plugin/projects/custom_rules/src/simple.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# simple check for custom rules

class A:
def fun(): # NOK - function definition
pass

for foo in bar: # NOK - for statement
pass
else:
pass
71 changes: 71 additions & 0 deletions its/plugin/python-custom-rules-plugin/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.sonarsource.python</groupId>
<artifactId>it-python-plugin</artifactId>
<version>2.0-SNAPSHOT</version>
</parent>

<artifactId>python-custom-rules-plugin</artifactId>
<packaging>sonar-plugin</packaging>

<name>Python Custom Rules Plugin</name>
<description>Python Custom Rules</description>

<dependencies>
<dependency>
<groupId>org.sonarsource.sonarqube</groupId>
<artifactId>sonar-plugin-api</artifactId>
</dependency>
<dependency>
<groupId>org.sonarsource.python</groupId>
<artifactId>sonar-python-plugin</artifactId>
<type>sonar-plugin</type>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.sonarsource.python</groupId>
<artifactId>python-checks-testkit</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>false</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId>
<artifactId>sonar-packaging-maven-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<pluginClass>org.sonar.samples.python.CustomPythonRulesPlugin</pluginClass>
</configuration>
</plugin>

<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* SonarQube Python Plugin
* Copyright (C) 2012-2019 SonarSource SA
* mailto:info 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.samples.python;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.sonar.api.server.rule.RulesDefinition;
import org.sonar.api.server.rule.RulesDefinitionAnnotationLoader;
import org.sonar.plugins.python.api.PythonCustomRuleRepository;

public class CustomPythonRuleRepository implements RulesDefinition, PythonCustomRuleRepository {

@Override
public void define(Context context) {
NewRepository repository = context.createRepository(repositoryKey(), "py").setName("My custom repo");
new RulesDefinitionAnnotationLoader().load(repository, checkClasses().toArray(new Class[] {}));
Map<String, String> remediationCosts = new HashMap<>();
remediationCosts.put("visitor", "5min");
remediationCosts.put("subscription", "10min");
repository.rules().forEach(rule -> rule.setDebtRemediationFunction(
rule.debtRemediationFunctions().constantPerIssue(remediationCosts.get(rule.key()))));
repository.done();
}

@Override
public String repositoryKey() {
return "python-custom-rules";
}

@Override
public List<Class> checkClasses() {
return Arrays.asList(CustomPythonVisitorCheck.class, CustomPythonSubscriptionCheck.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* SonarQube Python Plugin
* Copyright (C) 2012-2019 SonarSource SA
* mailto:info 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.samples.python;

import org.sonar.api.Plugin;

public class CustomPythonRulesPlugin implements Plugin {

@Override
public void define(Context context) {
context.addExtension(CustomPythonRuleRepository.class);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* SonarQube Python Plugin
* Copyright (C) 2012-2019 SonarSource SA
* mailto:info 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.samples.python;

import org.sonar.check.Priority;
import org.sonar.check.Rule;
import org.sonar.plugins.python.api.PythonSubscriptionCheck;
import org.sonar.plugins.python.api.tree.ForStatement;
import org.sonar.plugins.python.api.tree.Tree;

@Rule(
key = "subscription",
priority = Priority.MINOR,
name = "Python subscription visitor check",
description = "desc")
public class CustomPythonSubscriptionCheck extends PythonSubscriptionCheck {

@Override
public void initialize(Context context) {
context.registerSyntaxNodeConsumer(Tree.Kind.FOR_STMT, ctx -> ctx.addIssue(((ForStatement) ctx.syntaxNode()).forKeyword(), "For statement."));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* SonarQube Python Plugin
* Copyright (C) 2012-2019 SonarSource SA
* mailto:info 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.samples.python;

import org.sonar.check.Priority;
import org.sonar.check.Rule;
import org.sonar.plugins.python.api.PythonCheckTree;
import org.sonar.plugins.python.api.tree.FunctionDef;

@Rule(
key = "visitor",
priority = Priority.MINOR,
name = "Python visitor check",
description = "desc")
public class CustomPythonVisitorCheck extends PythonCheckTree {

@Override
public void visitFunctionDef(FunctionDef pyFunctionDefTree) {
addIssue(pyFunctionDefTree.name(), "Function def.");
super.visitFunctionDef(pyFunctionDefTree);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* SonarQube Python Plugin
* Copyright (C) 2012-2019 SonarSource SA
* mailto:info 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.
*/
@ParametersAreNonnullByDefault
package org.sonar.samples.python;

import javax.annotation.ParametersAreNonnullByDefault;

Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* SonarQube Python Plugin
* Copyright (C) 2012-2019 SonarSource SA
* mailto:info 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.samples.python;

import org.junit.Test;
import org.sonar.api.server.rule.RulesDefinition;

import static org.assertj.core.api.Assertions.assertThat;

public class CustomPythonRuleRepositoryTest {

@Test
public void test_rule_repository() {
CustomPythonRuleRepository customPythonRuleRepository = new CustomPythonRuleRepository();
RulesDefinition.Context context = new RulesDefinition.Context();
customPythonRuleRepository.define(context);
assertThat(customPythonRuleRepository.repositoryKey()).isEqualTo("python-custom-rules");
assertThat(context.repositories()).hasSize(1).extracting("key").containsExactly(customPythonRuleRepository.repositoryKey());
assertThat(context.repositories().get(0).rules()).hasSize(2);
assertThat(customPythonRuleRepository.checkClasses()).hasSize(2);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* SonarQube Python Plugin
* Copyright (C) 2012-2019 SonarSource SA
* mailto:info 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.samples.python;

import org.junit.Test;
import org.sonar.api.Plugin;
import org.sonar.api.SonarEdition;
import org.sonar.api.SonarQubeSide;
import org.sonar.api.SonarRuntime;
import org.sonar.api.internal.PluginContextImpl;
import org.sonar.api.internal.SonarRuntimeImpl;
import org.sonar.api.utils.Version;

import static org.assertj.core.api.Assertions.assertThat;

public class CustomPythonRulesPluginTest {
@Test
public void test() {
SonarRuntime sonarRuntime = SonarRuntimeImpl.forSonarQube(Version.create(7, 9), SonarQubeSide.SCANNER, SonarEdition.DEVELOPER);
Plugin.Context context = new PluginContextImpl.Builder().setSonarRuntime(sonarRuntime).build();
new CustomPythonRulesPlugin().define(context);
assertThat(context.getExtensions()).hasSize(1);
}
}
Loading