This page documents the linting policy for dataquieR and the internal
QualityIndicatorFunctions (QIF) implementation repository. It
complements the dataquieR
development policy with the current lintr baseline, the
QIF-specific configuration choices, and the linters that are
intentionally not enabled.
The package lint configuration lives in the internal QIF repository
at QualityIndicatorFunctions/.lintr. CI runs the
configuration through the lint_qif job using
Rscript .lint.R.
Lint results are review feedback for readability, maintainability, and small correctness risks. They must not be applied mechanically when doing so would make the code harder to understand, change semantics, obscure domain-specific names, or introduce noisy global suppressions.
The current baseline enables the low-risk style and correctness checks used by CI, including:
The current package tree has no findings from the enabled linters. CI exposes future findings as an allowed warning and supplies GitLab with a machine-readable Code Quality report.
Some linters are deliberately configured rather than used with their defaults.
object_name_linter allows snake case, upper snake case,
dataquieR option names, result slot names, metric abbreviations,
metadata names, REDCap rule names, S3 methods, JavaScript/DataTables
option names, and other package/domain-specific names that are not free
to rename.
Do not rename these names just to satisfy a generic style rule. Many of them are part of public APIs, result structures, metadata conventions, external configuration languages, or browser/report integration code.
object_length_linter(length = 70L) keeps a guardrail
against excessive new names. The default 30-character limit is too
strict for QIF’s descriptive domain, API, option, and report-slot names,
but names above 70 characters should remain exceptional.
pipe_consistency_linter(pipe = "%>%") keeps the
established magrittr pipe style. Do not mix in native pipes
(|>) opportunistically. Migrating all pipelines to the
native pipe is a separate semantic style migration and needs review on
its own.
The maximum source line length is 80 characters. Use focused
# nolint comments only for local exceptions that would
become less readable or less faithful to external/domain-specific text
if wrapped.
Package implementation code should not call base stop(),
warning(), or message() directly. Use
util_error(), util_warning(), and
util_message() instead, so conditions keep their dataquieR
classes, metadata, and report/rendering behavior. Direct base calls are
legitimate inside the wrapper implementations themselves and in rare
compatibility shims with an explicit rationale. QIF includes a
source-level test for this rule when the package R/ sources
are available.
Two high-conflict linters remain intentionally disabled.
return_linterreturn_linter is deliberately disabled. Explicit
return() is allowed when it improves readability,
especially for early exits and control-flow-heavy code. In small
lambda-like helpers an implicit return often reads better; use judgement
rather than a package-wide rule.
object_usage_linterobject_usage_linter is deliberately disabled. This
codetools-style linter is similar to R CMD check “no visible binding”
warnings. It produces many false positives for non-standard evaluation,
data masks, tidy evaluation, generated metadata environments,
REDCap/report domain-specific languages, and code such as
subset(cars, speed > dist) where names are resolved in a
data context.
Prefer local, readable fixes for true findings. Avoid broad
utils::globalVariables() suppressions because they can hide
real problems and make the check ineffective.
Use local # nolint exceptions when a specific line is
intentionally outside a generic lint rule. Keep exceptions narrow, name
the linter when useful, and prefer prose explanations over commented-out
code.
For larger removed code blocks, keep the history in Git rather than in source comments. A short source comment can point to the relevant commit or diff if that history is useful for maintainers.
TODO, FIXME, IDEA, and
QUESTION comments are permitted only as a short-lived
pointer to a tracked work item. Before adding one, create or enrich the
relevant issue with enough source context to implement the work: file
and function, the relevant code excerpt, the complete multi-line marker
text when applicable, and the intended outcome.
Do not use marker comments as an untracked backlog. Remove them when the issue has the needed context, the work is resolved, or the idea is rejected. For a large historical inventory, group related markers under a reviewed umbrella issue rather than creating hundreds of duplicate issues.
QIF CI uses todor to count these four marker types early
in lint_qif. The current ceiling is deliberately small; a
change that exceeds it must include the corresponding issue work and an
explicit review decision.
The lint_qif CI job uploads text, RDS, and GitLab Code
Quality artifacts. It is intentionally allow_failure: true,
so lint regressions are visible in pipelines but do not block merge
requests by themselves.
During dedicated lint-cleanup work it can be useful to make
lint_qif fail hard temporarily, so expensive tests do not
run behind known lint failures. The default after the cleanup is
warning-only linting with visible CI output and Code Quality
artifacts.