Skip to content

Commit 3c1f56a

Browse files
JS-1452 Document ProfileRegistrar for default Sonar way activation (#6592)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent df1f61d commit 3c1f56a

2 files changed

Lines changed: 74 additions & 16 deletions

File tree

docs/custom-rules/CUSTOM_RULES_API_CHANGELOG.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ git show <commit-hash> --stat
2525
- `sonar-plugin/api/src/main/java/org/sonar/plugins/javascript/api/`
2626
- `EslintHook.java` - New hook interface (10.23.0+)
2727
- `EslintHookRegistrar.java` - Hook registration (10.23.0+)
28+
- `ProfileRegistrar.java` - Default profile activation SPI (10.22.0+)
2829
- `EslintBasedCheck.java` - Check interface (deprecated 11.6.0)
2930
- `JavaScriptCheck.java` - Marker interface (deprecated 11.6.0)
3031
- `CustomRuleRepository.java` - Rule repository interface
@@ -107,12 +108,13 @@ public Set<org.sonar.plugins.javascript.api.Language> compatibleLanguages() {
107108

108109
### SonarJS 10.22.0 (March 2025)
109110

110-
| Change | Details | Commit |
111-
| --------------------------------------- | ------------------------------------------- | ------------- |
112-
|`Language` enum added (standalone) | `org.sonar.plugins.javascript.api.Language` | `2f9168ca008` |
113-
|`compatibleLanguages()` method added | New method in `CustomRuleRepository` | `2f9168ca008` |
114-
| ⚠️ `languages()` method deprecated | Use `compatibleLanguages()` instead | `2f9168ca008` |
115-
| 🔄 `CustomRuleRepository` undeprecated | Interface itself is no longer deprecated | `2f9168ca008` |
111+
| Change | Details | Commit |
112+
| --------------------------------------- | ------------------------------------------------------------------ | ------------- |
113+
|`Language` enum added (standalone) | `org.sonar.plugins.javascript.api.Language` | `2f9168ca008` |
114+
|`compatibleLanguages()` method added | New method in `CustomRuleRepository` | `2f9168ca008` |
115+
|`ProfileRegistrar` interface added | Register extra rule keys in built-in default profile (`Sonar way`) | `27e268aad12` |
116+
| ⚠️ `languages()` method deprecated | Use `compatibleLanguages()` instead | `2f9168ca008` |
117+
| 🔄 `CustomRuleRepository` undeprecated | Interface itself is no longer deprecated | `2f9168ca008` |
116118

117119
**Migration**: Start using `compatibleLanguages()` to prepare for 11.x.
118120

@@ -250,6 +252,7 @@ JavaScriptCheck (deprecated, marker only)
250252
| `RulesBundle` | 6.x | - |
251253
| Separate API module | 10.15.0 | - |
252254
| `compatibleLanguages()` | 10.22.0 | 25.5.0 |
255+
| `ProfileRegistrar` | 10.22.0 | 25.5.0 |
253256
| `EslintHook` / `EslintHookRegistrar` | 10.23.0 | 25.6.0 |
254257
| `languages()` removed | 11.1.0 | 25.9.0 |
255258
| `EslintBasedCheck` deprecated | 11.6.0 | 25.12.0 |

docs/custom-rules/ESLINT_HOOKS.md

Lines changed: 65 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ This document describes the recommended approach for creating custom rules that
99
The `EslintHook` interface is the modern way to define custom rules in SonarJS. Rules implementing this interface:
1010

1111
- **Can raise Sonar issues** when registered via `CustomRuleRepository`
12-
- **Are activated through quality profiles** - only run when enabled by users
12+
- **Are activated through quality profiles** - by default, run only when enabled in the active quality profile
1313
- **Provide full control** over analysis modes, file types, and configurations
1414

1515
## Components
@@ -21,6 +21,7 @@ A complete custom rules integration requires:
2121
3. **Rules Bundle** - packages the ESLint-side JavaScript code
2222
4. **Rules Definition** - defines rule metadata for SonarQube
2323
5. **Plugin Class** - registers all components
24+
6. **Default Profile Registrar (optional)** - implements `ProfileRegistrar` to activate rules in built-in default profile (`Sonar way`)
2425

2526
## Implementation Guide
2627

@@ -284,6 +285,51 @@ Add the SonarJS API dependency to your `pom.xml`:
284285
</dependency>
285286
```
286287

288+
### 9. Optional: Activate Rules in the Default Built-In Profile
289+
290+
If you want your rules to be active by default in the built-in default quality profile (`Sonar way`), implement `ProfileRegistrar`:
291+
292+
```java
293+
package com.example.plugin;
294+
295+
import java.util.List;
296+
import org.sonar.api.rule.RuleKey;
297+
import org.sonar.plugins.javascript.api.Language;
298+
import org.sonar.plugins.javascript.api.ProfileRegistrar;
299+
300+
public class MyProfileRegistrar implements ProfileRegistrar {
301+
302+
@Override
303+
public void register(RegistrarContext registrarContext) {
304+
registrarContext.registerDefaultQualityProfileRules(
305+
Language.JAVASCRIPT,
306+
List.of(RuleKey.of(MyRuleRepository.REPOSITORY_KEY, "S1234"))
307+
);
308+
registrarContext.registerDefaultQualityProfileRules(
309+
Language.TYPESCRIPT,
310+
List.of(RuleKey.of(MyRuleRepository.REPOSITORY_KEY, "S1234"))
311+
);
312+
}
313+
}
314+
```
315+
316+
Register it in your plugin:
317+
318+
```java
319+
context.addExtensions(
320+
MyRulesBundle.class,
321+
MyRuleRepository.class,
322+
MyRulesDefinition.class,
323+
MyProfileRegistrar.class
324+
);
325+
```
326+
327+
Notes:
328+
329+
- This is `@ServerSide` API and is not used in SonarLint.
330+
- It contributes to the built-in default profile (`Sonar way`) only.
331+
- Users can still activate/deactivate your rules in any quality profile.
332+
287333
## API Reference
288334

289335
### EslintHook Interface
@@ -305,6 +351,13 @@ Add the SonarJS API dependency to your `pom.xml`:
305351
| `checkClasses()` | List of check classes implementing EslintHook |
306352
| `compatibleLanguages()` | Languages this repository supports (JS/TS) |
307353

354+
### ProfileRegistrar Interface (Optional)
355+
356+
| Method | Description |
357+
| ----------------------------------------- | -------------------------------------------------------------------------- |
358+
| `register(RegistrarContext)` | Called on server side to contribute additional default-profile activations |
359+
| `registerDefaultQualityProfileRules(...)` | Adds rule keys to the built-in default profile (`Sonar way`) for JS or TS |
360+
308361
## Best Practices
309362

310363
1. **Use `@JavaScriptRule` and `@TypeScriptRule` annotations** - These control which languages your rule applies to.
@@ -658,12 +711,14 @@ This is why `CustomRuleRepository` rules can raise issues: their `eslintKey` is
658711

659712
### Key Integration Points
660713

661-
| Component | File | Purpose |
662-
| ------------------------------ | ---------------------------------------------------------- | ------------------------------------ |
663-
| `EslintHook` | `sonar-plugin/api/.../EslintHook.java` | Rule interface |
664-
| `CustomRuleRepository` | `sonar-plugin/api/.../CustomRuleRepository.java` | Interface for rule repositories |
665-
| `RulesBundle` | `sonar-plugin/api/.../RulesBundle.java` | Interface for JS bundle location |
666-
| `JsTsChecks.addCustomChecks()` | `sonar-plugin/sonar-javascript-plugin/.../JsTsChecks.java` | Processes custom repositories |
667-
| `JsTsChecks.doAddChecks()` | `sonar-plugin/sonar-javascript-plugin/.../JsTsChecks.java` | Instantiates checks via CheckFactory |
668-
| `RulesBundles` | `sonar-plugin/bridge/.../RulesBundles.java` | Deploys JS bundles |
669-
| `Linter` | `packages/jsts/src/linter/linter.ts` | Loads and executes rules |
714+
| Component | File | Purpose |
715+
| ------------------------------ | ---------------------------------------------------------------------------- | ------------------------------------- |
716+
| `EslintHook` | `sonar-plugin/api/.../EslintHook.java` | Rule interface |
717+
| `CustomRuleRepository` | `sonar-plugin/api/.../CustomRuleRepository.java` | Interface for rule repositories |
718+
| `ProfileRegistrar` | `sonar-plugin/api/.../ProfileRegistrar.java` | Optional default-profile activations |
719+
| `RulesBundle` | `sonar-plugin/api/.../RulesBundle.java` | Interface for JS bundle location |
720+
| `JsTsChecks.addCustomChecks()` | `sonar-plugin/sonar-javascript-plugin/.../JsTsChecks.java` | Processes custom repositories |
721+
| `JsTsChecks.doAddChecks()` | `sonar-plugin/sonar-javascript-plugin/.../JsTsChecks.java` | Instantiates checks via CheckFactory |
722+
| `JavaScriptProfilesDefinition` | `sonar-plugin/sonar-javascript-plugin/.../JavaScriptProfilesDefinition.java` | Applies default-profile contributions |
723+
| `RulesBundles` | `sonar-plugin/bridge/.../RulesBundles.java` | Deploys JS bundles |
724+
| `Linter` | `packages/jsts/src/linter/linter.ts` | Loads and executes rules |

0 commit comments

Comments
 (0)