Skip to main content

rule-options

Add or modify rule options in SonarJS, including the fields array, SonarQube UI visibility, and Java check class configuration. Use when working on rule configurations.

Zur Installation springen

Quellinformationen

Repository
SonarSource/SonarJS
Letzte Quellaktivität
14. September 2026 um 15:19
Erkannte Sprache von SKILL.md
Englisch
Sterne
1.291
Forks
192

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
rule-options
description
Add or modify rule options in SonarJS, including the fields array, SonarQube UI visibility, and Java check class configuration. Use when working on rule configurations.
## Architecture Overview Rule options flow through one typed path: ``` SonarQube UI → Java Check Class → configurations() → AnalyzeProjectRequest → normalizeJsTsRules() → ESLint Linter ``` The Java bridge encodes rule configurations as protobuf `Value` messages. Node.js receives numbers, booleans, strings, arrays, and objects with their types preserved. ## Key Files per Rule | File | Purpose | | ------------------- | ----------------------------------------------------------- | | `rule.ts` | ESLint rule implementation | | `meta.ts` | `implementation`, `eslintId`, `schema`, re-exports `fields` | | `config.ts` | `fields` array — source of truth for options | | `generated-meta.ts` | Auto-generated `defaultOptions` — do not edit | ## The `fields` Array (`config.ts`) The `fields` array defines options for SonarQube integration and default values. ```typescript import type { ESLintConfiguration } from '../helpers/configs.js'; export const fields = [ [ // outer array = one ESLint options object { field: 'max', // ESLint option name displayName: 'maximumFunctionParameters', // SonarQube key (if different) description: 'Maximum authorized...', // REQUIRED for SQ visibility default: 7, // default value; determines type }, { field: 'ignoreIIFE', default: false, // no description = internal only }, ], ] as const satisfies ESLintConfiguration; ``` ### Field Properties | Property | Required | Purpose | | --------------- | --------------------- | -------------------------------------------------------------------------- | | `field` | Yes | ESLint/schema key name | | `default` | Yes | Default value; also determines type (`number`, `string`, `boolean`, array) | | `description` | **For SQ visibility** | Makes option visible in SonarQube UI | | `displayName` | No | SonarQube key if different from `field` | | `items` | For arrays | `{ type: 'string' }` or `{ type: 'integer' }` | | `customDefault` | No | Different default for SQ than ESLint | | `fieldType` | No | Override SQ field type (e.g., `'TEXT'`) | ## Making Options Visible in SonarQube **A field appears in the SonarQube UI only if it has a `description`.** Fields without `description` are internal defaults invisible to users. ```typescript // S109/config.ts — NOT visible in SQ (no descriptions) export const fields = [ [ { field: 'ignore', default: [0, 1, -1, 24, 60] }, { field: 'ignoreDefaultValues', default: true }, ], ] as const satisfies ESLintConfiguration; // S2068/config.ts — VISIBLE in SQ (has description) export const fields = [ [ { field: 'passwordWords', items: { type: 'string' }, description: 'Comma separated list of words identifying potential passwords.', default: ['password', 'pwd', 'passwd', 'passphrase'], }, ], ] as const satisfies ESLintConfiguration; ``` ## Configuration Shapes ### Object-style (most common) ```typescript export const fields = [ [ { field: 'max', description: '...', default: 7 }, { field: 'ignoreIIFE', description: '...', default: false }, ], ] as const satisfies ESLintConfiguration; // ESLint receives: [{ max: 7, ignoreIIFE: false }] ``` ### Primitive (single value) ```typescript export const fields = [{ default: '^[a-z]+$' }] as const satisfies ESLintConfiguration; // ESLint receives: ['^[a-z]+$'] ``` ### Array options (comma-separated in SQ) ```typescript export const fields = [ [ { field: 'passwordWords', items: { type: 'string' }, // required for Java codegen description: 'Comma separated list...', default: ['password', 'pwd'], }, ], ] as const satisfies ESLintConfiguration; // SQ sends: "password,pwd,secret" → ESLint: [{ passwordWords: ['password','pwd','secret'] }] ``` ## Typed gRPC Values The gRPC normalizer does not parse rule options from strings. The generated Java check converts SonarQube parameters to their runtime types before building the protobuf request. In particular, array parameters entered as comma-separated text in SonarQube are split and trimmed on the Java side, then received by Node.js as protobuf lists. See `docs/rule-configuration-patterns.md` for the supported option shapes and materialization rules. ## JSON Schema vs `fields` | Aspect | JSON Schema (`meta.ts`) | `fields` (`config.ts`) | | ------------ | ----------------------------- | ------------------------------------- | | Purpose | ESLint validation | SQ UI + defaults + key mapping | | Used by | ESLint at runtime | Java codegen, meta generation, linter | | Required for | `original` rules with options | All rules with options | For `original` rules, schema and fields must be kept in sync manually. For `decorated`/`external` rules, schema is inherited from the external rule. ## Adding Options to an Existing Rule 1. Update `config.ts` — add field to `fields` array 2. Add `description` if it should be visible in SonarQube 3. Update `meta.ts` schema (for `original`/`decorated` rules) 4. Run `npm run generate-meta` — updates `generated-meta.ts` with new `defaultOptions` 5. Run `npm run generate-java-rule-classes` — updates Java check classes 6. Verify Java class has correct `configurations()` method ## Java Check Class (`configurations()`) ```java // Example: S107Check.java @Override public List<Object> configurations() { return List.of(Map.of("max", maximum)); } @RuleProperty( key = "maximumFunctionParameters", description = "Maximum authorized number of parameters", defaultValue = "" + DEFAULT_MAX ) private int maximum = DEFAULT_MAX; ``` Use `MyRuleCheckTest.java` to verify serialization: ```java assertThat(new MyRuleCheck().configurations()).containsExactly(Map.of("max", 7)); ``` ## Key Mapping: SonarQube ↔ ESLint When SQ and ESLint use different names: ```typescript // config.ts { field: 'max', displayName: 'maximumFunctionParameters', ... } ``` `displayName` controls the generated SonarQube parameter key, while `field` remains the key in the materialized ESLint option. The generated Java check sends the typed ESLint-shaped configuration, which Node.js merges with the rule defaults.
Auf GitHub ansehen