Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use XDG config directory #460

Merged
merged 5 commits into from
Jun 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@

* `available_linters()` gives priority to `tags` over `exclude_tags` in the case of overlap. In particular, this means that `available_linters(tags = "deprecated")` will work to return deprecated linters without needing to specify `exclude_tags` (#1959, @MichaelChirico).

* The {lintr} configuration file is now searched in the system's user configuration path; the lintr config filename can
also be configured explicitly by setting the environment variable `R_LINTR_LINTER_FILE` (#460, @klmr)

### New linters

* `matrix_apply_linter()` recommends use of dedicated `rowSums()`, `colSums()`, `colMeans()`, `rowMeans()` over `apply(., MARGIN, sum)` or `apply(., MARGIN, mean)`. The recommended alternative is much more efficient and more readable (#1869, @Bisaloo).
Expand Down
3 changes: 2 additions & 1 deletion R/settings.R
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
#' 4. `linter_file` in the user home directory
#' 5. [default_settings()]
#'
#' The default linter_file name is `.lintr` but it can be changed with option `lintr.linter_file`.
#' The default linter_file name is `.lintr` but it can be changed with option `lintr.linter_file`
#' or the environment variable `R_LINTR_LINTER_FILE`
#' This file is a dcf file, see [base::read.dcf()] for details.
#' @param filename source file to be linted
read_settings <- function(filename) {
Expand Down
4 changes: 3 additions & 1 deletion R/settings_utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ find_config <- function(filename) {
find_config2(path),
# User directory
# cf: rstudio@bc9b6a5 SessionRSConnect.R#L32
file.path(Sys.getenv("HOME", unset = "~"), linter_file)
file.path(Sys.getenv("HOME", unset = "~"), linter_file),
# Next check for a global config file
file.path(R_user_dir("lintr", which = "config"), "config")
AshesITR marked this conversation as resolved.
Show resolved Hide resolved
)

# Search through locations, return first valid result
Expand Down
2 changes: 1 addition & 1 deletion R/zzz.R
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ settings <- NULL
.onLoad <- function(libname, pkgname) {
op <- options()
op_lintr <- list(
lintr.linter_file = ".lintr"
lintr.linter_file = Sys.getenv("R_LINTR_LINTER_FILE", ".lintr")
)
toset <- !(names(op_lintr) %in% names(op))
if (any(toset)) options(op_lintr[toset])
Expand Down
3 changes: 2 additions & 1 deletion man/read_settings.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions tests/testthat/test-settings.R
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,23 @@ test_that("it uses config home directory settings if provided", {
expect_identical(settings$exclude, "test")
})

test_that("it uses system config directory settings if provided", {
path <- withr::local_tempdir()
config_parent_path <- withr::local_tempdir("config")
config_path <- file.path(config_parent_path, "R", "lintr")
dir.create(config_path, recursive = TRUE)
file <- withr::local_tempfile(tmpdir = path)
local_config(config_path, 'exclude: "test"', filename = "config")

withr::with_envvar(c(R_USER_CONFIG_DIR = config_parent_path), lintr:::read_settings(file))

lapply(setdiff(ls(settings), "exclude"), function(setting) {
expect_identical(settings[[setting]], default_settings[[setting]])
})

expect_identical(settings$exclude, "test")
})

test_that("it errors if the config file does not end in a newline", {
f <- withr::local_tempfile()
cat("linters: linters_with_defaults(closed_curly_linter = NULL)", file = f)
Expand Down
3 changes: 2 additions & 1 deletion vignettes/lintr.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,13 @@ exclusions: list(
More generally, `lintr` searches for a settings file according to following prioritized list.
The first one found, if any, will be used:

1. If `options("lintr.linter_file")` is an absolute path, this file will be used. The default for this option is `".lintr"`.
1. If `options("lintr.linter_file")` is an absolute path, this file will be used. The default for this option is `".lintr"` or the value of the environment variable `R_LINTR_LINTER_FILE`, if set.
2. A project-local linter file; that is, either
1. a linter file (that is, a file named like `lintr.linter_file`) in the currently-searched directory, i.e. the directory of the file passed to `lint()`; or
2. a linter file in the `.github/linters` child directory of the currently-searched directory.
3. A project-local linter file in the closest parent directory of the currently-searched directory, starting from the deepest path, moving upwards one level at a time. When run from `lint_package()`, this directory can differ for each linted file.
4. A linter file in the user's `HOME` directory.
5. A linter file called `config` in the user's configuration path (given by `tools::R_user_dir("lintr", which = "config")`).

If no linter file is found, only default settings take effect (see [defaults](#defaults)).

Expand Down