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.