Skip to content

Commit 7edac16

Browse files
authored
Merge 9e9611b into 8029e1f
2 parents 8029e1f + 9e9611b commit 7edac16

File tree

4 files changed

+90
-3
lines changed

4 files changed

+90
-3
lines changed

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,12 @@
3636
* `unnecessary_lambda_linter` is extended to encourage vectorized comparisons where possible, e.g. `sapply(x, sum) > 0` instead of `sapply(x, function(x) sum(x) > 0)` (part of #884, @MichaelChirico). Toggle this behavior with argument `allow_comparison`.
3737
* `backport_linter()` is slightly faster by moving expensive computations outside the linting function (#2339, #2348, @AshesITR and @MichaelChirico).
3838
* `Linter()` has a new argument `linter_level` (default `NA`). This is used by `lint()` to more efficiently check for expression levels than the idiom `if (!is_lint_level(...)) { return(list()) }` (#2351, @AshesITR).
39+
* `use_lintr()` adds the created `.lintr` file to the `.Rbuildignore` if run in a package (#1805, @MEO265).
3940
* `string_boundary_linter()` recognizes regular expression calls like `grepl("^abc$", x)` that can be replaced by using `==` instead (#1613, @MichaelChirico).
4041
* `unreachable_code_linter()` has an argument `allow_comment_regex` for customizing which "terminal" comments to exclude (#2327, @MichaelChirico). `# nolint end` comments are always excluded, as are {covr} exclusions (e.g. `# nocov end`) by default.
4142
* `format()` and `print()` methods for `lint` and `lints` classes get a new option `width` to control the printing width of lint messages (#1884, @MichaelChirico). The default is controlled by a new option `lintr.format_width`; if unset, no wrapping occurs (matching earlier behavior).
4243

44+
4345
### New linters
4446

4547
* `condition_call_linter()` for ensuring consistent use of `call.` in `warning()` and `stop()`. The default `call. = FALSE` follows the tidyverse guidance of not displaying the call (#2226, @Bisaloo)

R/use_lintr.R

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#' Use lintr in your project
22
#'
3-
#' Create a minimal lintr config file as a starting point for customization
3+
#' Create a minimal lintr config file as a starting point for customization and add it to the .Rbuildignore
44
#'
55
#' @param path Path to project root, where a `.lintr` file should be created.
66
#' If the `.lintr` file already exists, an error will be thrown.
@@ -25,7 +25,7 @@
2525
#' lintr::lint_dir()
2626
#' }
2727
use_lintr <- function(path = ".", type = c("tidyverse", "full")) {
28-
config_file <- normalizePath(file.path(path, lintr_option("linter_file")), mustWork = FALSE)
28+
config_file <- normalizePath(file.path(path, lintr_option("linter_file")), mustWork = FALSE, winslash = "/")
2929
if (file.exists(config_file)) {
3030
stop("Found an existing configuration file at '", config_file, "'.", call. = FALSE)
3131
}
@@ -43,5 +43,37 @@ use_lintr <- function(path = ".", type = c("tidyverse", "full")) {
4343
)
4444
)
4545
write.dcf(the_config, config_file, width = Inf)
46+
47+
if (file.exists(file.path(path, "DESCRIPTION"))) {
48+
# Some OS can only normalize a path if the associated file or folder exists, so the path needs to be re-normalized
49+
tryCatch({
50+
pkg_path <- normalizePath(path, mustWork = TRUE, winslash = "/")
51+
config_file <- normalizePath(file.path(path, lintr_option("linter_file")), mustWork = TRUE, winslash = "/")
52+
}, error = function(e) {
53+
stop("No entry could be added to the .Rbuildignore.", call. = FALSE)
54+
})
55+
# Check if config_file is in package i.e. lintr_option("linter_file") != "../.lintr"
56+
if (startsWith(config_file, prefix = pkg_path)) {
57+
# Skip a extra character for the leading `/`
58+
rel_path <- substring(config_file, first = nchar(pkg_path) + 2L, last = nchar(config_file))
59+
ignore_path <- file.path(pkg_path, ".Rbuildignore")
60+
if (!file.exists(ignore_path)) file.create(ignore_path)
61+
# Follow the same procedure as base R to see if the file is already ignored
62+
ignore <- tryCatch({
63+
trimws(readLines(ignore_path))
64+
}, warning = function(e) {
65+
cat(file = ignore_path, "\n", append = TRUE)
66+
trimws(readLines(ignore_path))
67+
})
68+
ignore <- ignore[nzchar(ignore)]
69+
already_ignored <-
70+
any(vapply(ignore, FUN = grepl, x = rel_path, perl = TRUE, ignore.case = TRUE, FUN.VALUE = logical(1L)))
71+
if (!already_ignored) {
72+
cat(file = ignore_path, rex::rex(start, rel_path, end), sep = "\n", append = TRUE)
73+
message("Adding ", rel_path, " to .Rbuildignore")
74+
}
75+
}
76+
}
77+
4678
invisible(config_file)
4779
}

man/use_lintr.Rd

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-use_lintr.R

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,56 @@ test_that("use_lintr with type = full also works", {
3535
lints <- lint_dir(tmp)
3636
expect_length(lints, 0L)
3737
})
38+
39+
test_that("No .Rbuildignore is created of packages", {
40+
tmp <- withr::local_tempdir()
41+
42+
lintr_file <- use_lintr(path = tmp, type = "full")
43+
expect_false(file.exists(file.path(tmp, ".Rbuildignore")))
44+
})
45+
46+
test_that("No .Rbuildignore is filled outside of packages", {
47+
tmp <- withr::local_tempdir()
48+
ignore <- file.path(tmp, ".Rbuildignore")
49+
file.create(ignore)
50+
51+
lintr_file <- use_lintr(path = tmp, type = "full")
52+
expect_identical(readLines(ignore), character())
53+
})
54+
55+
test_that("No .Rbuildignore is filled if matching regex exists", {
56+
tmp <- withr::local_tempdir()
57+
file.create(file.path(tmp, "DESCRIPTION"))
58+
ignore <- file.path(tmp, ".Rbuildignore")
59+
file.create(ignore)
60+
cat(file = ignore, ".*", sep = "\n")
61+
62+
lintr_file <- use_lintr(path = tmp, type = "full")
63+
expect_identical(readLines(ignore), ".*")
64+
})
65+
66+
test_that("use_lintr creates the correct regex", {
67+
tmp <- withr::local_tempdir()
68+
file.create(file.path(tmp, "DESCRIPTION"))
69+
ignore <- file.path(tmp, ".Rbuildignore")
70+
file.create(ignore)
71+
cat(file = ignore, "^fu$", "^bar$", sep = "\n")
72+
73+
expect_message({
74+
lintr_file <- use_lintr(path = tmp, type = "full")
75+
}, regexp = "Adding .* to .Rbuildignore")
76+
expect_identical(readLines(ignore), c("^fu$", "^bar$", "^\\.lintr$"))
77+
})
78+
79+
test_that("use_lintr handles missing final new line", {
80+
tmp <- withr::local_tempdir()
81+
file.create(file.path(tmp, "DESCRIPTION"))
82+
ignore <- file.path(tmp, ".Rbuildignore")
83+
file.create(ignore)
84+
cat(file = ignore, "^fu$\n^bar$")
85+
86+
expect_message({
87+
lintr_file <- use_lintr(path = tmp, type = "full")
88+
}, regexp = "Adding .* to .Rbuildignore")
89+
expect_identical(readLines(ignore), c("^fu$", "^bar$", "^\\.lintr$"))
90+
})

0 commit comments

Comments
 (0)