Skip to content

Commit

Permalink
Merge branch 'main' into chore-parallel-testing
Browse files Browse the repository at this point in the history
  • Loading branch information
IndrajeetPatil authored Feb 1, 2025
2 parents 063e552 + b6d945d commit 33fd6d4
Show file tree
Hide file tree
Showing 31 changed files with 117 additions and 101 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pkgdown.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:

- name: Deploy to GitHub pages 🚀
if: github.event_name != 'pull_request'
uses: JamesIves/[email protected].1
uses: JamesIves/[email protected].2
with:
clean: false
branch: gh-pages
Expand Down
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ BugReports: https://github.com/r-lib/lintr/issues
Depends:
R (>= 4.0)
Imports:
backports (>= 1.1.7),
backports (>= 1.4.0),
cli (>= 3.4.0),
codetools,
digest,
Expand Down
5 changes: 2 additions & 3 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

S3method("[",lints)
S3method(as.data.frame,lints)
S3method(data.table::as.data.table,lints)
S3method(format,lint)
S3method(format,lints)
S3method(names,lints)
S3method(print,lint)
S3method(print,lints)
S3method(split,lints)
S3method(summary,lints)
S3method(tibble::as_tibble,lints)
export(Lint)
export(Linter)
export(T_and_F_symbol_linter)
Expand Down Expand Up @@ -181,13 +183,10 @@ importFrom(stats,na.omit)
importFrom(tools,R_user_dir)
importFrom(utils,capture.output)
importFrom(utils,getParseData)
importFrom(utils,getTxtProgressBar)
importFrom(utils,globalVariables)
importFrom(utils,head)
importFrom(utils,relist)
importFrom(utils,setTxtProgressBar)
importFrom(utils,tail)
importFrom(utils,txtProgressBar)
importFrom(xml2,as_list)
importFrom(xml2,xml_attr)
importFrom(xml2,xml_children)
Expand Down
5 changes: 2 additions & 3 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
+ `source_file=` argument to `ids_with_token()` and `with_id()`.
+ Passing linters by name or as non-`"linter"`-classed functions.
+ `linter=` argument of `Lint()`.
+ Linters `closed_curly_linter()`, `open_curly_linter()`, `paren_brace_linter()`, and `semicolon_terminator_linter()`..
+ `with_defaults()`.
+ Linters `closed_curly_linter()`, `open_curly_linter()`, `paren_brace_linter()`, and `semicolon_terminator_linter()`.
+ Helper `with_defaults()`.
Expand All @@ -19,7 +18,6 @@
* `scalar_in_linter` is now configurable to allow other `%in%` like operators to be linted. The data.table operator `%chin%` is no longer linted by default; use `in_operators = "%chin%"` to continue linting it. (@F-Noelle)
* `lint()` and friends now normalize paths to forward slashes on Windows (@olivroy, #2613).
* `undesirable_function_linter()`, `undesirable_operator_linter()`, and `list_comparison_linter()` were removed from the tag `efficiency` (@IndrajeetPatil, #2655). If you use `linters_with_tags("efficiency")` to include these linters, you'll need to adjust your config to keep linting your code against them. We did not find any such users on GitHub.


## Bug fixes

Expand Down Expand Up @@ -62,6 +60,7 @@
* `paste_linter()` is extended to recommend using `paste()` instead of `paste0()` for simply aggregating a character vector with `collapse=`, i.e., when `sep=` is irrelevant (#1108, @MichaelChirico).
* `expect_no_lint()` was added as new function to cover the typical use case of expecting no lint message, akin to the recent {testthat} functions like `expect_no_warning()` (#2580, @F-Noelle).
* `lint()` and friends emit a message if no lints are found (#2643, @IndrajeetPatil).
* `{lintr}` now has a hex sticker (https://github.com/rstudio/hex-stickers/pull/110). Thank you, @gregswinehart!

### New linters

Expand Down Expand Up @@ -91,7 +90,7 @@

## Notes

* All user-facing messages are now prepared using the `{cli}` package (#2418, @IndrajeetPatil). All messages have been reviewed and updated to be more informative and consistent.
* All user-facing messages (including progress bars) are now prepared using the `{cli}` package (#2418 and #2641, @IndrajeetPatil). All messages have been reviewed and updated to be more informative and consistent.
* File locations in lints and error messages contain clickable hyperlinks to improve code navigation (#2645, #2588, @olivroy).
* {lintr} now depends on R version 4.0.0. It already does so implicitly due to recursive upstream dependencies requiring this version; we've simply made that dependency explicit and up-front (#2569, @MichaelChirico).
* Some code with parameters accepting regular expressions is less strict about whether there are capture groups (#2678, @MichaelChirico). In particular, this affects `unreachable_code_linter(allow_comment_regex=)` and `expect_lint(checks=)`.
Expand Down
3 changes: 3 additions & 0 deletions R/indentation_linter.R
Original file line number Diff line number Diff line change
Expand Up @@ -257,9 +257,12 @@ indentation_linter <- function(indent = 2L, hanging_indent_style = c("tidy", "al
}

# Only lint non-empty lines if the indentation level doesn't match.
# TODO: remove styler ignore directives once tidyverse/style/issues/197 is resolved
# styler: off
bad_lines <- which(indent_levels != expected_indent_levels &
nzchar(trimws(source_expression$file_lines)) &
!in_str_const)
# styler: on
if (length(bad_lines) > 0L) {
# Suppress consecutive lints with the same indentation difference, to not generate an excessive number of lints
is_consecutive_lint <- c(FALSE, diff(bad_lines) == 1L)
Expand Down
44 changes: 22 additions & 22 deletions R/lint.R
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,14 @@
#' @return An object of class `c("lints", "list")`, each element of which is a `"list"` object.
#'
#' @examples
#' # linting inline-code
#' lint("a = 123\n")
#' lint(text = "a = 123")
#'
#' # linting a file
#' f <- tempfile()
#' writeLines("a=1", f)
#' lint(f) # linting a file
#' lint("a = 123\n") # linting inline-code
#' lint(text = "a = 123") # linting inline-code
#' lint(f)
#' unlink(f)
#'
#' @export
Expand Down Expand Up @@ -182,20 +185,24 @@ lint_dir <- function(path = ".", ...,
return(lints)
}

pb <- if (isTRUE(show_progress)) {
txtProgressBar(max = length(files), style = 3L)
if (isTRUE(show_progress)) {
lints <- lapply(
# NB: This cli API is experimental (https://github.com/r-lib/cli/issues/709)
cli::cli_progress_along(files, name = "Running linters"),
function(idx) {
lint(files[idx], ..., parse_settings = FALSE, exclusions = exclusions)
}
)
} else {
lints <- lapply(
files,
function(file) { # nolint: unnecessary_lambda_linter.
lint(file, ..., parse_settings = FALSE, exclusions = exclusions)
}
)
}

lints <- flatten_lints(lapply(
files,
function(file) {
maybe_report_progress(pb)
lint(file, ..., parse_settings = FALSE, exclusions = exclusions)
}
))

if (!is.null(pb)) close(pb)

lints <- flatten_lints(lints)
lints <- reorder_lints(lints)

if (relative_path) {
Expand Down Expand Up @@ -688,13 +695,6 @@ has_positional_logical <- function(dots) {
!nzchar(names2(dots)[1L])
}

maybe_report_progress <- function(pb) {
if (is.null(pb)) {
return(invisible())
}
setTxtProgressBar(pb, getTxtProgressBar(pb) + 1L)
}

maybe_append_error_lint <- function(lints, error, lint_cache, filename) {
if (is_lint(error)) {
error$linter <- "error"
Expand Down
3 changes: 1 addition & 2 deletions R/lintr-package.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
#' @importFrom rex rex regex re_matches re_substitutes character_class
#' @importFrom stats complete.cases na.omit
#' @importFrom tools R_user_dir
#' @importFrom utils capture.output getParseData getTxtProgressBar globalVariables head relist
#' setTxtProgressBar tail txtProgressBar
#' @importFrom utils capture.output getParseData globalVariables head relist tail
#' @importFrom xml2 as_list
#' xml_attr xml_children xml_find_all xml_find_chr xml_find_lgl xml_find_num xml_find_first xml_name xml_text
## lintr namespace: end
Expand Down
2 changes: 2 additions & 0 deletions R/methods.R
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ as.data.frame.lints <- function(x, row.names = NULL, optional = FALSE, ...) { #
)
}

#' @exportS3Method tibble::as_tibble
as_tibble.lints <- function(x, ..., # nolint: object_name_linter.
.rows = NULL,
.name_repair = c("check_unique", "unique", "universal", "minimal"),
Expand All @@ -181,6 +182,7 @@ as_tibble.lints <- function(x, ..., # nolint: object_name_linter.
tibble::as_tibble(as.data.frame(x), ..., .rows = .rows, .name_repair = .name_repair, rownames = rownames)
}

#' @exportS3Method data.table::as.data.table
as.data.table.lints <- function(x, keep.rownames = FALSE, ...) { # nolint: object_name_linter.
stopifnot(requireNamespace("data.table", quietly = TRUE))
data.table::setDT(as.data.frame(x), keep.rownames = keep.rownames, ...)
Expand Down
5 changes: 3 additions & 2 deletions R/nested_pipe_linter.R
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@
#' @seealso [linters] for a complete list of linters available in lintr.
#' @export
nested_pipe_linter <- function(
allow_inline = TRUE,
allow_outer_calls = c("try", "tryCatch", "withCallingHandlers")) {
allow_inline = TRUE,
allow_outer_calls = c("try", "tryCatch", "withCallingHandlers")
) {
multiline_and <- if (allow_inline) "@line1 != @line2 and" else ""
xpath <- glue("
(//PIPE | //SPECIAL[{ xp_text_in_table(magrittr_pipes) }])
Expand Down
5 changes: 3 additions & 2 deletions R/object_overwrite_linter.R
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@
#' - <https://style.tidyverse.org/syntax.html#object-names>
#' @export
object_overwrite_linter <- function(
packages = c("base", "stats", "utils", "tools", "methods", "graphics", "grDevices"),
allow_names = character()) {
packages = c("base", "stats", "utils", "tools", "methods", "graphics", "grDevices"),
allow_names = character()
) {
for (package in packages) {
if (!requireNamespace(package, quietly = TRUE)) {
cli_abort("Package {.pkg {package}} is required, but not available.")
Expand Down
11 changes: 6 additions & 5 deletions R/return_linter.R
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,12 @@
#' - <https://style.tidyverse.org/functions.html?q=return#return>
#' @export
return_linter <- function(
return_style = c("implicit", "explicit"),
allow_implicit_else = TRUE,
return_functions = NULL,
except = NULL,
except_regex = NULL) {
return_style = c("implicit", "explicit"),
allow_implicit_else = TRUE,
return_functions = NULL,
except = NULL,
except_regex = NULL
) {
return_style <- match.arg(return_style)

check_except <- !allow_implicit_else || return_style == "explicit"
Expand Down
21 changes: 11 additions & 10 deletions R/unnecessary_nesting_linter.R
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,17 @@
#' - [linters] for a complete list of linters available in lintr.
#' @export
unnecessary_nesting_linter <- function(
allow_assignment = TRUE,
allow_functions = c(
"switch",
"try", "tryCatch", "withCallingHandlers",
"quote", "expression", "bquote", "substitute",
"with_parameters_test_that",
"reactive", "observe", "observeEvent",
"renderCachedPlot", "renderDataTable", "renderImage", "renderPlot",
"renderPrint", "renderTable", "renderText", "renderUI"
)) {
allow_assignment = TRUE,
allow_functions = c(
"switch",
"try", "tryCatch", "withCallingHandlers",
"quote", "expression", "bquote", "substitute",
"with_parameters_test_that",
"reactive", "observe", "observeEvent",
"renderCachedPlot", "renderDataTable", "renderImage", "renderPlot",
"renderPrint", "renderTable", "renderText", "renderUI"
)
) {
exit_calls <- c("stop", "return", "abort", "quit", "q")
exit_call_expr <- glue("
expr[SYMBOL_FUNCTION_CALL[{xp_text_in_table(exit_calls)}]]
Expand Down
3 changes: 1 addition & 2 deletions R/utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,7 @@ read_lines <- function(file, encoding = settings$encoding, ...) {

# nocov start
# support for usethis::use_release_issue(). Make sure to use devtools::load_all() beforehand!
release_bullets <- function() {
}
release_bullets <- function() {}
# nocov end

# see issue #923, PR #2455 -- some locales ignore _ when running sort(), others don't.
Expand Down
7 changes: 0 additions & 7 deletions R/zzz.R
Original file line number Diff line number Diff line change
Expand Up @@ -329,12 +329,5 @@ settings <- new.env(parent = emptyenv())
))

reset_settings()

if (requireNamespace("tibble", quietly = TRUE)) {
registerS3method("as_tibble", "lints", as_tibble.lints, asNamespace("tibble"))
}
if (requireNamespace("data.table", quietly = TRUE)) {
registerS3method("as.data.table", "lints", as.data.table.lints, asNamespace("data.table"))
}
}
# nocov end
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# lintr
# lintr <img src="man/figures/logo.png" align="right" width="240" />

[![R build status](https://github.com/r-lib/lintr/workflows/R-CMD-check/badge.svg)](https://github.com/r-lib/lintr/actions)
[![codecov.io](https://codecov.io/gh/r-lib/lintr/branch/main/graphs/badge.svg)](https://app.codecov.io/gh/r-lib/lintr?branch=main)
Expand Down
Binary file added man/figures/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 6 additions & 3 deletions man/lint.Rd

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

File renamed without changes.
Binary file added pkgdown/favicon/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pkgdown/favicon/favicon-96x96.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pkgdown/favicon/favicon.ico
Binary file not shown.
3 changes: 3 additions & 0 deletions pkgdown/favicon/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions pkgdown/favicon/site.webmanifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "",
"short_name": "",
"icons": [
{
"src": "/web-app-manifest-192x192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "/web-app-manifest-512x512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
}
Binary file added pkgdown/favicon/web-app-manifest-192x192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pkgdown/favicon/web-app-manifest-512x512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions tests/testthat/helper.R
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,16 @@ skip_if_not_utf8_locale <- function() {
testthat::skip_if_not(l10n_info()[["UTF-8"]], "Not a UTF-8 locale")
}

safe_load_help_db <- function() {
help_db <- tryCatch(tools::Rd_db("lintr"), error = function(e) NULL)
# e.g. in dev under pkgload::load_all()
if (length(help_db) == 0L) {
help_db <- tryCatch(tools::Rd_db(dir = testthat::test_path("..", "..")), error = function(e) NULL)
testthat::skip_if_not(length(help_db) > 0L, message = "Package help corrupted or not installed")
}
help_db
}

pipes <- function(exclude = NULL) {
if (getRversion() < "4.1.0") exclude <- unique(c(exclude, "|>"))
all_pipes <- c(
Expand Down
17 changes: 7 additions & 10 deletions tests/testthat/test-fixed_regex_linter.R
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ test_that("fixed_regex_linter blocks simple disallowed usages", {
})

patrick::with_parameters_test_that(
"fixed_regex_linter is robust to unrecognized escapes error",
"fixed_regex_linter is robust to unrecognized escapes error for {char}",
{
expect_lint(
sprintf(R"{grep('\\%s', x)}", char),
Expand All @@ -56,14 +56,11 @@ patrick::with_parameters_test_that(
fixed_regex_linter()
)
},
.cases = local({
char <- c(
"^", "$", "{", "}", "(", ")", ".", "*", "+", "?",
"|", "[", "]", R"(\\)", "<", ">", "=", ":", ";", "/",
"_", "-", "!", "@", "#", "%", "&", "~"
)
data.frame(char = char, .test_name = char)
})
char = c(
"^", "$", "{", "}", "(", ")", ".", "*", "+", "?",
"|", "[", "]", R"(\\)", "<", ">", "=", ":", ";", "/",
"_", "-", "!", "@", "#", "%", "&", "~"
)
)

test_that("fixed_regex_linter catches regex like [.] or [$]", {
Expand Down Expand Up @@ -326,7 +323,7 @@ local({
skip_cases <- character()
}
patrick::with_parameters_test_that(
"fixed replacements are correct",
"fixed replacements of {regex_expr} with {fixed_expr} is correct",
{
# TODO(google/patrick#19): handle this more cleanly by skipping up-front
skip_if(
Expand Down
6 changes: 0 additions & 6 deletions tests/testthat/test-lint_dir.R
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,6 @@ test_that("lint all files in a directory", {

expect_s3_class(lints, "lints")
expect_identical(sort(linted_files), sort(files))

expect_output(
lint_dir(the_dir, parse_settings = FALSE, show_progress = TRUE),
"======",
fixed = TRUE
)
})

test_that("lint all relevant directories in a package", {
Expand Down
Loading

0 comments on commit 33fd6d4

Please sign in to comment.