Skip to contents

Why rsonar?

Teams developing in Python, Java or JavaScript benefit from SonarQube: a centralized tool that analyzes code quality, measures test coverage, detects code smells and calculates technical debt. R developers, however, must juggle several disparate tools.

rsonar bridges this gap by orchestrating the best R tools available:

Dimension Underlying tool SonarQube equivalent
Static analysis lintr Issues (bugs, code smells)
Code style styler Style violations
Test coverage covr Code coverage
Best practices goodpractice Maintainability checks
Technical debt SQALE model Technical debt
Quality Gate quality_gate() Quality Gate

Installation

# From GitHub (recommended)
remotes::install_github("ddotta/rsonar")

Typical Workflow

1. Analyze a project

library(rsonar)

# Full analysis (from the root of an R package)
res <- sonar_analyse("path/to/my/package")

The sonar_analyse() function:

  1. Lists all .R files, excluding cache directories (renv, packrat, etc.)
  2. Runs lintr::lint_dir() using the project’s .lintr file if present
  3. Checks style with styler::style_file(..., dry = "on")
  4. Measures coverage with covr::package_coverage()
  5. Runs goodpractice::gp() on the package
  6. Computes technical debt using the SQALE model

2. View the console summary

print(res)

2bis. Get a quick quality percentage in your IDE

For rapid local feedback during development (without CI):

By default, quality_score() runs a fast analysis (coverage and goodpractice disabled) and displays a percentage score plus the SQALE rating.

── rsonar — Quality Report ──────────────────────────────────
ℹ Project  : /home/user/mypackage
ℹ Analysis : 2026-04-20 14:32
ℹ Files    : 8 R file(s)

── Metrics ──────────────────────────────────────────────────
  Lint        : 3 issue(s) (1 err / 2 warn / 0 style)
  Style       : 1 non-compliant file(s)
  Coverage    : 72.4%
  Goodpractice: 2 failure(s)

── Technical Debt ───────────────────────────────────────────
🟡 SQALE rating: C
⏱  Estimated duration: 1.42h (85 min)

3. Generate the HTML report

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

The HTML report contains:

  • Dashboard with consolidated metrics and SQALE A→E rating
  • Lint issues list with severity, file, line and rule
  • Improperly formatted files detected by styler
  • Technical debt breakdown by category and in minutes

4. Check the Quality Gate

gate <- quality_gate(res,
  coverage_min     = 80,   # 80% minimum coverage
  lint_errors_max  = 0,    # 0 errors tolerated
  style_issues_max = 0,    # all code must be formatted
  rating_min       = "C"   # minimum SQALE rating
)
print(gate)
── Quality Gate: PASSED ──────────────────────────────────────
✔ Coverage >= 80% [82.1%]
✔ Lint errors <= 0 [0]
✔ Style issues <= 0 [0]
✔ SQALE rating >= C [B]

5. Set up the project

# Add the recommended rsonar .lintr
use_rsonar_lintr()

# Add a pre-configured GitLab CI pipeline
use_rsonar_ci("gitlab")

# Or GitHub Actions
use_rsonar_ci("github")

Analyzing non-package projects (plain R scripts)

rsonar also works on projects that are not R packages:

res <- sonar_analyse(
  "path/to/project",
  include_coverage     = FALSE,  # no tests/
  include_goodpractice = FALSE   # no DESCRIPTION
)
sonar_report(res)

Comparing analyses

Use sonar_diff() to compare two analyses and detect regressions:

baseline <- sonar_analyse(".", include_coverage = FALSE)
# ... make changes ...
current  <- sonar_analyse(".", include_coverage = FALSE)
diff     <- sonar_diff(current, baseline)
print(diff)

Use sonar_trend() in your CI pipeline to build a history of quality metrics:

res <- sonar_analyse(".")
sonar_trend(res, file = "rsonar-history.json")

Export for SonarQube

If your organization already uses SonarQube for other languages, you can inject rsonar results via the Generic Issue Import:

export_sonar_json(res, "sonar-issues.json")

Then in sonar-project.properties:

sonar.externalIssuesReportPaths=sonar-issues.json

Export for GitHub Code Scanning (SARIF)

export_sarif(res, "results.sarif")

For GitLab CI with JUnit artifacts:

export_junit(res, "junit-results.xml")