`cargo-sonar`

Announcing cargo-sonar

For a few days, I’ve been working on a small project called cargo-sonar and now is the time to make it public.

Why?

Sonar [1] is a great tool for managing the quality of your software. Although, you might disagree if you’ve been using it 10 years ago!

However, our beloved language Rust has not been supported by Sonar (although there have been discussion about it).

In a company, Sonar is a great tool for centralizing all metrics about code quality. So not having Rust’s support is another reason a company could rule out Rust as a technical solution (a small one but still a valid one).

The community already provided a great plugin for SonarQube called sonar-rust. Even if the maintenance of the code has not been very active in the last few months, the plugin just works fine. But there is one trick, it has to be installed server-side. If you want to manage your own in-house instance of Sonar, that’s the go-to solution. But sonarcloud.io who provides hosted instances of Sonar doesn’t allow custom plugins to be installed. So how do we do it?

How?

Well, Sonar actually have an API to provide generic issues. How about we use the output from clippy, transform it into this generic issue format, then send it to Sonar? That’s exactly what cargo-sonar is made for…​ and a bit more.

Setting up cargo-sonar

The best example of a working setup of cargo-sonar is probably the cargo-sonar project itself. You can see the result on sonarcloud.io directly. But let me show you the big lines as a starter.

Generate clippy output

First of all, you’ll have to generate clippy output in JSON format. You can even activate clippy::pedantic in this case to have maximum feedback.

cargo clippy --all-features --all-targets --message-format=json -- --warn clippy::pedantic > clippy.json

Convert into Sonar generic issues

Here is where cargo-sonar do its work.

cargo install cargo-sonar
cargo sonar --clippy

This is going to produce a file sonar.json from the clippy.json file [2].

Push the generic issues to sonarcloud.io

You’ll need an account on sonarcloud.io and a existing project. To push the generic issues, we’re going to use sonar-scanner.

Once you’ve installed sonar-scanner, you’ll have to create a sonar-project.properties file. I’ll take cargo-sonar as an example.

sonar.organization=woshilapin
sonar.projectKey=woshilapin_cargo-sonar
sonar.projectName=cargo-sonar
sonar.sources=.
sonar.host.url=https://sonarcloud.io
sonar.sourceEncoding=UTF-8
sonar.externalIssuesReportPaths=sonar.json
sonar.login=the_token_of_the_project

Do not forget to replace the sonar.login property with your project’s token. Did you see the sonar.externalIssuesReportPaths property refering to our sonar.json file. Now, you can just run sonar-scanner and go see on sonarcloud.io the result.

What’s more?

Well, clippy is nice but we have tons of tools in the Rust ecosystem. How about seing CVE in Sonar? How about outdated dependencies? Or licenses incompatibilities?

With the same logic, I’ve been implementing conversion into generic issues for the following tools.

cargo-audit

cargo audit --json > audit.json
cargo sonar --audit

cargo-deny

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

cargo-outdated

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

What’s next

The project is pretty young. Not a lot of tests, the documentation can definitely be better, the code is made of huge functions and could probably have a better architecture…​ but it works. I’m hoping for some feedbacks to better focus on the next steps. You can post on issues, or on forums like URLO or Sonar, I’m woshilapin on both of them.


1. I’m going to refer to Sonar for both SonarQube and Sonarcloud
2. You can change the filename of the clippy’s output with `--clippy-path.

links

social