SonarLint does not use SonarQube's custom quality profiles

  • Operating system: Windows 10
  • SonarLint plugin version: 7.4.0.60471
  • Programming language you’re coding in: TypeScript
  • Is connected mode used: Yes
    • Connected to SonarQube 9.5 (build 56709):

On the SonarQube server there are defined some custom quality profiles which extend from the default (Sonar way) quality profile. The SonarLint plugin is connected with the SonarQube server and the respective project as defined in the official documentation and as a result can be seen the issues from the default quality profile. Since the project is an Angular project, HTML issues are shown as well.

The problem is that TypeScript issues from the custom quality profiles which can be seen on the SonarQube server are not presented in the SonarLint plugin in IntelliJ.

(I have seen this FAQ post: Frequently asked questions and can say that we are not speaking about test files, but normal TypeScript files.)

Hi @Cloud9Clone

The problem is that TypeScript issues from the custom quality profiles which can be seen on the SonarQube server are not presented in the SonarLint plugin in IntelliJ.

Do you still see some TypeScript issues (the one from SonarWay)? Or no TypeScript issues at all? Are you able to get some TypeScript issues when disabling connected mode?

Can you list a few rule keys (like typescript:S1234) that you are expecting to raise issues in your code and that don’t work in SonarLint?

I see one TypeScript issue (typescript:S106) in SonarLint.

When I disable the connected mode, I get a lot fewer HTML issues and the TypeScript issue is not presented.

For example typescript:S121, typescript:S1440 are successfully triggered in SonarQube, but not presented in SonarLint.

typescript:S106, typescript:S121 and typescript:S1440 are not active by default in SonarLint, and are not part of SonarWay (I haven’t checked with SonarQube 9.5, but they are definitely not enabled in 9.9).

The fact you see one issue for typescript:S106 is a piece of evidence that SonarLint is somehow using a different quality profile than SonarWay.

We have changed quite a lot the way SonarLint synchronizes quality profiles with SonarQube in the past releases, and this is relying on changes on SonarQube side as well. So one thing you can do is to ask for your SonarQube server to be updated to the latest LTS (9.9), since we are not actively supporting/testing the connected mode with non-LTS releases of SonarQube (except the latest release).

Another thing you can try is to manually force SonarLint to resync its local storage. To do that, go to the binding configuration screen, and click on Update local storage button.

I tried the manual force of SonarLint multiple times, but there is no change.

Is there a way to check which quality profiles are used by SonarLint?

When you manually trigger a sync of the local storage, and if you have verbose logs enabled, you should see in the SonarLint logs something like:

GET 200 https://<sq>/api/qualityprofiles/search.protobuf?project=<projectKey> | response time=97ms
Downloaded project quality profiles in 97ms
[...]
[SYNC] Fetching rule set for language 'js' from profile 'AXDEr5Q7LjElHiH99ZhW'
GET 200 https://<sq>/api/rules/search.protobuf?qprofile=AXDEr5Q7LjElHiH99ZhW&activation=true&f=templateKey,actives&types=CODE_SMELL,BUG,VULNERABILITY,SECURITY_HOTSPOT&s=key&ps=500&p=1 | response time=203ms
Page downloaded in 205ms

so you don’t have the quality profile name, but you have its id, which you can find in some SonarQube URL (for example on the rules page, when you filter by quality profile).

Then, when you analyze a file, you should see logs like:

Starting analysis with configuration: [...]
  * ts: xxx active rules

this should give you an idea of the number of active rules considered by SonarLint (but remember that SonarLint is excluding some rules, like security hotspots, taint vulnerabilities, …).

Thank you for the instructions Julien. I did like you described and came with the following observations:

SonarLint uses the same profile (I compared the id), which contains typescript:S106, typescript:S121 and typescript:S1440, but somehow does not apply these and other rules. (On the SonarQube server they are applied)

From the logs, I examined the following information about the rules:

* ts: 230 active rules
Rule typescript:S5728 is enabled on the server, but not available in SonarLint
Rule typescript:S5604 is enabled on the server, but not available in SonarLint
Rule typescript:S5725 is enabled on the server, but not available in SonarLint
Rule typescript:S5730 is enabled on the server, but not available in SonarLint
Rule typescript:S5732 is enabled on the server, but not available in SonarLint
Rule typescript:S6268 is enabled on the server, but not available in SonarLint
Rule typescript:S5852 is enabled on the server, but not available in SonarLint
Rule typescript:S5739 is enabled on the server, but not available in SonarLint
Rule typescript:S5734 is enabled on the server, but not available in SonarLint
Rule typescript:S5736 is enabled on the server, but not available in SonarLint
Rule typescript:S5743 is enabled on the server, but not available in SonarLint
Rule typescript:S5742 is enabled on the server, but not available in SonarLint
Rule typescript:S2245 is enabled on the server, but not available in SonarLint
Rule typescript:S3330 is enabled on the server, but not available in SonarLint
Rule typescript:S5759 is enabled on the server, but not available in SonarLint
Rule typescript:S5757 is enabled on the server, but not available in SonarLint
Rule typescript:S6299 is enabled on the server, but not available in SonarLint
Rule typescript:S4790 is enabled on the server, but not available in SonarLint
Rule typescript:S5443 is enabled on the server, but not available in SonarLint
Rule typescript:S5689 is enabled on the server, but not available in SonarLint
Rule typescript:S1523 is enabled on the server, but not available in SonarLint
Rule typescript:S2612 is enabled on the server, but not available in SonarLint
Rule typescript:S5691 is enabled on the server, but not available in SonarLint
Rule typescript:S2068 is enabled on the server, but not available in SonarLint
Rule typescript:S5693 is enabled on the server, but not available in SonarLint
Rule typescript:S5332 is enabled on the server, but not available in SonarLint
Rule typescript:S2077 is enabled on the server, but not available in SonarLint
Rule typescript:S1313 is enabled on the server, but not available in SonarLint
Rule typescript:S2092 is enabled on the server, but not available in SonarLint
Rule typescript:S4036 is enabled on the server, but not available in SonarLint
Rule typescript:S5247 is enabled on the server, but not available in SonarLint
Rule typescript:S5122 is enabled on the server, but not available in SonarLint
Rule typescript:S4721 is enabled on the server, but not available in SonarLint
Rule typescript:S4507 is enabled on the server, but not available in SonarLint
Rule typescript:S4502 is enabled on the server, but not available in SonarLint
Rule typescript:S5042 is enabled on the server, but not available in SonarLint

As you can see, the upper discussed three rules are not presented here (that’s why I am saying that SonarLint ignores other rules also). From the remaining logs I found other pieces of information which potentially may give a direction for a solution.

...
Execute Sensor: TypeScript analysis
eslint-bridge server is up, no need to start.
Analysis of unchanged files will not be skipped (current analysis requires all files to be analyzed)
Initializing linter "default" with max-statements-per-line,curly,no-commented-code,sonar-no-fallthrough,duplicates-in-character-class,no-inverted-boolean-check,file-uploads,sonar-no-misleading-character-class,arguments-order,no-same-argument-assert,no-unsafe-finally,prefer-while,unused-named-groups,single-character-alternation,nested-control-flow,sonar-max-lines-per-function,no-use-of-empty-return-value,session-regeneration,no-associative-arrays,no-weak-keys,no-useless-increment,weak-ssl,no-throw-literal,no-redundant-optional,post-message,constructor-for-side-effects,prefer-readonly,no-redeclare,no-globals-shadowing,bool-param-default,unverified-hostname,for-loop-increment-sign,no-return-await,no-nested-conditional,no-unnecessary-type-assertion,no-implicit-dependencies,insecure-jwt-token,no-dead-store,no-this-alias,prefer-const,prefer-type-guard,no-return-type-any,no-unused-function-argument,use-type-alias,no-in-misuse,no-parameter-reassignment,no-incorrect-string-concat,class-prototype,updated-loop-counter,concise-regex,stateful-regex,test-check-exception,no-extra-semi,max-switch-cases,no-undefined-argument,no-labels,cognitive-complexity,max-union-size,use-isnan,no-shadow,inverted-assertion-arguments,no-nested-template-literals,no-duplicate-in-composite,generator-without-yield,no-ignored-return,no-caller,no-redundant-parentheses,call-argument-line,no-unenclosed-multiline-block,no-redundant-boolean,prefer-immediate-return,prefer-promise-shorthand,no-template-curly-in-string,regex-complexity,no-empty-after-reluctant,assertions-in-tests,unused-import,empty-string-repetition,no-nested-assignment,index-of-compare-to-positive-number,file-name-differ-from-class,todo-tag,prefer-default-last,no-gratuitous-expressions,no-empty-pattern,sonar-no-invalid-regexp,anchor-precedence,fixme-tag,no-trailing-spaces,no-nested-incdec,non-existent-operator,new-operator-misuse,no-small-switch,no-for-in-iterable,prefer-for-of,default-param-last,xml-parser-xxe,no-global-this,no-array-delete,no-alphabetical-sort,consistent-type-assertions,adjacent-overload-signatures,cyclomatic-complexity,no-sequences,void-use,no-octal,comma-or-logical-or-case,label-position,conditional-indentation,existing-groups,semi,super-invocation,no-try-promise,sonar-no-control-regex,no-empty-alternatives,sonar-no-regex-spaces,prefer-regex-literals,no-same-line-conditional,no-empty-interface,no-identical-functions,no-element-overwrite,no-equals-in-for-termination,no-sparse-arrays,no-var,no-redundant-jump,no-duplicate-imports,no-unthrown-error,no-unnecessary-type-arguments,no-collection-size-mischeck,prefer-namespace-keyword,unverified-certificate,no-empty-collection,no-empty-group,quotes,eqeqeq,no-accessor-field-mismatch,no-unused-collection,no-invariant-returns,radix,no-case-label-in-switch,prefer-template,no-built-in-override,arguments-usage,destructuring-assignment-syntax,no-misleading-array-reverse,no-redundant-assignments,no-inconsistent-returns,no-all-duplicated-branches,no-identical-conditions,no-weak-cipher,no-delete-var,encryption-secure-mode,strings-comparison,no-useless-intersection,sonar-block-scoped-var,expression-complexity,no-empty-function,no-code-after-done,no-unsafe-negation,no-non-null-assertion,deprecation,misplaced-loop-counter,no-one-iteration-loop,no-multi-str,function-inside-loop,object-shorthand,no-inferrable-types,no-duplicated-branches,no-duplicate-string,disabled-timeout,bitwise-operators,class-name,array-constructor,sonar-max-lines,no-console,no-identical-expressions,no-unreachable,no-useless-catch,no-variable-usage-before-declaration,no-incomplete-assertions,chai-determinate-assertion,eol-last,variable-name,no-primitive-wrappers,no-exclusive-tests,no-self-assign,no-misused-new,no-invalid-await,no-function-declaration-in-block,no-empty,sonar-max-params,no-magic-numbers,no-unused-expressions
Resolving TSConfig files using './tsconfig.json' from property sonar.typescript.tsconfigPath
Using './tsconfig.json' to resolve TSConfig file(s)
Found 1 TSConfig file(s): [D:\Workspaces\<project-name>\.\tsconfig.json]
D:/Workspaces/<project-name>/src/app/components/partials/navigation/navigation.component.ts matched NO_CONFIG
Skipping 1 files with no tsconfig.json
Skipped files: [uri=file:///D:/Workspaces/<project-name>/src/app/components/partials/navigation/navigation.component.ts]
1 source file to be analyzed
1/1 source file has been analyzed
Hit the cache for 0 out of 0
Miss the cache for 0 out of 0
...

The file where typescript:S1440 and typescript:S121 must be detected is the one from the logs, namely navigation.component.ts. But maybe because there are not applied, the file is skipped. I don’t know if the fact that I have no specified property sonar.typescript.tsconfigPath in my sonar-project.properties might be a cause. (Maybe not, since it finds the file and the issues are rendered on the SonarQube server). Any idea where the issue might be?

I think you found the root cause. This particular file is totally ignored by the analyzer, apparently because of the lack of appropriate tsconfig.json.

SonarLint is not using properties from the sonar-project.properties. This is only for SonarQube scanners.

This is suspicious. Have you by chance tried to manually configure the property in SonarLint settings?
If yes, I suggest you try to remove it, and let our analyzer auto-detect the location of the tsconfig.json file.

I checked and can confirm that no Analysis properties are specified, so the analyzer auto-detects it successfully.

A little bit more from the logs:

...
Processed 0 issues
Found 0 issues
Trigger: BINDING_UPDATE
[BINDING_UPDATE] 1 file(s) submitted
Configuring analysis with org.sonarlint.intellij.java.JavaAnalysisConfigurator
Using connection '<connection>' for project '<project>'
Analysing 'navigation.component.ts'...
Starting analysis with configuration:
[
  projectKey: <project>
  baseDir: D:\Workspaces\<project>
  extraProperties: {sonar.java.target=19, sonar.java.source=19}
  moduleKey: Module: '<project>'
  inputFiles: [
    file:///D:/Workspaces/<project>/src/app/.../navigation.component.ts (UTF-8)
  ]
]
...

Indeed, so this is purely on the analyzer side. I will ping my colleagues to give a hand here.

Maybe you could already share the content of your tsconfig.json, since it might be helpful to understand what is the meaning of:

D:/Workspaces/<project-name>/src/app/components/partials/navigation/navigation.component.ts matched NO_CONFIG

This is the content of my tsconfig.json:

{
  "compilerOptions": {
    "target": "es2020",
    "module": "es2020",
    "moduleResolution": "node",
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "esModuleInterop": true,
    "noImplicitAny": true,
    "resolveJsonModule": true,
    "isolatedModules": false,
    "suppressImplicitAnyIndexErrors": true,
    "lib": [
      "es2020",
      "dom",
      "dom.iterable"
    ],
    "typeRoots": [
      "node_modules/@types"
    ],
    "types": [
      "chai",
      "jquery",
      "mocha",
      "sinon",
      "node"
    ]
  },
  "files": [
    "src/main.ts"
  ],
  "include": [
    "src/environments/**.*",
    "node_modules/.../**/*"                            // <- several node_modules
  ],
  "exclude": []
}

I am not a web developer, but none of your include patterns are matching src/app/components/partials/navigation/navigation.component.ts

Is it normal?

Well, I included the src folder in the include section of the tsconfig.json file and I do see all issues from the SonarQube server. Thank you and sorry for the effort!

Just as a side note for other readers: the logs show again the part :

Analysis of unchanged files will not be skipped (current analysis requires all files to be analyzed)
Initializing linter "default" with max-statements-per-line,curly,no-commented-code,sonar-no-fallthrough,duplicates-in-character-class,no-inverted-boolean-check,file-uploads,sonar-no-misleading-character-class,arguments-order,no-same-argument-assert,no-unsafe-finally,prefer-while,unused-named-groups,single-character-alternation,nested-control-flow,sonar-max-lines-per-function,no-use-of-empty-return-value,session-regeneration,no-associative-arrays,no-weak-keys,no-useless-increment,weak-ssl,no-throw-literal,no-redundant-optional,post-message,constructor-for-side-effects,prefer-readonly,no-redeclare,no-globals-shadowing,bool-param-default,unverified-hostname,for-loop-increment-sign,no-return-await,no-nested-conditional,no-unnecessary-type-assertion,no-implicit-dependencies,insecure-jwt-token,no-dead-store,no-this-alias,prefer-const,prefer-type-guard,no-return-type-any,no-unused-function-argument,use-type-alias,no-in-misuse,no-parameter-reassignment,no-incorrect-string-concat,class-prototype,updated-loop-counter,concise-regex,stateful-regex,test-check-exception,no-extra-semi,max-switch-cases,no-undefined-argument,no-labels,cognitive-complexity,max-union-size,use-isnan,no-shadow,inverted-assertion-arguments,no-nested-template-literals,no-duplicate-in-composite,generator-without-yield,no-ignored-return,no-caller,no-redundant-parentheses,call-argument-line,no-unenclosed-multiline-block,no-redundant-boolean,prefer-immediate-return,prefer-promise-shorthand,no-template-curly-in-string,regex-complexity,no-empty-after-reluctant,assertions-in-tests,unused-import,empty-string-repetition,no-nested-assignment,index-of-compare-to-positive-number,file-name-differ-from-class,todo-tag,prefer-default-last,no-gratuitous-expressions,no-empty-pattern,sonar-no-invalid-regexp,anchor-precedence,fixme-tag,no-trailing-spaces,no-nested-incdec,non-existent-operator,new-operator-misuse,no-small-switch,no-for-in-iterable,prefer-for-of,default-param-last,xml-parser-xxe,no-global-this,no-array-delete,no-alphabetical-sort,consistent-type-assertions,adjacent-overload-signatures,cyclomatic-complexity,no-sequences,void-use,no-octal,comma-or-logical-or-case,label-position,conditional-indentation,existing-groups,semi,super-invocation,no-try-promise,sonar-no-control-regex,no-empty-alternatives,sonar-no-regex-spaces,prefer-regex-literals,no-same-line-conditional,no-empty-interface,no-identical-functions,no-element-overwrite,no-equals-in-for-termination,no-sparse-arrays,no-var,no-redundant-jump,no-duplicate-imports,no-unthrown-error,no-unnecessary-type-arguments,no-collection-size-mischeck,prefer-namespace-keyword,unverified-certificate,no-empty-collection,no-empty-group,quotes,eqeqeq,no-accessor-field-mismatch,no-unused-collection,no-invariant-returns,radix,no-case-label-in-switch,prefer-template,no-built-in-override,arguments-usage,destructuring-assignment-syntax,no-misleading-array-reverse,no-redundant-assignments,no-inconsistent-returns,no-all-duplicated-branches,no-identical-conditions,no-weak-cipher,no-delete-var,encryption-secure-mode,strings-comparison,no-useless-intersection,sonar-block-scoped-var,expression-complexity,no-empty-function,no-code-after-done,no-unsafe-negation,no-non-null-assertion,deprecation,misplaced-loop-counter,no-one-iteration-loop,no-multi-str,function-inside-loop,object-shorthand,no-inferrable-types,no-duplicated-branches,no-duplicate-string,disabled-timeout,bitwise-operators,class-name,array-constructor,sonar-max-lines,no-console,no-identical-expressions,no-unreachable,no-useless-catch,no-variable-usage-before-declaration,no-incomplete-assertions,chai-determinate-assertion,eol-last,variable-name,no-primitive-wrappers,no-exclusive-tests,no-self-assign,no-misused-new,no-invalid-await,no-function-declaration-in-block,no-empty,sonar-max-params,no-magic-numbers,no-unused-expressions
Resolving TSConfig files using './tsconfig.json' from property sonar.typescript.tsconfigPath
Using './tsconfig.json' to resolve TSConfig file(s)
Found 1 TSConfig file(s): [D:\Workspaces\<project-name>\.\tsconfig.json]
D:/Workspaces/<project-name>/src/app/components/partials/navigation/navigation.component.ts matched NO_CONFIG
Skipping 1 files with no tsconfig.json
1 source file to be analyzed
Skipped files: [uri=file:///D:/Workspaces/<project-name>/src/app/components/partials/navigation/navigation.component.ts]
1/1 source file has been analyzed
Hit the cache for 0 out of 0
Miss the cache for 0 out of 0

So I guess the NO_CONFIG part is not a possibility for incorrect working.

Another question is, why I must do this change, whereas the some code is analyzed fully on the SonarQube server?

Hello @Cloud9Clone,

in SonarLint, the JS/TS analyzer selects the project files resolving the tsconfig ‘files’ and ‘include’ attributes (including wildcard resolutions). Any dependency not explictly set will not be seen by the analyzer.

While in SonarQube, the analyzer will create a ts program from the tsconfig. This by itself makes that all dependencies are picked up by Typescript, and the analyzer is able to see them and analyze them as well, even if not explicitly listed in the tsconfig.

We are currently working on unifying SonarLint and SonarQube analysis, so you will see same behaviour in both.

Cheers,
Victor

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.