[![GitLab License](https://img.shields.io/gitlab/license/woshilapin%2Fcargo-sonar?style=flat)](https://opensource.org/license/MIT)
[![GitLab Release](https://img.shields.io/gitlab/v/release/woshilapin%2Fcargo-sonar?style=flat&logo=Gitlab)](https://gitlab.com/woshilapin/cargo-sonar/-/releases)
[![Crates.io Version](https://img.shields.io/crates/v/cargo-sonar?style=flat&logo=Rust)](https://crates.io/crates/cargo-sonar)
[![Docker Image Version](https://img.shields.io/docker/v/woshilapin/cargo-sonar?sort=semver&style=flat&logo=Docker)](https://hub.docker.com/r/woshilapin/cargo-sonar)
[![docs.rs](https://img.shields.io/docsrs/cargo-sonar?style=flat&logo=docs.rs)](https://docs.rs/cargo-sonar/latest/cargo_sonar/)
[![Gitlab Pipeline Status](https://img.shields.io/gitlab/pipeline-status/woshilapin%2Fcargo-sonar?style=flat&logo=Gitlab)](https://gitlab.com/woshilapin/cargo-sonar/-/pipelines)
[![Sonar Violations](https://img.shields.io/sonar/violations/woshilapin_cargo-sonar?server=https%3A%2F%2Fsonarcloud.io&format=long&style=flat&logo=SonarCloud)](https://sonarcloud.io/project/overview?id=woshilapin_cargo-sonar)

# `cargo-sonar` and `cargo-codeclimate`

`cargo-sonar` help you to use the tools of the Rust community and report the
information to Sonarcloud (or Sonarqube).

> [!note]
> Since April 2025, SonarQube supports Rust out-of-the-box (see the
> [announcement](https://community.sonarsource.com/t/sonarqube-now-supports-rust/138933?utm_source=beamer&utm_medium=sidebar&utm_campaign=New-Support-for-Rust&utm_content=ctalink)).
> This is great news because it means a good and homogeneous integration of some
> `clippy` lints into Sonar ecosystem. However, it is not yet a full replacement
> for `cargo-sonar` because `cargo-sonar` supports more than just `clippy`.

`cargo-codeclimate` help you in the same way providing a CodeClimate output
format. Note that Gitlab does also understand CodeClimate format.

You can even set it up in a Continuous Integration so this report is
automatically forwarded to Sonar, CodeClimate or Gitlab.

Note that this project was first created for `cargo-sonar`. Therefore, most of
the things are documented around `cargo-sonar`, but `cargo-codeclimate` as the
exact same CLI API (only the output format is different). Note also that `cargo-
codeclimate` is still part of `cargo-sonar` crate and docker images. So if you
installed `cargo-sonar`, you did also installed `cargo-codeclimate`.

# Table of contents
- [Installation](#installation)
  - [From binary](#from-binary)
  - [From Docker/Podman](#from-dockerpodman)
  - [From crates.io](#from-cratesio)
  - [From source](#from-source)
- [Use](#use)
- [Supported tools](#supported-tools)
  - [`cargo-clippy`](#cargo-clippy)
  - [`cargo-audit`](#cargo-audit)
  - [`cargo-deny`](#cargo-deny)
  - [`cargo-outdated`](#cargo-outdated)
  - [`cargo-udeps`](#cargo-udeps)
- [Examples](#examples)
- [Release](#release)
  - [Tagging](#tagging)
  - [Package on crates.io](#package-on-cratesio)
  - [Docker image](#docker-image)
- [Alternatives](#alternatives)
  - [`cargo-sarif`](#cargo-sarif)
- [Todo list](#todo-list)

# Installation
## From binary

If you use [`cargo-binstall`](https://github.com/cargo-bins/cargo-binstall),
you can install `cargo-sonar` with the following.

```
cargo binstall cargo-sonar
cargo sonar --help
```

You can also download the binary directly from the
[release page](https://gitlab.com/woshilapin/cargo-sonar/-/releases).

## From Docker/Podman

The OCI images are hosted on the Gitlab container registry of the project.

```
export CONTAINER_ENGINE=docker # or CONTAINER_ENGINE=podman
${CONTAINER_ENGINE} pull registry.gitlab.com/woshilapin/cargo-sonar
${CONTAINER_ENGINE} run registry.gitlab.com/woshilapin/cargo-sonar --help
```

If you prefer DockerHub, you can also pull them from DockerHub.

```
export CONTAINER_ENGINE=docker # or CONTAINER_ENGINE=podman
${CONTAINER_ENGINE} pull docker.io/woshilapin/cargo-sonar
${CONTAINER_ENGINE} run docker.io/woshilapin/cargo-sonar --help
```

By default, the working directory in the container is `/tmp`.

Note that if you want to use `cargo-codeclimate`, you will need to change the
entrypoint with `--entrypoint '/cargo-codeclimate`.

## From crates.io

```
cargo install cargo-sonar
cargo sonar --help
```

## From source

```
git clone https://gitlab.com/woshilapin/cargo-sonar.git
cd cargo-sonar/
cargo install -- path .
cargo sonar --help
```

# Use

`cargo-sonar` is only a tool to convert reports from other tools into Sonar
compatible report (see [Supported tools](#supported-tools)). Once the Sonar
report is generated, it can be sent to [sonarcloud.io](https://sonarcloud.io)
or any [SonarQube](https://www.sonarqube.org/) instance with
[`sonar-scanner`](https://docs.sonarqube.org/latest/analysis/scan/sonarscanner/).

First generate a report from any [supported tool](#supported-tools), for example
`clippy`.

```
cargo clippy --message-format=json > my-clippy-report.json
```

Then convert this report.

```
cargo sonar --clippy --clippy-path my-clippy-report.json
```

This creates a file `sonar-issues.json`. You can now configure `sonar-scanner`
with `sonar.externalIssuesReportPaths=sonar-issues.json` in your `sonar-
project.properties` file.

# Supported tools
## `cargo-clippy`

```
cargo clippy --message-format=json > clippy.json
```

> [!caution]
> `clippy` may report the duplicate errors. Usually, `cargo
> clippy` will remove the duplicate automatically... except
> when using `--message-format=json`. You can use [`cargo
> deduplicate-warnings`](https://crates.io/crates/cargo-deduplicate-warnings) to
> trim the JSON output.
> ```
> cargo clippy --message-format json | cargo deduplicate-warnings | my-clippy-report.json
> ```

## `cargo-audit`

```
cargo audit --json > audit.json
```

## `cargo-deny`

```
cargo deny --format json check 2> deny.json
```

Note that only `advisories` and `licenses` are supported at the moment.

## `cargo-outdated`

```
cargo outdated --workspace --depth 1 --format json > outdated.json
```

`--depth 1` is useful here since the conversion will not work on any dependency
of greater depth.

## `cargo-udeps`

```
cargo +nightly udeps --quiet --workspace --all-features --all-targets --output json > udeps.json
```

# Examples

The best example out there at the moment is the project `cargo-sonar` itself. In
the CI, take a look at 
[`.gitlab-ci.yml`](https://gitlab.com/woshilapin/cargo-sonar/-/blob/main/.gitlab-ci.yml)
and especially the use of `cargo sonar` in
[executed](https://gitlab.com/woshilapin/cargo-sonar/-/blob/main/.gitlab/cargo-sonar.yml)
followed by the use of `sonar-scanner` configured with
[`sonar-project.properties` configuration file](https://gitlab.com/woshilapin/cargo-sonar/-/blob/main/sonar-project.properties).
The final result can be seen on
[sonarcloud.io](https://sonarcloud.io/project/overview?id=woshilapin_cargo-sonar).

# Release

All the release process is automated: each time you push a commit on `main`
branch, the next version is automatically deduce from the
[conventional commit standard](https://www.conventionalcommits.org/en/v1.0.0/)
since last tag.

You can find the release in different places and forms:
- [crates.io](https://crates.io/crates/cargo-sonar)
- [Docker container](https://hub.docker.com/r/woshilapin/cargo-sonar)
- [Binary](https://gitlab.com/woshilapin/cargo-sonar/-/releases)

Sometimes, the CI might get into a problem. If you need to switch to manual
release, here are the steps. Below, `1.2.3` is used as an example, please
replace with the correct version.

## Tagging

```
cog bump --auto
```

## Package on crates.io

```
git checkout 1.2.3
cargo publish
```

## Docker image

```
git checkout 1.2.3
buildah bud --layers --tag woshilapin/cargo-sonar:1.2.3
buildah push woshilapin/cargo-sonar:1.2.3
```

# Alternatives
## `cargo-sarif`

[`SARIF`](https://sarifweb.azurewebsites.net/) stands for Static
Analysis Results Interchange Format. It's typically a standard format
to express what a tool like `clippy` would report. [Sonar can consume
SARIF](https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/importing-external-issues/importing-issues-from-sarif-reports/).

[`cargo-sarif`](https://psastras.github.io/sarif-rs/) is a similar tool to
`cargo-sonar`, which takes the output of `cargo clippy` to generate SARIF
format. For the moment, `cargo-sonar` doesn't rely on a standard format
of exchange, but directly talks to Sonar or CodeClimate. However, both
`cargo-sonar` and `cargo-sarif` also consumes from other tools than `clippy`,
each providing support for different kind of tools (see above for the one
supported in `cargo-sonar`).

# Todo list

- [ ] add `cargo-geiger` parsing
- [ ] create a Github Action (see [Docker Github Action](https://docs.github.com/en/actions/creating-actions/creating-a-docker-container-action))
