Skip to content

Require lintr (>= 3.3.0-1) and drop workarounds for older lintr - #783

Open
MichaelChirico wants to merge 2 commits into
REditorSupport:masterfrom
MichaelChirico:lintr-3.3.0-1
Open

MichaelChirico wants to merge 2 commits into
REditorSupport:masterfrom
MichaelChirico:lintr-3.3.0-1

Conversation

@MichaelChirico

Copy link
Copy Markdown
Contributor

In #774 and #775, I noticed {languageserver} has found itself needing to use several private functions from {lintr}.

So I set up an audit of such usage in order to decide what gaps there are in {lintr}'s API so we can export some more meta-helpers that packages such as {languageserver} could avail themselves of.

The first step in the audit found that there are a number of "crutches" in place allowing {languageserver} to depend on older versions of {lintr}; I find that extended back-compatibility for CRAN packages is not as useful as doing so for "tougher" dependencies (e.g. R itself).

So here, I propose bumping the version requirement for {lintr} to 3.3.0-1 (Nov 2025, so about a year by the time {languageserver} lands on CRAN), as well as some clean-up of {languageserver} internals enabled by this bump.

@renkun-ken renkun-ken left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blocking issues found in the diagnostics cleanup.

I reviewed commit 498a531ebb7a438854008743a9e6f55b91e43284 and ran test-lintr.R, test-code-action.R, test-literate.R, and test-diagnostics-configuration.R against the exact lintr 3.3.0-1 release on R 4.6.1. All four passed, including the editor integration tests. The corresponding unit tests also passed with lintr 3.4.0. This covered saved/new R Markdown and Quarto buffers, nested configuration, configuration reloads, custom suppression markers, file/line exclusions, and terminal-newline diagnostics and fixes. The PR's CI checks are also passing.

One non-blocking compatibility note: lintr 3.3.0-1 declares R (>= 4.0), whereas lintr 3.0.0 supported R (>= 3.2). This dependency bump therefore raises languageserver's effective minimum R version to 4.0, although DESCRIPTION still declares R (>= 3.4.0). I suggest aligning that declaration and mentioning the new lintr/R requirements in NEWS so the installation impact is explicit.

@renkun-ken

Copy link
Copy Markdown
Member

Do we really want to bump the minimum required R version? What do you think, @randy3k?

@MichaelChirico

Copy link
Copy Markdown
Contributor Author

Great point. FWIW, R 4.0.0 is approaching 7 years old: https://github.com/wch/r-source/tree/tags/R-4-0-0

@MichaelChirico

Copy link
Copy Markdown
Contributor Author

I could also look into making {lintr} Suggests in {languageserver} so that this package still has other functionality on "ancient" R. WDYT?

@renkun-ken

Copy link
Copy Markdown
Member

I checked the declared R requirements of every direct dependency, including the previously required lintr 3.0.0, to inform the minimum-R discussion.

The previous lintr minimum declared R >= 3.2; the proposed minimum declares R >= 4.0. The updated DESCRIPTION now makes languageserver's R >= 4.0.0 requirement explicit. Using all current CRAN releases instead gives an R >= 4.1 floor: fs, lintr, and roxygen2 require it directly, and no package in the recursively required current dependency tree declares a higher floor.

lintr version comparison

Role lintr release Declared R minimum
Previously required minimum 3.0.0 >= 3.2
Minimum proposed in PR #783 3.3.0-1 >= 4.0
Current CRAN release 3.4.0 >= 4.1.0

Required packages (Imports)

Dependency Package minimum in PR R required by that release Current CRAN release R required by current release
callr 3.0.0 Not declared 3.8.0 >= 3.4
collections 0.3.0 >= 3.4.0 0.3.12 Not declared
digest Unbounded N/A 0.6.39 >= 3.3.0
fs 1.3.1 >= 3.1 2.1.0 >= 4.1
jsonlite 1.6 Not declared 2.0.0 Not declared
lintr 3.3.0-1 >= 4.0 3.4.0 >= 4.1.0
R6 2.4.1 >= 3.0 2.6.1 >= 3.6
roxygen2 7.0.0 >= 3.2 8.1.0 >= 4.1
stringi 1.1.7 >= 2.14 1.8.9 >= 3.4
styler 1.5.1 Not declared 1.11.0 >= 4.0.0
xml2 1.2.2 >= 3.1.0 1.6.0 >= 3.6.0
xmlparsedata 1.0.3 >= 3.0.0 1.0.5 >= 3.0.0

Optional packages (Suggests)

Dependency Package minimum in PR R required by that release Current CRAN release R required by current release
covr 3.4.0 >= 3.1.0 3.6.5 >= 3.1.0
magrittr 1.5 Not declared 2.0.5 >= 3.4.0
mockery 0.4.2 Not declared 0.4.5 >= 3.6
pacman Unbounded N/A 0.5.1 >= 3.5.0
processx 3.4.1 Not declared 3.9.0 >= 3.4.0
purrr 0.3.3 >= 3.2 1.2.2 >= 4.1
testthat 2.1.0 >= 3.1 3.3.2 >= 4.1.0
withr 2.3.0 >= 3.2.0 3.0.3 >= 3.6.0
rmarkdown 2.0 >= 3.0 2.32 >= 3.0
stringr Unbounded N/A 1.6.0 >= 4.1.0

parallel, tools, and utils are distributed with R. They have no independent CRAN package version bound here and follow the package's R requirement.

“Not declared” means that release has no explicit R version constraint in Depends; it does not establish compatibility with every R version. “Unbounded” means languageserver sets no package version lower bound, so there is no exact historical minimum release to inspect. These are DESCRIPTION metadata checks, not runtime compatibility tests.

At the exact package versions specified as lower bounds, lintr 3.3.0-1 is the only direct dependency explicitly requiring R >= 4.0. The current CRAN requirements do not establish that languageserver must require R >= 4.1: older compatible dependency releases can satisfy its package version constraints. Moving lintr to Suggests could therefore help preserve older-R support for other functionality, but older compatible releases of other dependencies would still be needed; that change alone would not make the full current CRAN dependency set installable below R 4.1.

Sources: current CRAN package metadata, checked on 6 October 2026; linked archived releases for the exact minimum versions; and lintr 3.0.0's tagged DESCRIPTION linked above.

@MichaelChirico

Copy link
Copy Markdown
Contributor Author

OK, so basically, while it's technically possible to run current {languageserver} using archived versions of its dependencies that still satisfy its stated version requirements, doing so is pretty onerous -- it's very likely that anyone that installs {languageserver} today does so with an effective R version minimum of 4.1.0 because that's what would be required for installing directly from CRAN.

(and this assumes that the stated version requirements for the other dependencies are indeed accurate)

@renkun-ken

Copy link
Copy Markdown
Member

Bumping the minimum to R 4.0 is reasonable as a deliberate decision to end R 3.x support. The main benefit is easier maintenance; the main cost is excluding older environments from the entire language server.

The practical impact is:

Environment Impact
R 3.4–3.6 with compatible dependencies already installed Cannot install the new languageserver release. An existing compatible release continues working, but users cannot receive future languageserver updates on that R version.
R 4.0 Meets the new declared requirement, but still needs older compatible dependencies because several current CRAN releases require R 4.1.
R >= 4.1 with current dependencies Little installation impact.
Any R version with lintr 3.0 pinned in a project Must update lintr and potentially its dependencies to install the new release.

Pros

  • Less compatibility code. This PR removes special handling for older lintr behavior around extracted R Markdown code, configuration, exclusions, and diagnostic wording.
  • A narrower support burden. Maintainers can focus development and testing on R 4.x and newer lintr releases.
  • Clear installation requirements. Declaring R >= 4.0 accurately reflects the mandatory lintr dependency.
  • Limited disruption to installations using current CRAN packages. Their dependency tree already requires R >= 4.1.

Cons

  • A package-wide restriction for a diagnostics-related change. Users on R 3.x lose access to future completion, navigation, formatting, and other improvements—even if they disable linting.
  • Pinned environments are affected materially. An existing library, lockfile, container, or institutional package repository may already contain working older dependencies. Those users do not need to reconstruct an archived dependency tree to continue using languageserver today.
  • Upgrading R can require project migration. Rebuilding compiled packages and validating changed R behavior can be substantial work in reproducible or managed environments.
  • The maintenance savings are partial. The PR still uses private lintr functions and retains the terminal-newline fallback.
  • R 4.0 compatibility remains unverified by the checks discussed here. The focused tests reported earlier ran on R 4.6.1, and the R-CMD-check workflow tests the current R release. Passing those checks does not demonstrate support for the declared minimum.

The dependency audit establishes that fresh installations using all current CRAN releases need R >= 4.1. It does not establish how many users still rely on older, working environments. We have no usage data to quantify that group, so the current-CRAN floor is evidence of limited impact for that installation path, not evidence that dropping R 3.x has no practical cost.

Recommendation: accept R >= 4.0 if maintainers intend to retire R 3.x support, document the breaking change and last compatible languageserver release, and validate installation and core behavior on R 4.0 with compatible dependencies. If preserving R 3.x remains a goal, making lintr optional deserves consideration: it could retain other editor features while requiring newer R for diagnostics, at the cost of additional feature checks and tests. Supporting those older environments would still require compatible versions of the other dependencies.

@MichaelChirico

Copy link
Copy Markdown
Contributor Author
  • Pinned environments are affected materially.

FWIW, such users should not find it difficult to keep using a pinned old version languageserver as well

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants