Skip to content

Code metrics

RefreshCRAN three times a day, Bioconductor daily

Overview

Code metrics are produced by parsing the released source of each package version. The package is never installed, loaded, or executed.

The documentation section on a package page

Documentation

In release 2.3.0
READMEYes · 412 wordsVignettesYes · 2 · dynamicNEWSYes · 83% structured · mentions 2.3.0Citation fileYes · cites a publicationWebsiteYes · pkgdown
Help pages
36 (4 internal)includes a package overview page
Examples that run
80%24 run in a plain check · 3 only when donttest examples are enabled (R CMD check --as-cran) · 2 never run · 1 hold no code
Exported functions with examples
81%
Documented parameters
88%
Return-value docs
not tracked
Help pages citing references
31%

An illustrative package with invented numbers. Every badge describes a file in the analysed release. A file the repository keeps but the release leaves out is marked that way when a repository scan can see the .Rbuildignore line. A field that was never computed reads not tracked.

Each version the pipeline analyzes produces one row. These numbers appear on CRAN package pages, Bioconductor Code cards, version-compare pages, and Task View Doc coverage columns.

Input and timing

For CRAN, the source is the public github.com/cran mirror, which carries one commit per released tarball. Every version-like tag is analyzed. Nothing is built, installed, or run.

Line counts include blank and comment lines. Five directories are measured and the total is their sum: R/, src/, tests/, man/, and vignettes/. Inside src/, C, C++, Fortran and Rust files are counted, and Rust crates vendored under src/ are left out. Help pages are found whatever the case of their .Rd extension. Files under inst/, tools/, or data-raw/ are not counted.

Totals reflect bulk, not just executable code. Vignette prose, test fixture data, reference output, and stored snapshots all contribute to the line counts.

The assessed_at date is when the analyzer ran, not when the version was released.

Per-version fields

The glossary defines each field. Below are details the field names alone do not convey.

  • Exported functions counts export() directives in NAMESPACE, or definitions matched by an exportPattern when only patterns are declared. S3 methods counts S3method() registrations. S4, R6, S7, and Reference Class counts come from source-level detection.
  • Roxygen coverage is the share of NAMESPACE exports that have a corresponding man/*.Rd file. It drives the Docs vital sign and Task View Doc coverage columns.
  • Examples coverage counts Rd files with an examples block (whether wrapped in dontrun or not). Value docs and references coverage use different denominators and are not directly comparable.
  • Quality and risk fields are regex-based tallies over R/ source. Credential-shaped literals are counted in all non-binary files, so test fixtures and example keys are included. Density columns are per 1,000 lines of R code.

Per-file churn is cumulative across all releases between the two versions being compared, not a direct diff. A line edited and then reverted appears as both added and deleted.

Object-system chips (S4, R6, etc.) appear only when the count is above zero. A stored zero and a blank both result in no chip being shown.

Examples and help pages

Each help page with an examples section falls into one of four groups. Its examples run in a plain check when some code sits outside \dontrun, \donttest, \dontshow and \testonly. They run only when donttest examples are enabled when the rest of the code sits inside \donttest, which R CMD check --as-cran turns on. A page counts as never run when its code sits only inside \dontrun, \dontshow or \testonly. Code in \dontshow and \testonly does run, but R hides it from the reader, so no example the reader sees is run. A page whose examples hold only comments is counted apart.

Help pages are found by file name whatever the case of the .Rd extension, and Rd macro files under man/macros are left out. The share of exported functions with examples counts the pages that document an exported function. When a package declares its exports only by pattern, the count falls back to pages not marked internal, which makes it a lower bound.

Citation and NEWS

A citation file is read as text and never run. When its entry is built by code, such as a call that reads the installed version, the card says the file is present and asks the reader to run citation() rather than guessing what it returns. A DOI is reported only when it is written in the file.

The NEWS file is the one R itself would read, checked in the order inst/NEWS.Rd, NEWS.md, inst/NEWS.md, NEWS and inst/NEWS. The release notes on a package page are the section of that file written for the analysed version, and only that section is kept.

What the release carries

The Documentation card reports what the analysed release contains, which is a README, vignettes, a NEWS file and the rates read from its help pages. The card names the release it describes, and says so when a newer release has not been analysed yet.

The Website badge reads the URL field of DESCRIPTION. It says Yes when the field declares a site and names the generator when the repository scan can identify it. When the field declares no site, the badge says so rather than No.

A link to a code repository is not a site, and that includes a repository on a GitLab, Gitea or Forgejo server an institution runs itself. The project sites those servers publish, on hosts such as gitlab.io, frama.io or codeberg.page, are sites.

Files a maintainer keeps only in the source repository, such as a pkgdown config, a code of conduct, a contributing guide or CI configuration, are not release contents. The repository practices scan reads them from the repository itself.

Older analyses looked for fewer README and NEWS file names, so a zero from them reads not tracked rather than No until the package is analysed again.

Bioconductor differences

Bioconductor packages are analyzed from git branches rather than tarballs. The version column holds the Bioconductor release (e.g. RELEASE_3_20), not the package's own version number. A package is re-analyzed only when a new Bioconductor release appears.

Most software, experiment-data, and workflow packages have a code row. Annotation packages have no release-branch repository and no row.

From the 0.5.0 analyzer onward, release-content fields on Bioconductor are read from the files R CMD build would keep, after .Rbuildignore and its default exclusions. Earlier rows read the whole git branch, so a Bioconductor package's history shifts once at that rescan. The code of conduct, contributing guide, pkgdown config and CI files keep reading the git branch and appear under Repository practices, labelled as read from the Bioconductor git repository.

The Bioconductor Code card includes additional fields not shown elsewhere: total file count, compiled-source presence, C++ standard, on.exit coverage, and a line-count sparkline.

The Bioconductor compare page does not include typed dependency columns, churn data, or export history.

Zero, blank, and the latest row

A zero and a blank carry different meanings.

  • Zero means the analyzer looked and found none.
  • Blank means the field was not computed or does not apply. On the compare page, a field is hidden only when both sides are blank.
  • Latest row only applies to about ten summary fields (dependency drift, version count, release dates, etc.) that exist only on the most recent version and cannot be compared across releases.
  • No row at all means the package has never been analyzed.

A blank is often correct. For example, roxygen coverage is blank for a package that exports nothing, and seed discipline is blank when no test uses randomness.

Per-function detail (for the call graph and function table) is kept for the latest CRAN version only. A column added after a package was last analyzed stays blank until its next release.

Limits

These metrics reflect what the parser finds in the source text. Code generated at build time or registered dynamically is not captured. Nothing here indicates that tests pass or that tools are configured correctly.

  • Exported and internal function counts come from NAMESPACE directives, while the analyzer's own counts come from definitions. The two often disagree and neither adds up to the total R function count.
  • Test-to-code ratio is test lines divided by R lines. Fixture files and reference output inflate the numerator.
  • "Has tests" is true when any file exists under tests/, including bare stubs. Test cases are counted for testthat, tinytest, RUnit, unittest, and testit only.
  • "Exported functions covered by tests" uses name matching, not call tracing. A function name appearing in a comment under tests/ counts as covered.
  • Release dates come from the CRAN mirror's commit timestamps, not from CRAN directly.

The Dependencies and Documentation indicators use fixed thresholds chosen by this site, not by an external standard. An internal analyzer failure shows as a blank rather than an error.

Interpreting the numbers

These numbers are most useful for tracking changes across a package's own releases. No column is a score, and none are combined into a single rating. Direction hints indicate which way a field typically reads, not how much it matters.

Privacy choices

These apply to this browser and are stored on this device only. Nothing about your choice is sent to us.

Read the privacy policy