Skip to content

Commit 1c2c8a9

Browse files
Normalize output to Forward slash (#2613)
* Normalize to forward slash * add news * lint * Add `normalizePath()` to undesirable_functions * Use normalize_path everywhere and remove unneeded `fsep` * fix news typo * Use nolint + add comment * Address comments * less whitespace * even simpler --------- Co-authored-by: Michael Chirico <[email protected]>
1 parent 10de2ae commit 1c2c8a9

13 files changed

+35
-26
lines changed

.lintr

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ linters: all_linters(
1717
options = NULL,
1818
message = "use cli::cli_inform()",
1919
warning = "use cli::cli_warn()",
20-
stop = "use cli::cli_abort()"
20+
stop = "use cli::cli_abort()",
21+
normalizePath = "use normalize_path()"
2122
)),
2223
undesirable_operator_linter(modify_defaults(
2324
defaults = default_undesirable_operators,

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
* Drop support for posting GitHub comments from inside GitHub comment bot, Travis, Wercker, and Jenkins CI tools (spurred by #2148, @MichaelChirico). We rely on GitHub Actions for linting in CI, and don't see any active users relying on these alternatives. We welcome and encourage community contributions to get support for different CI system going again.
1818
* `cyclocomp_linter()` is no longer part of the default linters (#2555, @IndrajeetPatil) because the tidyverse style guide doesn't contain any guidelines on meeting certain complexity requirements. Note that users with `cyclocomp_linter()` in their configs may now need to install {cyclocomp} intentionally, in particular in CI/CD pipelines.
1919
* `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)
20+
* `lint()` and friends now normalize paths to forward slashes on Windows (@olivroy, #2613).
2021

2122
## Bug fixes
2223

R/exclude.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ normalize_exclusions <- function(x, normalize_path = TRUE,
326326
paths[rel_path] <- file.path(root, paths[rel_path])
327327
names(x) <- paths
328328
x <- x[file.exists(paths)] # remove exclusions for non-existing files
329-
names(x) <- normalizePath(names(x)) # get full path for remaining files
329+
names(x) <- normalize_path(names(x)) # get full path for remaining files
330330
}
331331

332332
remove_line_duplicates(

R/lint.R

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ lint <- function(filename, linters = NULL, ..., cache = FALSE, parse_settings =
5252
close(con)
5353
}
5454

55-
filename <- normalizePath(filename, mustWork = !inline_data) # to ensure a unique file in cache
55+
filename <- normalize_path(filename, mustWork = !inline_data) # to ensure a unique file in cache
5656
source_expressions <- get_source_expressions(filename, lines)
5757

5858
if (isTRUE(parse_settings)) {
@@ -163,9 +163,10 @@ lint_dir <- function(path = ".", ...,
163163
pattern = pattern
164164
)
165165

166-
# normalizePath ensures names(exclusions) and files have the same names for the same files.
166+
# normalize_path ensures names(exclusions) and files have the same names for the same files.
167+
# It also ensures all paths have forward slash
167168
# Otherwise on windows, files might incorrectly not be excluded in to_exclude
168-
files <- normalizePath(dir(
169+
files <- normalize_path(dir(
169170
path,
170171
pattern = pattern,
171172
recursive = TRUE,
@@ -198,7 +199,7 @@ lint_dir <- function(path = ".", ...,
198199
lints <- reorder_lints(lints)
199200

200201
if (relative_path) {
201-
path <- normalizePath(path, mustWork = FALSE)
202+
path <- normalize_path(path, mustWork = FALSE)
202203
lints[] <- lapply(
203204
lints,
204205
function(x) {
@@ -249,7 +250,7 @@ lint_package <- function(path = ".", ...,
249250

250251
if (is.null(pkg_path)) {
251252
cli_warn(c(
252-
i = "Didn't find any R package searching upwards from {.file {normalizePath(path)}}"
253+
i = "Didn't find any R package searching upwards from {.file {normalize_path(path)}}"
253254
))
254255
return(NULL)
255256
}
@@ -274,7 +275,7 @@ lint_package <- function(path = ".", ...,
274275
)
275276

276277
if (isTRUE(relative_path)) {
277-
path <- normalizePath(pkg_path, mustWork = FALSE)
278+
path <- normalize_path(pkg_path, mustWork = FALSE)
278279
lints[] <- lapply(
279280
lints,
280281
function(x) {

R/path_utils.R

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,12 @@ split_path <- function(dirs, prefix) {
133133
dirs[nzchar(dirs)]
134134
}
135135

136+
#' Simple wrapper around normalizePath to ensure forward slash on Windows
137+
#' https://github.com/r-lib/lintr/pull/2613
138+
#' @noRd
139+
# nolint next: undesirable_function_linter, object_name_linter.
140+
normalize_path <- function(path, mustWork = NA) normalizePath(path = path, winslash = "/", mustWork = mustWork)
141+
136142
#' @include utils.R
137143
path_linter_factory <- function(path_function, message, linter, name = linter_auto_name()) {
138144
force(name)

R/settings_utils.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ has_rproj <- function(path) {
88
}
99

1010
find_package <- function(path, allow_rproj = FALSE, max_depth = 2L) {
11-
path <- normalizePath(path, mustWork = !allow_rproj)
11+
path <- normalize_path(path, mustWork = !allow_rproj)
1212
if (allow_rproj) {
1313
found <- function(path) has_description(path) || has_rproj(path)
1414
} else {
@@ -68,7 +68,7 @@ find_config <- function(filename) {
6868
dirname(filename)
6969
}
7070

71-
path <- normalizePath(path, mustWork = FALSE)
71+
path <- normalize_path(path, mustWork = FALSE)
7272

7373
# NB: This vector specifies a priority order for where to find the configs,
7474
# i.e. the first location where a config exists is chosen and configs which

R/use_lintr.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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 <- normalize_path(file.path(path, lintr_option("linter_file")), mustWork = FALSE)
2929
if (file.exists(config_file)) {
3030
cli_abort("Found an existing configuration file at {.file {config_file}}.")
3131
}

tests/testthat/test-cache.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ test_that("cache = TRUE workflow works", {
437437
# Need a test structure with a safe to load .lintr
438438
withr::local_dir(file.path("dummy_packages", "package"))
439439
withr::local_options(lintr.linter_file = "lintr_test_config")
440-
files <- normalizePath(list.files(recursive = TRUE, full.names = TRUE))
440+
files <- normalize_path(list.files(recursive = TRUE, full.names = TRUE))
441441

442442
# Manually clear cache (that function is exported)
443443
for (f in files) {

tests/testthat/test-lint.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ test_that("lint() results from file or text should be consistent", {
118118
lines <- c("x<-1", "x+1")
119119
file <- withr::local_tempfile(lines = lines)
120120
text <- paste(lines, collapse = "\n")
121-
file <- normalizePath(file)
121+
file <- normalize_path(file)
122122

123123
lint_from_file <- lint(file, linters = linters)
124124
lint_from_lines <- lint(linters = linters, text = lines)

tests/testthat/test-lint_dir.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ test_that("respects directory exclusions", {
7171
lints_norm <- lint_dir(the_dir, exclusions = "exclude-me", relative_path = FALSE)
7272
linted_files <- unique(names(lints_norm))
7373
expect_length(linted_files, 1L)
74-
expect_identical(linted_files, normalizePath(file.path(the_dir, "default_linter_testcode.R")))
74+
expect_identical(linted_files, normalize_path(file.path(the_dir, "default_linter_testcode.R")))
7575
})
7676

7777
test_that("respect directory exclusions from settings", {

tests/testthat/test-normalize_exclusions.R

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ a <- withr::local_tempfile()
88
b <- withr::local_tempfile()
99
c <- withr::local_tempfile(tmpdir = ".")
1010
file.create(a, b, c)
11-
a <- normalizePath(a)
12-
b <- normalizePath(b)
13-
c <- normalizePath(c)
11+
a <- normalize_path(a)
12+
b <- normalize_path(b)
13+
c <- normalize_path(c)
1414

1515
test_that("it merges two NULL or empty objects as an empty list", {
1616
expect_identical(lintr:::normalize_exclusions(c(NULL, NULL)), list())
@@ -132,7 +132,7 @@ test_that("it normalizes file paths, removing non-existing files", {
132132
t3[[c]] <- 5L:15L
133133
res <- list()
134134
res[[a]] <- list(1L:10L)
135-
res[[normalizePath(c)]] <- list(5L:15L)
135+
res[[c]] <- list(5L:15L)
136136
expect_identical(lintr:::normalize_exclusions(c(t1, t2, t3)), res)
137137

138138
res <- list()

tests/testthat/test-settings.R

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,12 @@ test_that("it has a smart default for encodings", {
117117
pkg_file <- test_path("dummy_packages", "cp1252", "R", "cp1252.R")
118118

119119
expect_identical(
120-
normalizePath(find_rproj_at(find_package(proj_file, allow_rproj = TRUE)), winslash = "/"),
121-
normalizePath(test_path("dummy_projects", "project", "project.Rproj"), winslash = "/")
120+
normalize_path(find_rproj_at(find_package(proj_file, allow_rproj = TRUE))),
121+
normalize_path(test_path("dummy_projects", "project", "project.Rproj"))
122122
)
123123
expect_identical(
124-
normalizePath(find_package(pkg_file), winslash = "/"),
125-
normalizePath(test_path("dummy_packages", "cp1252"), winslash = "/")
124+
normalize_path(find_package(pkg_file)),
125+
normalize_path(test_path("dummy_packages", "cp1252"))
126126
)
127127

128128
expect_identical(lintr:::find_default_encoding(proj_file), "ISO8859-1")

tests/testthat/test-use_lintr.R

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ test_that("use_lintr works as expected", {
66

77
# check that newly created file is in the root directory
88
expect_identical(
9-
normalizePath(lintr_file, winslash = "/"),
10-
file.path(normalizePath(tmp, winslash = "/"), ".lintr")
9+
normalize_path(lintr_file),
10+
file.path(normalize_path(tmp), ".lintr")
1111
)
1212

1313
# can't generate if a .lintr already exists
@@ -28,8 +28,8 @@ test_that("use_lintr with type = full also works", {
2828

2929
# check that newly created file is in the root directory
3030
expect_identical(
31-
normalizePath(lintr_file, winslash = "/"),
32-
file.path(normalizePath(tmp, winslash = "/"), ".lintr")
31+
normalize_path(lintr_file),
32+
file.path(normalize_path(tmp), ".lintr")
3333
)
3434

3535
lints <- lint_dir(tmp)

0 commit comments

Comments
 (0)