Browse Source

SONARPY-395 Update documentation for python custom rules (#2172)

tags/8.1.0.31237
benzonico 4 years ago
parent
commit
f8ee1dfe40

+ 78
- 0
server/sonar-docs/src/pages/analysis/languages/python.md View File

@@ -27,6 +27,84 @@ pylint <module_or_package> -r n --msg-template="{path}:{line}: [{msg_id}({symbol
```
Then pass the generated report path to analysis via the `sonar.python.pylint.reportPath` property.

<!-- sonarqube -->

## Custom Rules

### Overview

The Python analyzer parses the source code, creates an Abstract Syntax Tree (AST) and then walks through the entire tree. A coding rule is a visitor that is able to visit nodes from this AST.

As soon as the coding rule visits a node, it can navigate its children and log issues if necessary.

### Writing a Plugin

Custom rules for Python can be added by writing a SonarQube Plugin and using Python analyzer APIs.
Here are the step to follow:

#### Create SonarQube Plugin

* create a standard SonarQube plugin project
* attach this plugin to the SonarQube Python analyzer through the `pom.xml`:
* add the dependency to the Python analyzer.
* add the following line in the sonar-packaging-maven-plugin configuration.
```
<requirePlugins>python:2.0-SNAPSHOT</requirePlugin>
```
* implement the following extension points:
* [Plugin](http://javadocs.sonarsource.org/latest/apidocs/org/sonar/api/Plugin.html)
* [RulesDefinition](http://javadocs.sonarsource.org/latest/apidocs/org/sonar/api/server/rule/RulesDefinition.html) and [PythonCustomRuleRepository](https://github.com/SonarSource/sonar-python/blob/master/python-frontend/src/main/java/org/sonar/plugins/python/api/PythonCustomRuleRepository.java), which can be implemented by a single class, to declare your custom rules
* declare the RulesDefinition as an extension in the Plugin extension point.

#### Implement a Rule

* create a class that will hold the implementation of the rule, it should:
* extend `PythonCheckTree` or `PythonSubscriptionCheck`
* define the rule name, key, tags, etc. with Java annotations.
* declare this class in the `RulesDefinition`.

### Example Plugin

To get started a sample plugin can be found here: [python-custom-rules](https://github.com/SonarSource/sonar-custom-rules-examples/tree/master/python-custom-rules).

#### Implementation Details

**Using `PythonCheckTree`**

To explore a part of the AST, override a method from the PythonCheckTree. For example, if you want to explore "if statement" nodes, override [PythonCheckTree#visitIfStatement](https://github.com/SonarSource/sonar-python/blob/39b6126e9fdef42b93004cf6cc5818e861051334/python-frontend/src/main/java/org/sonar/plugins/python/api/tree/BaseTreeVisitor.java#L56) method that will be called each time an [ifStatement](https://github.com/SonarSource/sonar-python/blob/master/python-frontend/src/main/java/org/sonar/plugins/python/api/tree/IfStatement.java) node is encountered in the AST.

![](/images/exclamation.svg) When overriding a visit method, you must call the super method in order to allow the visitor to visit the children the node.

**Using `PythonSubscriptionCheck`**

To explore a part of the AST, override [`PythonSubscriptionCheck#initialize`](https://github.com/SonarSource/sonar-python/blob/master/python-frontend/src/main/java/org/sonar/plugins/python/api/SubscriptionCheck.java#L26) and call the [`SubscriptionCheck.Context#registerSyntaxNodeConsumer`](https://github.com/SonarSource/sonar-python/blob/master/python-frontend/src/main/java/org/sonar/plugins/python/api/SubscriptionCheck.java) with the [`Tree#Kind`](https://github.com/SonarSource/sonar-python/blob/master/python-frontend/src/main/java/org/sonar/plugins/python/api/tree/Tree.java#L42) of node you want to visit. For example, if you want to explore "if statement" you should register to the kind [`Tree#Kind#IF_STATEMENT`](https://github.com/SonarSource/sonar-python/blob/master/python-frontend/src/main/java/org/sonar/plugins/python/api/tree/Tree.java#L97) and then provide a lambda that will consume a [`SubscriptionContext`](https://github.com/SonarSource/sonar-python/blob/master/python-frontend/src/main/java/org/sonar/plugins/python/api/SubscriptionContext.java#L27) to act on such ndoes.

**Create Issues**

From the check, issue can be created by calling [`SubscriptionContext#addIssue`](https://github.com/SonarSource/sonar-python/blob/master/python-frontend/src/main/java/org/sonar/plugins/python/api/SubscriptionContext.java#L30) method or [`PythonCheckTree#addIssue`](https://github.com/SonarSource/sonar-python/blob/master/python-frontend/src/main/java/org/sonar/plugins/python/api/PythonCheckTree.java#L36) method.

**Testing Checks**

To test custom checks you can use method [`PythonCheckVerifier#verify`](https://github.com/SonarSource/sonar-python/blob/master/python-checks-testkit/src/main/java/org/sonar/python/checks/utils/PythonCheckVerifier.java). Don't forget to add the testkit dependency to access this class from your project :
```
<dependency>
<groupId>org.sonarsource.python</groupId>
<artifactId>python-checks-testkit</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
```

You should end each line with an issue with a comment in the following form:

```
# Noncompliant {{Message}}
```

Comment syntax is described [here](https://github.com/SonarSource/sonar-analyzer-commons/blob/master/test-commons/README.md).

<!-- /sonarqube -->

## Related Pages
* [Importing External Issues](/analysis/external-issues/) ([Pylint](http://www.pylint.org/), [Bandit](https://github.com/PyCQA/bandit/blob/master/README.rst))
* [Test Coverage & Execution](/analysis/coverage/) (the [Coverage Tool](http://nedbatchelder.com/code/coverage/) provided by [Ned Batchelder](http://nedbatchelder.com/), [Nose](https://nose.readthedocs.org/en/latest/), [pytest](https://docs.pytest.org/en/latest/))

+ 2
- 2
server/sonar-docs/src/pages/extend/adding-coding-rules.md View File

@@ -26,7 +26,7 @@ JavaScript | - | ![](/images/check.svg) | -
PHP | - | ![](/images/check.svg)| -
PL/SQL | ![](/images/check.svg) | - | -
PL/I | ![](/images/check.svg) | - | -
Python | Deprecated | - | -
Python | - | ![](/images/check.svg) | -
RPG | - | ![](/images/check.svg)| -
VB.NET| - | - | ![](/images/check.svg)[Importing Issues from Third-Party Roslyn Analyzers (C#, VB.NET)](/analysis/external-issues/)
XML | ![](/images/check.svg) | - | -
@@ -48,6 +48,7 @@ See the following pages to see samples and details about how to create coding ru
* [for Java](/analysis/languages/java/)
* [for JavaScript](/analysis/languages/javascript/)
* [for PHP](/analysis/languages/php/)
* [for Python](/analysis/languages/python/)
* [for RPG](/analysis/languages/rpg/)


@@ -67,7 +68,6 @@ The latest version of SSLR Toolkit can be downloaded from following locations:
* [Flex](https://binaries.sonarsource.com/Distribution/sonar-flex-plugin/)
* [PL/SQL](https://binaries.sonarsource.com/CommercialDistribution/sslr-plsql-toolkit/)
* [PL/I](https://binaries.sonarsource.com/CommercialDistribution/sslr-pli-toolkit/)
* [Python](https://binaries.sonarsource.com/Distribution/sslr-python-toolkit/) (Deprecated)

For an SSLR preview, consider the following source code sample:
```

Loading…
Cancel
Save