Skip to content

Commit 66cd43e

Browse files
add dry argument: either write back, fail on change or don't fail on change
1 parent d872f45 commit 66cd43e

26 files changed

+371
-79
lines changed

API

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ create_style_guide(initialize = default_style_guide_attributes, line_break = NUL
1010
default_style_guide_attributes(pd_flat)
1111
specify_math_token_spacing(zero = "'^'", one = c("'+'", "'-'", "'*'", "'/'"))
1212
specify_reindention(regex_pattern = NULL, indention = 0, comments_only = TRUE)
13-
style_dir(path = ".", ..., style = tidyverse_style, transformers = style(...), filetype = c("R", "Rprofile"), recursive = TRUE, exclude_files = NULL, exclude_dirs = c("packrat", "renv"), include_roxygen_examples = TRUE)
14-
style_file(path, ..., style = tidyverse_style, transformers = style(...), include_roxygen_examples = TRUE)
15-
style_pkg(pkg = ".", ..., style = tidyverse_style, transformers = style(...), filetype = c("R", "Rprofile"), exclude_files = "R/RcppExports.R", exclude_dirs = c("packrat", "renv"), include_roxygen_examples = TRUE)
13+
style_dir(path = ".", ..., style = tidyverse_style, transformers = style(...), filetype = c("R", "Rprofile"), recursive = TRUE, exclude_files = NULL, exclude_dirs = c("packrat", "renv"), include_roxygen_examples = TRUE, dry = "off")
14+
style_file(path, ..., style = tidyverse_style, transformers = style(...), include_roxygen_examples = TRUE, dry = "off")
15+
style_pkg(pkg = ".", ..., style = tidyverse_style, transformers = style(...), filetype = c("R", "Rprofile"), exclude_files = "R/RcppExports.R", exclude_dirs = c("packrat", "renv"), include_roxygen_examples = TRUE, dry = "off")
1616
style_text(text, ..., style = tidyverse_style, transformers = style(...), include_roxygen_examples = TRUE)
1717
tidyverse_math_token_spacing()
1818
tidyverse_reindention()

R/io.R

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,56 @@
11
#' Apply a function to the contents of a file
22
#'
33
#' Transforms a file with a function.
4-
#' @param path A vector with file paths to transform.
5-
#' @param fun A function that returns a character vector.
6-
#' @param write_back Whether or not the results of the transformation should
7-
#' be written back to the file.
84
#' @importFrom magrittr set_names
95
#' @importFrom rlang abort
6+
#' @inheritParams transform_utf8_one
107
#' @keywords internal
11-
transform_utf8 <- function(path, fun, write_back = TRUE) {
12-
map_lgl(path, transform_utf8_one, fun = fun, write_back = write_back) %>%
8+
transform_utf8 <- function(path, fun, dry) {
9+
map_lgl(path, transform_utf8_one, fun = fun, dry = dry) %>%
1310
set_names(path)
1411
}
1512

13+
#' Potentially transform a file
14+
#'
15+
#' @param path A vector with file paths to transform.
16+
#' @param fun A function that returns a character vector.
17+
#' @param dry To indicate whether styler should run in *dry* mode, i.e. refrain
18+
#' from write back to files .`"on"` and `"fail"` both don't write back, the
19+
#' latter returns an error if styling *would* change contents. "off", the
20+
#' default, writes back if the input and output of styling are not identical.
1621
#' @importFrom rlang with_handlers warn
17-
transform_utf8_one <- function(path, fun, write_back) {
22+
#' @keywords internal
23+
transform_utf8_one <- function(path, fun, dry) {
24+
rlang::arg_match(dry, c("on", "off", "fail"))
1825
with_handlers(
1926
{
2027
file_with_info <- read_utf8(path)
2128
# only write back when changed OR when there was a missing newline
2229
new <- fun(file_with_info$text)
2330
identical_content <- identical(unclass(file_with_info$text), unclass(new))
2431
identical <- identical_content && !file_with_info$missing_EOF_line_break
25-
if (!identical && write_back) {
26-
xfun::write_utf8(new, path)
32+
if (!identical) {
33+
if (dry == "fail") {
34+
rlang::abort(
35+
paste0("File `", path, "` would be modified by styler and `dry` = 'fail'."),
36+
class = "dryError"
37+
)
38+
} else if (dry == "on") {
39+
# don't do anything
40+
} else if (dry == "off") {
41+
xfun::write_utf8(new, path)
42+
} else {
43+
# not implemented
44+
}
2745
}
2846
!identical
2947
},
3048
error = function(e) {
31-
warn(paste0("When processing ", path, ": ", conditionMessage(e)))
49+
if (inherits(e, "dryError")) {
50+
rlang::abort(conditionMessage(e))
51+
} else {
52+
warn(paste0("When processing ", path, ": ", conditionMessage(e)))
53+
}
3254
NA
3355
}
3456
)

R/testing.R

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#' @importFrom rlang abort
2121
#' @keywords internal
2222
test_collection <- function(test, sub_test = NULL,
23-
write_back = TRUE,
23+
dry = "off",
2424
write_tree = NA,
2525
transformer,
2626
...) {
@@ -49,7 +49,7 @@ test_collection <- function(test, sub_test = NULL,
4949
pwalk(list(in_items, out_items, in_names, out_names, out_trees),
5050
transform_and_check,
5151
transformer = transformer,
52-
write_back = write_back,
52+
dry = dry,
5353
write_tree = write_tree,
5454
...
5555
)
@@ -87,20 +87,19 @@ construct_tree <- function(in_paths, suffix = "_tree") {
8787
#' @param in_name The label of the in_item, defaults to `in_item`.
8888
#' @param out_name The label of the out_item, defaults to `out_item`.
8989
#' @param transformer A function to apply to the content of `in_item`.
90-
#' @param write_back Whether the results of the transformation should be written
91-
#' to the output file.
9290
#' @param write_tree Whether or not the tree structure of the test should be
9391
#' computed and written to a file. Note that this needs R >= 3.2
9492
#' (see [set_arg_write_tree()]). If the argument is set to `NA`, the function
9593
#' determines whether R >= 3.2 is in use and if so, trees will be written.
9694
#' @param ... Parameters passed to transformer function.
9795
#' @param out_tree Name of tree file if written out.
96+
#' @inheritParams transform_utf8
9897
#' @importFrom utils write.table
9998
#' @importFrom rlang warn
10099
#' @keywords internal
101100
transform_and_check <- function(in_item, out_item,
102101
in_name = in_item, out_name = out_item,
103-
transformer, write_back,
102+
transformer, dry,
104103
write_tree = NA,
105104
out_tree = "_tree", ...) {
106105
write_tree <- set_arg_write_tree(write_tree)
@@ -121,7 +120,7 @@ transform_and_check <- function(in_item, out_item,
121120
transformed <- transform_utf8(
122121
out_item,
123122
function(x) transformed_text,
124-
write_back = write_back
123+
dry = dry
125124
)
126125

127126
if (transformed) {
@@ -234,17 +233,19 @@ copy_to_tempdir <- function(path_perm = testthat_file()) {
234233
#' first run.
235234
#' @keywords internal
236235
n_times_faster_with_cache <- function(x1, x2 = x1, ...,
237-
fun = styler::style_text,
238-
n = 3,
239-
clear = "always") {
236+
fun = styler::style_text,
237+
n = 3,
238+
clear = "always") {
240239
rlang::arg_match(clear, c("always", "final", "never", "all but last"))
241240
capture.output(
242241
out <- purrr::map(1:n, n_times_faster_bench,
243242
x1 = x1, x2 = x2, fun = fun,
244-
..., n = n, clear = clear) %>%
245-
purrr::map_dbl(
246-
~ unname(.x$first["elapsed"] / .x$second["elapsed"])) %>%
247-
mean()
243+
..., n = n, clear = clear
244+
) %>%
245+
purrr::map_dbl(
246+
~ unname(.x$first["elapsed"] / .x$second["elapsed"])
247+
) %>%
248+
mean()
248249
)
249250
if (clear %in% c("always", "final")) {
250251
clear_testthat_cache()
@@ -267,7 +268,7 @@ n_times_faster_bench <- function(i, x1, x2, fun, ..., n, clear) {
267268
}
268269
list(
269270
first = first,
270-
second = second
271+
second = second
271272
)
272273
}
273274

@@ -320,4 +321,3 @@ fresh_testthat_cache <- function() {
320321
clear_testthat_cache()
321322
activate_testthat_cache()
322323
}
323-

R/transform-code.R

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,18 @@
88
#' @param ... Further arguments passed to [transform_utf8()].
99
#' @importFrom rlang abort
1010
#' @keywords internal
11-
transform_code <- function(path, fun, ...) {
11+
transform_code <- function(path, fun, ..., dry) {
1212
if (is_plain_r_file(path) || is_rprofile_file(path)) {
13-
transform_utf8(path, fun = fun, ...)
13+
transform_utf8(path, fun = fun, ..., dry = dry)
1414
} else if (is_rmd_file(path)) {
1515
transform_utf8(path,
1616
fun = partial(transform_mixed, transformer_fun = fun, filetype = "Rmd"),
17-
...
17+
..., dry = dry
1818
)
1919
} else if (is_rnw_file(path)) {
2020
transform_utf8(path,
2121
fun = partial(transform_mixed, transformer_fun = fun, filetype = "Rnw"),
22-
...
22+
..., dry = dry
2323
)
2424
} else {
2525
abort(paste(path, "is not an R, Rmd or Rnw file"))

R/transform-files.R

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@
55
#' @param files A character vector with paths to the file that should be
66
#' transformed.
77
#' @inheritParams make_transformer
8+
#' @inheritParams transform_file
89
#' @section Value:
910
#' Invisibly returns a data frame that indicates for each file considered for
10-
#' styling whether or not it was actually changed.
11+
#' styling whether or not it was actually changed (or would be changed when
12+
#' `dry` is not "off").
1113
#' @keywords internal
12-
transform_files <- function(files, transformers, include_roxygen_examples) {
14+
transform_files <- function(files, transformers, include_roxygen_examples, dry) {
1315
transformer <- make_transformer(transformers, include_roxygen_examples)
1416
max_char <- min(max(nchar(files), 0), getOption("width"))
1517
len_files <- length(files)
@@ -18,7 +20,7 @@ transform_files <- function(files, transformers, include_roxygen_examples) {
1820
}
1921

2022
changed <- map_lgl(files, transform_file,
21-
fun = transformer, max_char_path = max_char
23+
fun = transformer, max_char_path = max_char, dry = dry
2224
)
2325
communicate_summary(changed, max_char)
2426
communicate_warning(changed, transformers)
@@ -34,7 +36,7 @@ transform_files <- function(files, transformers, include_roxygen_examples) {
3436
#' @param message_after The message to print after the path.
3537
#' @param message_after_if_changed The message to print after `message_after` if
3638
#' any file was transformed.
37-
#' @inheritParams transform_utf8
39+
#' @inheritParams transform_code
3840
#' @param ... Further arguments passed to [transform_utf8()].
3941
#' @keywords internal
4042
transform_file <- function(path,
@@ -43,7 +45,8 @@ transform_file <- function(path,
4345
message_before = "",
4446
message_after = " [DONE]",
4547
message_after_if_changed = " *",
46-
...) {
48+
...,
49+
dry) {
4750
char_after_path <- nchar(message_before) + nchar(path) + 1
4851
max_char_after_message_path <- nchar(message_before) + max_char_path + 1
4952
n_spaces_before_message_after <-
@@ -53,7 +56,7 @@ transform_file <- function(path,
5356
rep_char(" ", max(0L, n_spaces_before_message_after)),
5457
append = FALSE
5558
)
56-
changed <- transform_code(path, fun = fun, ...)
59+
changed <- transform_code(path, fun = fun, ..., dry = dry)
5760

5861
bullet <- ifelse(is.na(changed), "warning", ifelse(changed, "info", "tick"))
5962

R/ui-styling.R

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,7 @@ NULL
1919
#' @param transformers A set of transformer functions. This argument is most
2020
#' conveniently constructed via the `style` argument and `...`. See
2121
#' 'Examples'.
22-
#' @param filetype Vector of file extensions indicating which file types should
23-
#' be styled. Case is ignored, and the `.` is optional, e.g.
24-
#' `c(".R", ".Rmd")`, or `c("r", "rmd")`. Supported values (after
25-
#' standardization) are: "r", "rprofile", "rmd", "rnw".
26-
#' @param exclude_files Character vector with paths to files that should be
27-
#' excluded from styling.
28-
#' @param exclude_dirs Character vector with directories to exclude. Note that
29-
#' the default values were set for consistency with [style_dir()] and as
30-
#' these directories are anyways not styled.
31-
#' @param include_roxygen_examples Whether or not to style code in roxygen
32-
#' examples.
22+
#' @inheritParams prettify_pkg
3323
#' @section Warning:
3424
#' This function overwrites files (if styling results in a change of the
3525
#' code to be formatted). It is strongly suggested to only style files
@@ -78,20 +68,35 @@ style_pkg <- function(pkg = ".",
7868
filetype = c("R", "Rprofile"),
7969
exclude_files = "R/RcppExports.R",
8070
exclude_dirs = c("packrat", "renv"),
81-
include_roxygen_examples = TRUE) {
71+
include_roxygen_examples = TRUE,
72+
dry = "off") {
8273
pkg_root <- rprojroot::find_package_root_file(path = pkg)
8374
changed <- withr::with_dir(pkg_root, prettify_pkg(
8475
transformers,
85-
filetype, exclude_files, exclude_dirs, include_roxygen_examples
76+
filetype, exclude_files, exclude_dirs, include_roxygen_examples, dry
8677
))
8778
invisible(changed)
8879
}
8980

81+
#' Prettify a package
82+
#'
83+
#' @param filetype Vector of file extensions indicating which file types should
84+
#' be styled. Case is ignored, and the `.` is optional, e.g.
85+
#' `c(".R", ".Rmd")`, or `c("r", "rmd")`. Supported values (after
86+
#' standardization) are: "r", "rprofile", "rmd", "rnw".
87+
#' @param exclude_files Character vector with paths to files that should be
88+
#' excluded from styling.
89+
#' @param exclude_dirs Character vector with directories to exclude. Note that
90+
#' the default values were set for consistency with [style_dir()] and as
91+
#' these directories are anyways not styled.
92+
#' @inheritParams transform_files
93+
#' @keywords internal
9094
prettify_pkg <- function(transformers,
9195
filetype,
9296
exclude_files,
9397
exclude_dirs,
94-
include_roxygen_examples) {
98+
include_roxygen_examples,
99+
dry) {
95100
filetype <- set_and_assert_arg_filetype(filetype)
96101
r_files <- rprofile_files <- vignette_files <- readme <- NULL
97102
exclude_files <- set_arg_paths(exclude_files)
@@ -137,7 +142,7 @@ prettify_pkg <- function(transformers,
137142
c(r_files, rprofile_files, vignette_files, readme),
138143
exclude_files
139144
)
140-
transform_files(files, transformers, include_roxygen_examples)
145+
transform_files(files, transformers, include_roxygen_examples, dry)
141146
}
142147

143148
#' Style a string
@@ -194,11 +199,13 @@ style_dir <- function(path = ".",
194199
recursive = TRUE,
195200
exclude_files = NULL,
196201
exclude_dirs = c("packrat", "renv"),
197-
include_roxygen_examples = TRUE) {
202+
include_roxygen_examples = TRUE,
203+
dry = "off") {
198204
changed <- withr::with_dir(
199205
path, prettify_any(
200206
transformers,
201-
filetype, recursive, exclude_files, exclude_dirs, include_roxygen_examples
207+
filetype, recursive, exclude_files, exclude_dirs,
208+
include_roxygen_examples, dry
202209
)
203210
)
204211
invisible(changed)
@@ -216,7 +223,8 @@ prettify_any <- function(transformers,
216223
recursive,
217224
exclude_files,
218225
exclude_dirs,
219-
include_roxygen_examples) {
226+
include_roxygen_examples,
227+
dry) {
220228
exclude_files <- set_arg_paths(exclude_files)
221229
exclude_dirs <- set_arg_paths(exclude_dirs)
222230
files_root <- dir(
@@ -236,7 +244,7 @@ prettify_any <- function(transformers,
236244
}
237245
transform_files(
238246
setdiff(c(files_root, files_other), exclude_files),
239-
transformers, include_roxygen_examples
247+
transformers, include_roxygen_examples, dry
240248
)
241249
}
242250

@@ -266,8 +274,9 @@ style_file <- function(path,
266274
...,
267275
style = tidyverse_style,
268276
transformers = style(...),
269-
include_roxygen_examples = TRUE) {
277+
include_roxygen_examples = TRUE,
278+
dry = "off") {
270279
path <- set_arg_paths(path)
271-
changed <- transform_files(path, transformers, include_roxygen_examples)
280+
changed <- transform_files(path, transformers, include_roxygen_examples, dry)
272281
invisible(changed)
273282
}

0 commit comments

Comments
 (0)