rsonar en pratique

Mesurer simplement la qualite de code R

Damien Dotta

rsonar, c’est quoi ?

rsonar mesure la qualite de code R, inspire de SonarQube :

  • Analyse statique (lintr)
  • Style de code (styler)
  • Couverture de tests (covr)
  • Bonnes pratiques package (goodpractice)
  • Dette technique + Quality Gate

Pourquoi c’est utile ?

Une seule commande, tout est centralise :

  • Resume console
  • Rapport HTML
  • Score qualite en %
  • Exports pour la CI (JUnit, SARIF, JSON)

Demo : depot rsonar-examples

  • Code propre : R/clean_code.R
  • Code volontairement sale : R/messy_code.R
  • Tests partiels
  • Workflows CI pre-configures

Exemple de code problematique

messy_function <- function(x,y) {
  res=x+y
  vlong <- ifelse(res > 0, T, F)
  output = list(sum=res, positive=vlong)
  return(output)
}

Problemes : espaces, T/F, affectations =, style non conforme.

1) Analyse complete

library(rsonar)
res <- sonar_analyse(".")
print(res)

Un seul objet contient : lint, style, couverture, bonnes pratiques, dette.

Sortie console

-- rsonar -- Quality Report --
  Fichiers : 12 R
  Lint     : 8 (0 err / 4 warn / 4 style)
  Style    : 1 non-conforme
  Coverage : 42.3%

-- Dette Technique --
  SQALE: E | Score: 37.8% | Duree: 3.1h

2) Score qualite rapide (IDE)

quality_score(".")

Avant un commit, pendant une revue, pour suivre l’amelioration.

3) Rapport HTML

sonar_report(res, output = "quality.html")

Affiche : score %, note SQALE, couverture, lint/style, dette detaillee.

4) Bloquer les regressions (Quality Gate)

quality_gate(res,
  coverage_min    = 80,
  lint_errors_max = 0,
  rating_min      = "C",
  fail_on_error   = TRUE)

Si le gate echoue, le pipeline CI bloque automatiquement.

La note SQALE

Estime un temps de correction (minutes) vs effort du projet.

Ratio Note Signification
<5% A Excellent
5-10% B Bon
10-20% C Correct
20-50% D Dette importante
>50% E Dette critique

5) Exports CI

export_junit(res, "junit-results.xml")      # GitLab/Jenkins
export_sarif(res, "results.sarif")          # GitHub Code Scanning
export_sonar_json(res, "sonar-issues.json") # SonarQube

6) Auto-fix avec sonar_fix()

16 familles de corrections — 12 appliquees, 4 en rapport :

Categorie Exemple
styler / air Formatage complet
spacing x<-1x <- 1
true_false if(T)if(TRUE)
commas c(1,2,3)c(1, 2, 3)
simplify if(x==TRUE)if(x)
pipes %>%|>
assignment =<-
cleanup Espaces fin de ligne

Utilisation

# Apercu (dry-run)
fix <- sonar_fix(".", dry_run = TRUE)

# Appliquer toutes les corrections
fix <- sonar_fix(".", dry_run = FALSE)

# Avec air (plus rapide)
install_air()
fix <- sonar_fix(".", formatter = "air")

7) Workflow complet : sonar_autofix()

Une fonction pour tout le processus :

sonar_autofix(provider = "gitlab")   # Analyse + commit + push + MR
sonar_autofix(provider = "github")   # Analyse + commit + push + PR
sonar_autofix()                      # Auto-detection de la plateforme

Pipeline CI

stages: [quality, autofix]

rsonar-check:
  stage: quality
  script: R -e "sonar_analyse('.'); export_junit()"

rsonar-autofix:
  stage: autofix
  when: manual
  script: R -e "sonar_autofix(provider='gitlab', verbose=TRUE)"

Installation : token GitLab (etape 1)

Settings > Access Tokens > Create token

Champ Valeur
Token name rsonar-fix
Role Maintainer
Scopes write_repository

📋 Copier immediatement la valeur du token.

Format : glpat-xxxxxxxxxxxxxxxxxxxx

Installation : PROJECT_TOKEN (etape 2)

Settings > CI/CD > Variables > Add variable

Champ Valeur
Key PROJECT_TOKEN
Value Coller le token de l’etape 1
Flags ✅ Masquee

Le job CI utilise ce token via oauth2 : https://oauth2:${PROJECT_TOKEN}@...

Installation : autoriser les branches (etape 3)

Settings > Repository > Protected branches > Add

Champ Valeur
Branch auto/rsonar-fix-*
Push Maintainers

Le wildcard * accepte : auto/rsonar-fix-20260728-091500

Recapitulatif

Etape 1 : Creer un token (scope write_repository)
   |
Etape 2 : Ajouter PROJECT_TOKEN en variables CI/CD
   |
Etape 3 : Autoriser le pattern auto/rsonar-fix-* (Maintainers)

Termine ! Pusher du code, cliquer sur le job autofix, review et merger la MR.

Resultat dans Gitlab

Suivi dans le temps

sonar_diff(new_res, old_res)                   # Comparaison
sonar_trend(res, file = "rsonar-history.json") # Historique

Affiche : nouveaux problemes, problemes corriges, tendance.

Ce qu’il faut retenir

rsonar a 3 niveaux d’utilisation : - Localement : score qualite rapide dans l’IDE - En CI : gate + exports + rapports - Dans le temps : dette, diff, tendance

Conclusion

sonar_fix() + sonar_autofix() completent la suite rsonar :

  • Analyser le code
  • Corriger automatiquement
  • Ouvrir une Merge Request pour review

Le tout depuis le pipeline CI, en un clic.