*** `rules/Sxxxx/metadata.json`: rule metadata shared between language-specific RSPECs. Each language can override fields in its own `metadata.json` file. +
It is thanks to this file that you can add `tags`, `securityStandards` etc... to your rule.
**** `rules/Sxxxx/[LANGUAGE]/rule.adoc`: asciidoc file used to generate the `Sxxxx` rule description for programming language `[LANGUAGE]`. It can include parts from `*.adoc` files located in the parent directory.
**** `rules/Sxxxx/[LANGUAGE]/metadata.json`: metadatas for the specific language. Each key at the top will completely override the key of the `metadata.json` file of the parent directory.
All specified rules (implemented or not) are listed in the https://sonarsource.github.io/rspec/#/[Search Page].
For each rule, you can find the languages it covers, the descriptions for each language as well as the related open tickets and pull requests. +
There will be a red warning with a link to the rule pull request if the rule has not been implemented yet (i.e. is not present on the main branch yet).
You can use the "Search in unimplemented" link on the Search Page to repeat your search in the PRs.
WARNING: Unlike the Search Page, the GitHub search across the PRs for unimplemented rules considers only the PR summary and title. It does not search the content of the proposed rule (i.e. it does not look into `rule.adoc` nor into `metadata.json`).
However, one of the reasons we are migrating to a git repository is that we want to have a clean process and history for rule creation and modification.
In particular, the main branch aims at representing what will be integrated in the next version of the analyzers, i.e. what will be part of the next releases.
Thus every newly created rule or modification of rule should follow these steps:
. Create a pull request adding or modifying a rule
. Ask for a review
. Create an implementation ticket
. Implement the new rule or the change in the existing rule
You should see https://github.com/pulls/assigned[a new pull request assigned to you]. It might take up to a few minutes to appear.
It contains a scaffolding of files for the new rule. Feel free to modify it as you please.
The title of the PR for a new rule will say only "Create rule Sxxxx", which is not very informative. +
Modify the title to better summarize the nature or the rule, so that it is easier to find when searching through unimplemented rules.
Do preserve the "Create rule Sxxxx" prefix, as it is used by our tooling.
For example:
----
Create rule S7028: All identifiers should be in CamelCase
----
Add the description of the PR to further increase its discoverability
(GitHub PR search does not see the `rule.adoc`).
To do that, click on the three dots (next to the smile) on the first comment (created by github-actions bot) and select "Edit".
The rule must contain subdirectories corresponding to all the languages this rule will be implemented for (by the time the PR is merged).
Each language subdirectory contains the `rule.adoc` that is the root document used to render the specification.
The rule specification in `rule.adoc` can include other `*.adoc` files that are in the language subdirectory or in the parent directory by using the `include::content.adoc[]` syntax.
To reduce the number of turnarounds with the asciidoc edits you can install an asciidoc plugin.
Otherwise, you can use https://asciidoclive.com/[AsciiDocLIVE] and this https://docs.asciidoctor.org/asciidoc/latest/syntax-quick-reference/[cheatsheet].
==== To add language to an existing rule
If the rule exists on the main branch, create a PR named "Create rule Sxxxx[_language_]: _rule title_". For example:
----
Create rule S100[java]: Method names should comply with a naming convention
----
Otherwise, if the rule has not been merged yet (i.e. the rule has not been implemented by any plugin), you can use the already existing PR corresponding to this rule. +
Then,
* Create a subdirectory with the name of the language you want to add. +
It can be any of the following:
include::supported_languages.adoc[]
* Add two files in this subdirectory:
** `rule.adoc`: write down the whole description of the rule. If you want to include already existing parts (that are in the current or the parent directory), use the `include::` syntax.
** `metadata.json`: it automatically inherits from the `metadata.json` of the parent directory so you only need to write the parts that need to be overwritten. +
Please note that in any case this file should at least contain two curly braces (`{ }`)
Create an implementation ticket as it is usually done for your plugin (i.e. as a Jira ticket or a Github issue). +
For this ticket to be correcty indexed on the search page of the rules, it has to contain the rule ID (RSPEC-1234 or S1234) either in the ticket title or in the ticket description. +
It is also recommended to add a link to the Github Page of the related rule, to ease the navigation between the ticket and the rule.
In the pull request adding the rule specification, add the following text referencing the implementation ticket:
Only once the implementation is complete, but before it is merged on the analyzer side, merge the RSPEC PR.
The RSPEC PR has to be merged before the implementation PR to enable `rule-api` to fetch the correct metadata in the analyzer.
The RSPEC PR has to be merged as close as possible to the merge of the implementation PR to shorten the time span of the inconsistency in the rule status
("active" in the RSPEC metadata, and not implemented on the analyzer side).
Finally, merge the rule implementation in your analyzer repository.
Multi-language rule creation is more involved than the default process because it involves multiple roles that typically do not coincide.
It is infeasible to synchronize the implementation of the rule for all the languages it covers.
The special metadata field `"extra"."coveredLanguages"` enables asynchrous implementation in multiple analyzers.
`"extra"."coveredLanguages"` contains the languages the rule is implemented for.
The workflow below makes sure that all rules on the main branch are implemented for all languages they are specified for or for all languages listed in `"coveredLanguages"`.
. An RSPECator creates a PR and specifies the multi-language rule.
* The RSPECator asks for a review for the PR.
* The RSPECator does not merge the PR, even after the review is done.
* The rule metadata.json contains an empty `"extra": {"coveredLanguages": []}` field.
. The RSPECator opens implementation tickets for all the targeted languages.
. An Ada analyzer developer Alice implements the rule first. Alice prepares the PR with the implementation.
. As soon as the implementation of the rule is ready for Ada analyzer, Alice merges both PRs:
.. Alice adds `"Ada"` to `"coveredLanguages"` in the RSPEC PR (`"extra": {"coveredLanguages": ["Ada"]}`).
.. Alice merges the RSPEC PR.
.. Alice fetches the rule metadata with `rule-api` into Ada analyzer.
.. Alice merges the rule implementation in Ada analyzer.
. A Cobol analyzer developer Bob implements the rule some time later. Bob prepares the PR with the implementation.
. Bob opens a new RSPEC PR "Modify rule S1234: Add Cobol support" to add `"Cobol"` to `"coveredLangauges"` (`"extra": {"coveredLanguages": ["Ada", "Cobol"]}`).
. As soon as the Cobol implementation is ready, Bob merges both PRs:
.. Bob merges his RSPEC PR.
.. Bob fetches the rule metadata with `rule-api` into Cobol analyzer.
.. Bob merges the rule implementation in Cobol analyzer.
Untriaged PRs are the ones without any label. You can easily see all of them with the filter https://github.com/SonarSource/rspec/pulls?q=is%3Aopen+is%3Apr+no%3Alabel[`Label > Unlabeled`]. +
All triaged PRs should have at least one label that corresponds to the bubble(s) the PR is related to. This allows bubbles to easily filter out the PRs they are interested in.
The following graph shows the path of an RSPEC from its inception in Github RSPEC repository to its consumption in SQ/SC/SL or on rules.sonarsource.com: +
(The part that is grayed out corresponds to what existed before, when RSPECs were hosted in Jira)
Tickets related to this RSPEC repository are in Jira, in the https://jira.sonarsource.com/projects/RULEAPI/issues/RULEAPI-324?filter=allopenissues[RULEAPI] project.
You found a bug, something is bothering you or you have an idea of how to improve the project? First, have a look at all the https://jira.sonarsource.com/projects/RULEAPI/issues/RULEAPI-324?filter=allopenissues[open tickets]. If you don't see anything related to your subject, please open a new ticket in the backlog, with `backlog` as the fix version.