Shell commands
This section explains how you can configure the Docker images of Qodana and the Qodana CLI tool. You can use both tools locally and in CI/CD pipelines. Several options are available in Qodana CLI only.
In several cases, you can configure them using the qodana.yaml
file, which is also mentioned in this section.
Starting from version 2022.3 of Qodana, the Ultimate and Ultimate Plus linters require the QODANA_TOKEN
variable to refer to the project token. If you run the Community linters of Qodana, using QODANA_TOKEN
is necessary only if you wish to view Qodana reports in Qodana Cloud.
Qodana CLI stores files in the <userCacheDir>
directory, which is mentioned several times throughout this section. Here is the list of <userCacheDir>
directory locations depending on the operating system:
Operating System | Path |
---|---|
macOS |
|
Linux |
|
Windows |
|
If you run the qodana init
command in the project directory, Qodana CLI will let you choose the linter that will be run during inspection, and save the choice in qodana.yaml
. Once done, you do not need to specify the linter in the commands, which is shown throughout this section.
The detailed description of the qodana init
command is available in the Project configuration section.
This table lists the paths available in Docker images and Qodana CLI:
Path | Description |
---|---|
| Root directory of the project |
| Directory to store the analysis results. It should be empty before running Qodana |
| IDE distributive directory |
| IDE configuration directory |
| Directory for binding profile files |
| Maven project dependencies |
| Gradle project dependencies |
| NuGet project dependencies |
| Directory containing plugins |
| Directory for mapping code coverage files |
Below you can find several examples of how these paths can be applied.
In case of JVM linters, you can override the default Gradle settings:
$docker run \ -v $(pwd):/data/project/ \ -v $(pwd)/gradle.properties:/data/cache/gradle/gradle.properties \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter>
$qodana scan \ -v $(pwd)/gradle.properties:/data/cache/gradle/gradle.properties \ -e QODANA_TOKEN="<cloud-project-token>"
note
This feature is not available in the Qodana for .NET linter.
You can automatically download the required plugins from JetBrains Marketplace and use them in your CI/CD pipelines. For example, this shell script will download the Twig plugin:
IDE_CODE=PS
PLUGIN_ID="com.jetbrains.twig"
BUILD_ID="231.7515"
curl -L -o "$PLUGIN_ID".zip "https://plugins.jetbrains.com/pluginManager?action=download&id=$PLUGIN_ID&build=$IDE_CODE-$BUILD_ID" && unzip "$PLUGIN_ID".zip
This script contains several variables explained in the table below.
Variable | Description | Example |
---|---|---|
| The two-character code of the linter that the plugin should be downloaded for. The available values are:
|
|
| Plugin identifier from a plugin page available on JetBrains Marketplace |
|
| Build ID of Qodana available in Qodana logs |
|
You can run Qodana with the plugin file mounted to the plugin directory:
$docker run \ -v $(pwd):/data/project/ \ -v <path-to-plugin>/<plugin-name>:/opt/idea/plugins/<plugin-name> \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter>
$qodana scan \ -v <path-to-plugin>/<plugin-name>:/opt/idea/plugins/<plugin-name> \ -e QODANA_TOKEN="<cloud-project-token>"
Depending on the tool, you can view log files generated by Qodana:
You can mount the $(pwd)/.qodana/results/
directory to the /data/results
directory of the Docker image:
$docker run \ -v $(pwd):/data/project/ \ -v $(pwd)/.qodana/results/:/data/results \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter>
Once the Qodana run is complete, you can view log files in the $(pwd)/.qodana/results/
directory.
After running Qodana, in the project root run the qodana show -d
command for opening the directory containing log files.
Docker images can be configured using several CLI options. All these options can be divided into three groups.
Option type | Example |
---|---|
Requires the equal sign ( |
|
Requires the space character ( |
|
Requires no argument |
|
Here is the example command that invokes all these options:
$docker run \ -p 8080:8080 \ -v $(pwd):/data/project/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --property=idea.log.config.file=info.xml \ --baseline <baseline-path> \ --show-report
$qodana scan \ -e QODANA_TOKEN="<cloud-project-token>" \ --property=idea.log.config.file=info.xml \ --baseline <baseline-path> \ --show-report
To see the available options, you can use this command:
$docker run jetbrains/qodana-<linter> -h
$qodana scan -h
Using these options, you can override the paths described in the Docker image paths section.
Option | Default setting | |
---|---|---|
| Root directory of the inspected project. Files and directories contained in the outside directory are not used while running Qodana |
|
| Directory to save Qodana inspection results to |
|
| Directory for saving the generated HTML report. To open the report, you will need to add the
|
|
| Directory to store cache |
|
| Directory inside Files and directories contained in the outside directory like | None |
tip
During inspection, Qodana CLI automatically saves inspection reports in the
./<userCacheDir>/JetBrains/Qodana/<linter>/<project-id>/results/report
directory.Here, the
linter
andproject-id
directories have the hash format.
This Docker command overrides the default report directory using the --report-dir
option, and saves the generated report to the local filesystem using the --save-report
option:
$docker run \ -v $(pwd):/data/project/ \ -v <html-report-directory>:/data/results/newreportdir/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --report-dir /data/results/newreportdir/ \ --save-report
The generated report is saved to the local filesystem as per the -v <html-report-directory>:/data/results/newreportdir/
line in this command.
tip
Qodana CLI automatically manages cache and requires no action.
After the first run, Qodana CLI stores cache in the
./<userCacheDir>/JetBrains/<linter>/cache
directory.
You can improve Qodana performance by persisting cache between runs. For example, package and dependency management tools such as Maven, Gradle, npm, Yarn, and NuGet keep a local cache of downloaded dependencies.
By default, Qodana save caches to the /data/cache
directory inside a container. You can override this location using the --cache-dir
option. This data is per-repository, so you can pass cache from branch-a
to build checking branch-b
. In this case, only new dependencies would be downloaded if they were added.
This command maps the local directory with the /data/cache
directory of the Docker image, which saves cache to your local filesystem:
$docker run \ -v $(pwd):/data/project/ \ -v <local-cache-directory>:/data/cache/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter>
Using the --cache-dir
option, you can override the cache directory:
$docker run \ -v $(pwd):/data/project/ \ -v <local-cache-directory>:/data/newcachedir/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --cache-dir /data/newcachedir
$qodana scan \ -e QODANA_TOKEN="<cloud-project-token>" \ --cache-dir /opt/newcachedir
In a GitHub workflow, you can use dependency caching. GitLab CI/CD also has the cache that can be stored only inside the project directory. In this case, you can exclude the cache directory from inspection via qodana.yaml
.
By default, Qodana inspects your code using the qodana.starter
profile.
You can configure and override Qodana profiles either in the qodana.yaml
file, or using the CLI options from this table.
Option | Description | Default setting |
---|---|---|
| Skip running the inspections configured by the | Enabled |
| The profile name taken either from the list of predefined Qodana profiles, or a custom profile name stored in XML-formatted profile files as You can also configure this option using the |
|
| The absolute path to the profile file. You can also configure this option using the | None |
| Run promo inspections as a part of the
| Enabled only if Qodana is configured for the |
The --profile-name
option lets you run Qodana using either the default profiles or the profile name from a custom profile.
tip
You can also configure this option using the
qodana.yaml
file.
This command lets you override the default profile und run Qodana using the qodana.recommended
profile:
$docker run \ -v $(pwd):/data/project/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --profile-name qodana.recommended
$qodana scan \ -e QODANA_TOKEN="<cloud-project-token>" \ --profile-name qodana.recommended
To run Qodana with a custom profile, use its actual profile name.
This command lets you bind a custom profile:
$docker run \ -v $(pwd):/data/project/ \ -v <path-to-profile-file>/<file-name>:/data/project/.idea/inspectionProfiles/<file-name> \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --profile-name <profile-name-from-file>
$qodana scan \ -v <path-to-profile-file>/<file-name>:/data/project/.idea/inspectionProfiles/<file-name> \ -e QODANA_TOKEN="<cloud-project-token>" \ --profile-name <profile-name-from-file>
The --profile-path
option lets you override the path to the file containing the profile.
tip
You can also configure this option using the
qodana.yaml
file.
This command lets you bind the file to the profile directory, and the --profile-path
option tells Qodana which profile file to read:
$docker run \ -v $(pwd):/data/project/ \ -v <path-to-profile-file>/<file-name>:/data/project/myprofiles/<file-name> \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --profile-path /data/project/myprofiles/<file-name>
$qodana scan \ -v <path-to-profile-file>/<file-name>:/data/project/myprofiles/<file-name> \ -e QODANA_TOKEN="<cloud-project-token>" \ --profile-path /data/project/myprofiles/<file-name>
Your project can have several Qodana configurations contained in YAML-formatted files. This comes in handy if you analyze monorepo projects or run a single CI job.
You can use the --config
option and a path to a file relatively to the project root:
$docker run \ -v $(pwd):/data/project \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --config relative/path/to/config.yaml
$qodana scan \ -e QODANA_TOKEN="<cloud-project-token>" \ --config relative/path/to/config.yaml
In the baseline run mode, each new Qodana run is compared to some initial run. This can help in situations when you have no possibility to fix old problems and rather want to prevent the appearance of new ones.
To use the baseline feature, first run Qodana, and in the report UI select the problems that will be considered as baseline. Finally, save the SARIF-formatted file containing the baseline problems.
This is the list of baseline-related options:
Option | Description |
---|---|
| Run Qodana in the baseline mode. Provide the path to an existing SARIF report to be used in the baseline state calculation |
| Include in the output report the results from the baseline run that are absent in the current run |
This is the command that invoke all baseline options:
$docker run \ -v $(pwd):/data/project/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --baseline <path-to-the-SARIF-file> \ --baseline-include-absent
$qodana scan \ -e QODANA_TOKEN="<cloud-project-token>" \ --baseline <path-to-the-SARIF-file> \ --baseline-include-absent
Here, the <path-to-the-SARIF-file>
is the path to a qodana.sarif.json
file relative to the project root and taken from a previous Qodana run. If --baseline-include-absent
is invoked, the inspection results will include absent problems or the problems detected only in the baseline run but not in the current run.
Based on this run, the SARIF output report will contain the per-problem information on the baseline state.
note
For the Qodana for Go linter, the code coverage requires that a project contains no
.idea
directory.
You can run the code coverage by mapping the directory containing code coverage files to the /data/coverage
directory of a Qodana linter image:
$docker run \ -v /my/dir/with/coverage:/data/coverage \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter>
$qodana scan \ -v /my/dir/with/coverage:/data/coverage \ -e QODANA_TOKEN="<cloud-project-token>"
This table contains the options related to reports:
Option | Description |
---|---|
| Generate and save HTML-formatted reports |
| Serve HTML-formatted reports. By default, port |
tip
During inspection, Qodana CLI automatically saves inspection reports in the
./<userCacheDir>/JetBrains/Qodana/<linter>/<project-id>/results/report
directory.Here, the
linter
andproject-id
directories have the hash format.To view the generated report in your browser, in the project root run the
qodana show
command.
The --save-report
option in the Docker command lets you save the generated HTML report to your local filesystem:
$docker run \ -v $(pwd):/data/project/ \ -v <directory-to-save-report-to>:/data/results/report \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --save-report
This command runs the web server on port 4040 of a host machine, so your report will be available on http://localhost:4040:
$docker run \ -p 4040:8080 \ -v $(pwd):/data/project/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --show-report
$qodana scan \ -e QODANA_TOKEN="<cloud-project-token>" \ --port 4040 \ --show-report
Alternatively, in the project root you can run the qodana show
command.
To stop the web server, press Ctrl-C in the Docker console.
Qodana lets you configure a quality gate or the number of problems that will act as a threshold. Once the threshold is exceeded, the inspection run is terminated.
tip
You can specify the threshold as explained in the Set a quality gate section. However, the Docker command option overrides the settings in the
qodana.yaml
file.
Option | Description |
---|---|
| Set the number of problems that will serve as a quality gate |
Here is the command that tells Qodana to fail the build in case the number of problems exceeds 10:
$docker run \ -v $(pwd):/data/project/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --fail-threshold 10
$qodana scan \ -e QODANA_TOKEN="<cloud-project-token>" \ --fail-threshold 10
If you run Qodana with the baseline mode enabled, a threshold is calculated as the sum of new and absent problems. The unchanged results are ignored.
To apply quick-fix strategies to your codebase, you can invoke the --fixes-strategy
option.
$docker run \ -v <source-directory>/:/data/project/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --fixes-strategy <cleanup/apply>
$qodana scan \ -e QODANA_TOKEN="<cloud-project-token>" \ <--apply-fixes/--cleanup>
Using the --property=
option, you can override various Qodana parameters:
Option | Description |
---|---|
| Set a JVM property using this notation:
This option can be repeated multiple times for setting multiple JVM properties. |
note
This feature is not available in the Qodana for .NET linter.
The default log level for STDOUT is WARN
. You can override it using the idea.log.config.file
property.
$docker run \ -v $(pwd):/data/project/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --property=idea.log.config.file=info.xml
$qodana scan \ -e QODANA_TOKEN="<cloud-project-token>" \ --property=idea.log.config.file=info.xml
To disable reporting of usage statistics, adjust the idea.headless.enable.statistics
value of the --property
option:
$docker run \ -v $(pwd):/data/project/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --property=idea.headless.enable.statistics=false
$qodana scan \ -e QODANA_TOKEN="<cloud-project-token>" \ --property=idea.headless.enable.statistics=false
Using the idea.required.plugins.id
and idea.suppressed.plugins.id
properties, you can specify the plugins required for a specific run, and the list of plugins that will be suppressed:
$docker run \ -v $(pwd):/data/project/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --property=idea.required.plugins.id=JavaScript,org.intellij.grails \ --property=idea.suppressed.plugins.id=com.intellij.spring.security
$qodana scan \ -e QODANA_TOKEN="<cloud-project-token>" \ --property=idea.required.plugins.id=JavaScript,org.intellij.grails \ --property=idea.suppressed.plugins.id=com.intellij.spring.security
note
This feature is not supported by the Qodana Community for .NET linter.
Option | Description |
---|---|
| Run incremental analysis on a change set, for example merge or pull requests |
If you just finished work and would like to analyze the changes, you can employ the --diff-start
option and specify a hash of the commit that will act as a base for comparison:
$docker run \ -v $(pwd):/data/project/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --diff-start=<GIT_START_HASH>
$qodana scan \ -e QODANA_TOKEN="<cloud-project-token>" \ --diff-start=<GIT_START_HASH>
To analyze a set of changes between two commits, employ both --diff-start
and --diff-end
options:
$docker run \ -v $(pwd):/data/project/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --diff-start=<GIT_START_HASH> \ --diff-end=<GIT_END_HASH>
$qodana scan \ -e QODANA_TOKEN="<cloud-project-token>" \ --diff-start=<GIT_START_HASH> \ --diff-end=<GIT_END_HASH>
Option | Description | Default setting |
---|---|---|
| Override the default run scenario |
|
tip
You can also configure this option using the
qodana.yaml
file.
Application of the default
run scenario is equivalent to running this command:
$docker run \ -v $(pwd):/data/project/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --script default
$qodana scan \ -e QODANA_TOKEN="<cloud-project-token>" \ --script default
To run the PHP version migration scenario, you can run this command:
$docker run \ -v $(pwd):/data/project/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter> \ --script php-migration:<old-php-version>−to−<upgraded-php-version>
$qodana scan \ -e QODANA_TOKEN="<cloud-project-token>" \ --script php-migration:<old-php-version>−to−<upgraded-php-version>
To forward reports to Qodana Cloud, you can set the list of Docker environments as explained in the Forward reports section.
By default, the Heap size is set to 80% of the host RAM. You can configure this setting using the _JAVA_OPTIONS
variable:
$docker run \ -v $(pwd):/data/project/ \ -e _JAVA_OPTIONS=-Xmx6g \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter>
$qodana scan \ -e _JAVA_OPTIONS=-Xmx6g \ -e QODANA_TOKEN="<cloud-project-token>"
To learn more about configuring the Heap, see the Heap Tuning Parameters of the Oracle documentation.
note
This feature is not available in the Qodana for .NET linter.
The idea.properties
configures the default locations of the IDE files.
You can override the idea.properties
file using the IDEA_PROPERTIES
variable:
$docker run \ -v $(pwd):/data/project/ \ -e IDEA_PROPERTIES=/data/project/idea.properties \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter>
$qodana scan \ -e IDEA_PROPERTIES=/data/project/idea.properties \ -e QODANA_TOKEN="<cloud-project-token>"
tip
You can build your own Docker image with the required dependencies using our Dockerfile.
By default, a Docker container runs under the root
user, so Qodana can read project information and write inspection results. Therefore, all files in the results/
directory are owned by the root
user after the run.
To overcome this, you can run the container as a regular user:
$docker run \ -u $(id -u):$(id -g) \ -v $(pwd):/data/project/ \ -v <results-directory>:/data/results/ \ -e QODANA_TOKEN="<cloud-project-token>" \ jetbrains/qodana-<linter>
In this case, the results/
directory on host should already be created and owned by you. Otherwise, Docker will create it as the root
user, and Qodana will not be able to write to it.
TeamCity and Qodana CLI run Qodana using a current non-root user. This can be inconvenient if you wish to install dependencies using the apt
tool invoked in the bootstrap
section.
To run Qodana as a root user in TeamCity, in the Additional Docker arguments field of the Qodana runner configuration add the -u root
option.
To run Qodana CLI as a root user, you can append -u root
option to the qodana scan
command:
$qodana scan -u root
You can use these options with the qodana init <options>
command:
Option | Description |
---|---|
| Force initialization (overwrite the existing valid |
| Help for the |
| Root directory of the project to configure (default is |
You can use these options with the qodana scan <options>
command:
Option | Description |
---|---|
|
Choose linter (image) to use. Available images are: |
| Use to run Qodana without a container. Path to the installed IDE, or a downloaded one: provide direct URL or a product code. Not compatible with the |
| Root directory of the inspected project (default |
| Override directory to save Qodana inspection results to (default <userCacheDir>/JetBrains/Qodana/<linter>/results) |
| Override cache directory (default <userCacheDir>/JetBrains/Qodana/<linter>/cache) |
| Override directory to save Qodana HTML report to (default <userCacheDir>/JetBrains/<linter>/results/report) |
| Print all found problems by Qodana in the CLI output |
| Clear the local Qodana cache before running the analysis |
| Serve an HTML report on a specific port |
| Port to serve the report on (default 8080) |
| Override qodana.yaml name to use: |
| Unique report identifier (GUID) to be used by Qodana Cloud (default "<generated value>") |
| Provide the path to an existing SARIF report to be used in the baseline state calculation |
| Include in the output report the results from the baseline run that are absent in the current run |
| Go through the full commit history and run the analysis on each commit. If combined with |
| Set the number of problems that will serve as a quality gate. If this number is reached, the inspection run is terminated with a non-zero exit code |
| Skip running the inspections configured by the sanity profile |
| Directory inside the project-dir directory must be inspected. If not specified, the whole project is inspected |
| Profile name defined in the project |
| Path to the profile file |
| Set to |
| Override the run scenario (default |
| Absolute path to the fallback profile file. This option is applied in case the profile was not specified using any available options |
| Apply all available quick-fixes, including cleanup |
| Run project cleanup |
| Set a JVM property to be used while running Qodana using the |
| Generate HTML report (default true) |
|
Define additional environment variables for the Qodana container (you can use the flag multiple times). CLI is not reading full host environment variables and does not pass it to the Qodana container for security reasons |
|
Define additional volumes for the Qodana container (you can use the flag multiple times) |
|
User to run Qodana container as. Please specify user id – |
|
Skip pulling the latest Qodana container |
| Generate a Code Quality report supported by GitLab CI/CD. |
| Generate a Code Insights report supported by Bitbucket Cloud and forward it using the Bitbucket Code Insights API. |
| Help for the |
You can use these options with the qodana show <options>
command:
Option | Description |
---|---|
| Open report directory only |
| Help for the |
| Override linter to use |
| Specify the port to serve a report at (default 8080) |
| Root directory of the inspected project (default ".") |
| Specify the HTML report path (the one with |
You can run the qodana view <options>
command using these options:
Option | Description | Default setting |
---|---|---|
| Path to the SARIF-formatted file |
|
| Help for the | None |
The contributor counting mechanism is described in the Contributor counting section.
To count contributors using Qodana CLI, you can run the qodana contributors <options>
command with the following options:
Option | Description | Default setting |
---|---|---|
| Number of days to calculate the number of active contributors for | 30 |
| Help for the | None |
| Root directory of the project to configure |
|
Using the qodana cloc <options>
command, you can view information about your project, such as languages and lines of code. Here is the list of available options for this command:
Option | Description |
---|---|
| The output format that accepts the |
| Help for the |
| The project directory. This option can be specified multiple times to check multiple projects. If not specified, the current directory will be used |
Qodana checks the configuration parameters for resolving the inspection profile in this order:
Profile with the name
%name%
from the command-line option--profile-name %name%
Profile by the path
%path%
from the command-line option--profile-path %path%
Profile with the name
%name%
fromqodana.yaml
Profile by the path
%path%
fromqodana.yaml
Fall back to using the default
qodana.recommended
profile
Thanks for your feedback!