diff --git a/R/settings_utils.R b/R/settings_utils.R index f5f024ae0..3ca34d415 100644 --- a/R/settings_utils.R +++ b/R/settings_utils.R @@ -34,14 +34,21 @@ is_root <- function(path) { identical(path, dirname(path)) } -is_directory <- function(filename) { - is_dir <- file.info(filename)$isdir - - !is.na(is_dir) && is_dir -} - -has_config <- function(path, config) { - file.exists(file.path(path, config)) +is_directory <- function(filename) isTRUE(file.info(filename)$isdir) + +#' Return the first of a vector of files that exists. +#' +#' Avoid running 'expensive' [file.exists()] for the full vector, +#' since typically the first entries will lead to early exit. +#' TODO(#2204): check if the implementation should be simpler +#' @noRd +first_exists <- function(files) { + for (file in files) { + if (file.exists(file)) { + return(file) + } + } + NULL } find_config <- function(filename) { @@ -61,12 +68,14 @@ find_config <- function(filename) { dirname(filename) } + path <- normalizePath(path, mustWork = FALSE) + # NB: This vector specifies a priority order for where to find the configs, # i.e. the first location where a config exists is chosen and configs which # may exist in subsequent directories are ignored file_locations <- c( # Local (incl. parent) directories - find_config2(path), + find_local_config(path, basename(linter_file)), # User directory # cf: rstudio@bc9b6a5 SessionRSConnect.R#L32 file.path(Sys.getenv("HOME", unset = "~"), linter_file), @@ -74,31 +83,24 @@ find_config <- function(filename) { file.path(R_user_dir("lintr", which = "config"), "config") ) - # Search through locations, return first valid result - for (loc in file_locations) { - if (file.exists(loc)) { - return(loc) - } - } - - NULL + first_exists(file_locations) } -find_config2 <- function(path) { - config <- basename(getOption("lintr.linter_file")) - path <- normalizePath(path, mustWork = FALSE) - - while (!has_config(path, config)) { - gh <- file.path(path, ".github", "linters") - if (has_config(gh, config)) { - return(file.path(gh, config)) +find_local_config <- function(path, config_file) { + repeat { + guesses_in_dir <- c( + file.path(path, config_file), + file.path(path, ".github", "linters", config_file) + ) + found <- first_exists(guesses_in_dir) + if (!is.null(found)) { + return(found) } path <- dirname(path) if (is_root(path)) { return(character()) } } - return(file.path(path, config)) } pkg_name <- function(path = find_package()) {