diff --git a/.travis.yml b/.travis.yml index b807f9d6e..68273b8ea 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ # Usually you shouldn't need to change the first part of the file # DO NOT CHANGE THE CODE BELOW -before_install: R -q -e 'install.packages(c("remotes", "curl", "knitr", "rmarkdown")); remotes::install_github("ropenscilabs/tic"); tic::prepare_all_stages(); remotes::install_deps(dependencies = TRUE); if (isTRUE(as.logical(toupper(Sys.getenv("R_REMOVE_RCACHE"))))) remove.packages("R.cache"); tic::before_install()' +before_install: R -q -e 'install.packages(c("remotes", "curl", "knitr", "rmarkdown")); remotes::install_github("ropenscilabs/tic"); tic::prepare_all_stages(); remotes::install_deps(dependencies = TRUE); tic::before_install()' install: R -q -e 'tic::install()' after_install: R -q -e 'tic::after_install()' before_script: R -q -e 'tic::before_script()' @@ -38,9 +38,6 @@ matrix: - r: release env: - BUILD_PKGDOWN: true - - r: release - env: - - R_REMOVE_RCACHE: true - r: devel #env diff --git a/DESCRIPTION b/DESCRIPTION index ce13fc8b2..0c3a819e6 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -21,6 +21,7 @@ Imports: cli (>= 1.1.0), magrittr (>= 1.0.1), purrr (>= 0.2.3), + R.cache (>= 0.14.0), rematch2 (>= 2.0.1), rlang (>= 0.1.1), rprojroot (>= 1.1), @@ -35,7 +36,6 @@ Suggests: here, knitr, prettycode, - R.cache (>= 0.14.0), rmarkdown, rstudioapi (>= 0.7), testthat (>= 2.1.0) diff --git a/NEWS.md b/NEWS.md index 1ce334118..17132626a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,47 +1,48 @@ - -# styler 1.2.0.9000 +# styler 1.2.9001 ## Breaking changes -* `style_pkg()` and `style_dir()` gain a new argument `exclude_dirs` to exclude - directories from styling, by default `renv` and `packrat`. Note that the - defaults won't change the behavior of `style_pkg()` because it does anyways +* `style_pkg()` and `style_dir()` gain a new argument `exclude_dirs` to exclude + directories from styling, by default `renv` and `packrat`. Note that the + defaults won't change the behavior of `style_pkg()` because it does anyways does not style these directories and they were set for consistency. - -* `style_file()` and friends now strip `./` in file paths returned invisibly, + +* `style_file()` and friends now strip `./` in file paths returned invisibly, i.e. `./script.R` becomes `script.R` (#568). ## New features -* ignore certain lines using `# styler: off` and `#styler: on` or custom - markers, see `help("stylerignore")` (#560). +* ignore certain lines using `# styler: off` and `#styler: on` or custom + markers, see `?stylerignore` (#560). * styler caches results of styling, so applying styler to code it has styled before will be instantaneous. This brings large speed boosts in many situations, e.g. when `style_pkg()` is run but only a few files have changed since the last styling or when using the [styler pre-commit - hook](https://github.com/lorenzwalthert/precommit). Because styler caches - by expression, you will also get speed boosts in large files with many - expressions when you only change a few o them. See `help("caching")` for - details (#538, #578). - -* `create_style_guide()` gains two arguments `style_guide_name` and - `style_guide_version` that are carried as meta data, in particular to version - third-party style guides and ensure the proper functioning of caching. This + hook](https://github.com/lorenzwalthert/precommit). Because styler caches by + expression, you will also get speed boosts in large files with many + expressions when you only change a few of them. See `?caching` for details + (#538, #578). + +* `create_style_guide()` gains two arguments `style_guide_name` and + `style_guide_version` that are carried as meta data, in particular to version + third-party style guides and ensure the proper functioning of caching. This change is completely invisible to users who don't create and distribute their own style guide like `tidyverse_style()` (#572). - ## Minor changes and fixes * lines are now broken after `+` in `ggplot2` calls for `strict = TRUE` (#569). * function documentation now contains many more line breaks due to roxygen2 update to version 7.0.1 (#566). - + * spaces next to the braces in subsetting expressions `[` and `[[` are now removed (#580). +* Adapt to changes in the R parser to make styler pass R CMD check again. + (#583). + # styler 1.2.0 ## Breaking changes @@ -51,17 +52,17 @@ This is also reflected in the invisible return value of the function (#522). * `style_file()` and friends do not write content back to a file when styling - does not cause any changes in the file. This means the modification date of + does not cause any changes in the file. This means the modification date of styled files is only changed when the content is changed (#532). ## New features -* Aligned function calls are detected and remain unchanged if they match the styler - [definition for aligned function +* Aligned function calls are detected and remain unchanged if they match the + styler [definition for aligned function calls](https://styler.r-lib.org/articles/detect-alignment.html) (#537). -* curly-curly (`{{`) syntactic sugar introduced with rlang 0.4.0 is now - explicitly handled, where previously it was just treated as two consecutive +* curly-curly (`{{`) syntactic sugar introduced with rlang 0.4.0 is now + explicitly handled, where previously it was just treated as two consecutive curly braces (#528). * `style_pkg()`, `style_dir()` and the Addins can now style `.Rprofile`, and @@ -69,15 +70,15 @@ ## Minor improvements and fixes -* Brace expressions in function calls are formatted in a less compact way to +* Brace expressions in function calls are formatted in a less compact way to improve readability. Typical use case: `tryCatch()` (#543). -* Arguments in function declarations in a context which is indented multiple +* Arguments in function declarations in a context which is indented multiple times should now be correct. This typically affects `R6::R6Class()` (#546). * Escape characters in roxygen code examples are now correctly escaped (#512). -* Special characters such as `\n` in strings are now preserved in text and not +* Special characters such as `\n` in strings are now preserved in text and not turned into literal values like a line break (#554). * Style selection Addin now preserves line break when the last line selected is diff --git a/R/communicate.R b/R/communicate.R index 344673f99..3e9328b8a 100644 --- a/R/communicate.R +++ b/R/communicate.R @@ -34,37 +34,3 @@ assert_data.tree_installation <- function() { abort("The package data.tree needs to be installed for this functionality.") } } - -#' Assert the R.cache installation in conjunction with the cache config -#' -#' R.cache needs to be installed if caching functionality is enabled -#' @param installation_only Whether or not to only check if R.cache is -#' installed. -#' @keywords internal -assert_R.cache_installation <- function(installation_only = FALSE, - action = "abort") { - # fail if R.cache is not installed but feature is actiavted. - if (!rlang::is_installed("R.cache") && - ifelse(installation_only, TRUE, cache_is_activated()) - ) { - msg_basic <- paste( - "R package R.cache is not installed, which is needed when the caching ", - "feature is activated. Please install the package with ", - "`install.packages('R.cache')` and then restart R to enable the ", - "caching feature of styler or permanently deactivate the feature by ", - "adding `styler::cache_deactivate()` to your .Rprofile, e.g. via ", - "`usethis::edit_r_profile()`.", - sep = "" - ) - - if (action == "abort") { - rlang::abort(msg_basic) - } else { - rlang::warn(paste0( - msg_basic, " ", - "Deactivating the caching feature for the current session." - )) - cache_deactivate(verbose = FALSE) - } - } -} diff --git a/R/transform-files.R b/R/transform-files.R index bbb305de8..68e44f428 100644 --- a/R/transform-files.R +++ b/R/transform-files.R @@ -78,12 +78,9 @@ make_transformer <- function(transformers, warn_empty = TRUE) { force(transformers) assert_transformers(transformers) - assert_R.cache_installation(action = "warn") - - is_R.cache_installed <- rlang::is_installed("R.cache") function(text) { - should_use_cache <- is_R.cache_installed && cache_is_activated() + should_use_cache <- cache_is_activated() if (should_use_cache) { use_cache <- is_cached(text, transformers) diff --git a/R/ui-caching.R b/R/ui-caching.R index dabd5ad41..90aec6d1a 100644 --- a/R/ui-caching.R +++ b/R/ui-caching.R @@ -14,7 +14,6 @@ #' @family cache managers #' @export cache_clear <- function(cache_name = NULL, ask = TRUE) { - assert_R.cache_installation(installation_only = TRUE) path_cache <- cache_find_path(cache_name) R.cache::clearCache(path_cache, prompt = ask) cache_deactivate(verbose = FALSE) @@ -23,15 +22,45 @@ cache_clear <- function(cache_name = NULL, ask = TRUE) { #' Remember the past to be quicker in the future #' -#' styler by default uses caching. It may prompt you to install the R package -#' `R.cache` the first time you want to use it. R.cache will also ask you to let -#' it create a permanent cache on your file system that styler will use. -#' This is needed if you want to cache across R sessions and not just within. +#' Caching makes styler faster on repeated styling. It does not cache input +#' but output code. That means if you style code that already complies to a +#' style guide and you have previously styled that code, it will be quicker. +#' Code is cached by expression and the cache is shared across all APIs (e.g. +#' `style_text()` and Addin. +#' +#' @section Setup: +#' styler by default uses caching, via the `{R.cache}` package. You will be +#' asked you to let it create a permanent cache on your file system that styler +#' will use in case it is not set that up already for another tool that +#' uses `{R.cache}`. We encourage users to let `{R.cache}` create a permanent +#' directory for caching, because otherwise, the cache is lost at restart of R. +#' +#' @section Non-interactive use: +#' Note that if you have never authorised `{R.cache}` to create the cache in a +#' permenent directory, it wil build the cache in a temporary directory. To +#' create a permenent cache, just open an interactive R session and type +#' `cache_info()`. You can see under `Location:` if a permanent directory is +#' used and if not, `{R.cache}` will ask you to create one the first time you +#' use `{R.cache}` in an R session. +#' +#' @section Invalidation: #' The cache is specific to a version of styler by default, because different #' versions potentially format code differently. This means after upgrading #' styler or a style guide you use, the cache will be re-built. +#' +#' @section Manage the cache: #' See [cache_info()], -#' [cache_activate()], [cache_clear()] for utilities to manage the cache. +#' [cache_activate()], [cache_clear()] for utilities to manage the cache. Since +#' we leverage `{R.cache}` to manage the cache, you can also use any `{R.cache}` +#' functionality to manipulate it. +#' +#' @section Using a cache for styler in CI/CD: +#' If you want to set up caching in a CI/CD pipeline, we suggest to set the +#' `{R.cache}` root path to a directory for which you have the cache enabled. +#' The former can be done with `R.cache::setCacheRootPath("/path/to/cache")`, +#' the latter can often be set in config files of CI/CD tools, e.g. see the +#' the [Travis documentation on caching](https://docs.travis-ci.com/user/caching). +#' #' @name caching NULL @@ -50,7 +79,6 @@ NULL #' @family cache managers #' @export cache_info <- function(cache_name = NULL, format = "both") { - assert_R.cache_installation(installation_only = TRUE) rlang::arg_match(format, c("tabular", "lucid", "both")) path_cache <- cache_find_path(cache_name) files <- list.files(path_cache, full.names = TRUE) @@ -92,7 +120,6 @@ cache_info <- function(cache_name = NULL, format = "both") { #' @family cache managers #' @export cache_activate <- function(cache_name = NULL, verbose = TRUE) { - assert_R.cache_installation(installation_only = TRUE) if (!is.null(cache_name)) { options("styler.cache_name" = cache_name) } else { diff --git a/README.Rmd b/README.Rmd index 4a5ca3b39..4c4319cc7 100644 --- a/README.Rmd +++ b/README.Rmd @@ -27,7 +27,7 @@ version](https://www.r-pkg.org/badges/version/styler)](https://cran.r-project.or The goal of styler is to provide non-invasive pretty-printing of R source code while adhering to the [tidyverse](https://style.tidyverse.org) formatting rules. -styler can be customized to format code according to other style guides too. +styler can be customized to format code according to other style guides too. The following online docs are available: @@ -35,15 +35,20 @@ The following online docs are available: - [GitHub development version](https://styler.r-lib.org/dev). - ## Installation -You can install the package from CRAN: +You can install the package from CRAN. ```{r, eval = FALSE} install.packages("styler") ``` +If you don't use styler interactively (i.e. not from the R prompt or Rstudio +Addin), make sure you authorise `{R.cache}` once to set up a permanent cache. +If you use it interactively, you will be asked to grant this permission once. +See `?caching` for details. + + Or get the development version from GitHub: ```{r, eval = FALSE} @@ -76,20 +81,6 @@ There are a few variants of `style_text()`: knitr::include_graphics("https://raw.githubusercontent.com/lorenzwalthert/some_raw_data/master/styler_0.1.gif") ``` -## Features - -* style roxygen2 code examples. - -* do not re-style [deliberate code - alignment](https://styler.r-lib.org/articles/detect-alignment.html). - -* [ignore some lines](https://styler.r-lib.org/reference/stylerignore.html) for - styling (GitHub development version). - -* [cache styled expressions](https://styler.r-lib.org/reference/caching.html) - for speed (GitHub development version). - - ## Configuration You can decide on the level of invasiveness with the scope argument. You can @@ -116,11 +107,24 @@ Note that compared to the default used above `scope = "tokens"`: While spaces still got styled (around `=` in `(x)`). -This was just the tip of the iceberg. To learn more about customization options -with the tidyverse style guide, see the [help file for `tidyverse_style](https://styler.r-lib.org/reference/tidyverse_style.html) for a -quick overview or the -[introductory vignette](https://styler.r-lib.org/articles/introducing_styler.html). +This was just the tip of the iceberg. To learn more about customization options +with the tidyverse style guide, see the [help file for +`tidyverse_style](https://styler.r-lib.org/reference/tidyverse_style.html) for a +quick overview or the [introductory +vignette](https://styler.r-lib.org/articles/introducing_styler.html). + +## Features + +* style roxygen2 code examples. + +* do not re-style [deliberate code + alignment](https://styler.r-lib.org/articles/detect-alignment.html). + +* [ignore some lines](https://styler.r-lib.org/dev/reference/stylerignore.html) + for styling. +* [cache styled + expressions](https://styler.r-lib.org/dev/reference/caching.html) for speed. ## Adaption of styler diff --git a/README.md b/README.md index 4816e8e9e..53bf3882b 100644 --- a/README.md +++ b/README.md @@ -25,12 +25,17 @@ The following online docs are available: ## Installation -You can install the package from CRAN: +You can install the package from CRAN. ``` r install.packages("styler") ``` +If you don’t use styler interactively (i.e. not from the R prompt or +Rstudio Addin), make sure you authorise `{R.cache}` once to set up a +permanent cache. If you use it interactively, you will be asked to grant +this permission once. See `?caching` for details. + Or get the development version from GitHub: ``` r @@ -65,21 +70,6 @@ region. -## Features - - - style roxygen2 code examples. - - - do not re-style [deliberate code - alignment](https://styler.r-lib.org/articles/detect-alignment.html). - - - [ignore some - lines](https://styler.r-lib.org/reference/stylerignore.html) for - styling (GitHub development version). - - - [cache styled - expressions](https://styler.r-lib.org/reference/caching.html) for - speed (GitHub development version). - ## Configuration You can decide on the level of invasiveness with the scope argument. You @@ -115,6 +105,21 @@ options with the tidyverse style guide, see the [help file for for a quick overview or the [introductory vignette](https://styler.r-lib.org/articles/introducing_styler.html). +## Features + + - style roxygen2 code examples. + + - do not re-style [deliberate code + alignment](https://styler.r-lib.org/articles/detect-alignment.html). + + - [ignore some + lines](https://styler.r-lib.org/dev/reference/stylerignore.html) for + styling. + + - [cache styled + expressions](https://styler.r-lib.org/dev/reference/caching.html) + for speed. + ## Adaption of styler styler functionality is made available through other tools, most notably diff --git a/man/assert_R.cache_installation.Rd b/man/assert_R.cache_installation.Rd deleted file mode 100644 index 61f812c95..000000000 --- a/man/assert_R.cache_installation.Rd +++ /dev/null @@ -1,16 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/communicate.R -\name{assert_R.cache_installation} -\alias{assert_R.cache_installation} -\title{Assert the R.cache installation in conjunction with the cache config} -\usage{ -assert_R.cache_installation(installation_only = FALSE, action = "abort") -} -\arguments{ -\item{installation_only}{Whether or not to only check if R.cache is -installed.} -} -\description{ -R.cache needs to be installed if caching functionality is enabled -} -\keyword{internal} diff --git a/man/caching.Rd b/man/caching.Rd index 161be2076..c978e168e 100644 --- a/man/caching.Rd +++ b/man/caching.Rd @@ -4,13 +4,52 @@ \alias{caching} \title{Remember the past to be quicker in the future} \description{ -styler by default uses caching. It may prompt you to install the R package -\code{R.cache} the first time you want to use it. R.cache will also ask you to let -it create a permanent cache on your file system that styler will use. -This is needed if you want to cache across R sessions and not just within. +Caching makes styler faster on repeated styling. It does not cache input +but output code. That means if you style code that already complies to a +style guide and you have previously styled that code, it will be quicker. +Code is cached by expression and the cache is shared across all APIs (e.g. +\code{style_text()} and Addin. +} +\section{Setup}{ + +styler by default uses caching, via the \code{{R.cache}} package. You will be +asked you to let it create a permanent cache on your file system that styler +will use in case it is not set that up already for another tool that +uses \code{{R.cache}}. We encourage users to let \code{{R.cache}} create a permanent +directory for caching, because otherwise, the cache is lost at restart of R. +} + +\section{Non-interactive use}{ + +Note that if you have never authorised \code{{R.cache}} to create the cache in a +permenent directory, it wil build the cache in a temporary directory. To +create a permenent cache, just open an interactive R session and type +\code{cache_info()}. You can see under \verb{Location:} if a permanent directory is +used and if not, \code{{R.cache}} will ask you to create one the first time you +use \code{{R.cache}} in an R session. +} + +\section{Invalidation}{ + The cache is specific to a version of styler by default, because different versions potentially format code differently. This means after upgrading styler or a style guide you use, the cache will be re-built. +} + +\section{Manage the cache}{ + See \code{\link[=cache_info]{cache_info()}}, -\code{\link[=cache_activate]{cache_activate()}}, \code{\link[=cache_clear]{cache_clear()}} for utilities to manage the cache. +\code{\link[=cache_activate]{cache_activate()}}, \code{\link[=cache_clear]{cache_clear()}} for utilities to manage the cache. Since +we leverage \code{{R.cache}} to manage the cache, you can also use any \code{{R.cache}} +functionality to manipulate it. +} + +\section{Using a cache for styler in CI/CD}{ + +If you want to set up caching in a CI/CD pipeline, we suggest to set the +\code{{R.cache}} root path to a directory for which you have the cache enabled. +The former can be done with \code{R.cache::setCacheRootPath("/path/to/cache")}, +the latter can often be set in config files of CI/CD tools, e.g. see the +the \href{https://docs.travis-ci.com/user/caching}{Travis documentation on caching}. } + diff --git a/tests/testthat/test-cache-high-level-api.R b/tests/testthat/test-cache-high-level-api.R index 5e9dd9eb2..3daaf1091 100644 --- a/tests/testthat/test-cache-high-level-api.R +++ b/tests/testthat/test-cache-high-level-api.R @@ -1,5 +1,4 @@ capture.output(test_that("activated cache brings speedup on style_file() API", { - skip_if_not_installed("R.cache") on.exit(clear_testthat_cache()) clear_testthat_cache() activate_testthat_cache() @@ -25,7 +24,7 @@ text <- c( rep(10) capture.output(test_that("activated cache brings speedup on style_text() API on character vector", { - skip_if_not_installed("R.cache") + activate_testthat_cache() on.exit(clear_testthat_cache()) clear_testthat_cache() @@ -37,7 +36,7 @@ capture.output(test_that("activated cache brings speedup on style_text() API on })) capture.output(test_that("activated cache brings speedup on style_text() API on character scalar", { - skip_if_not_installed("R.cache") + activate_testthat_cache() on.exit(clear_testthat_cache()) clear_testthat_cache() @@ -50,7 +49,7 @@ capture.output(test_that("activated cache brings speedup on style_text() API on capture.output(test_that("no speedup when tranformer changes", { - skip_if_not_installed("R.cache") + activate_testthat_cache() on.exit(clear_testthat_cache()) clear_testthat_cache() @@ -68,7 +67,6 @@ capture.output( "activated cache brings speedup on style_text() API on ", "character scalar and character vector (mixed)" ), { - skip_if_not_installed("R.cache") activate_testthat_cache() on.exit(clear_testthat_cache()) clear_testthat_cache() @@ -81,7 +79,7 @@ capture.output( capture.output(test_that("unactivated cache does not bring speedup", { - skip_if_not_installed("R.cache") + on.exit(clear_testthat_cache()) clear_testthat_cache() cache_deactivate() @@ -93,7 +91,6 @@ capture.output(test_that("unactivated cache does not bring speedup", { capture.output(test_that("avoid deleting comments #584 (see commit messages)", { - skip_if_not_installed("R.cache") on.exit(clear_testthat_cache()) clear_testthat_cache() activate_testthat_cache() @@ -119,7 +116,6 @@ capture.output(test_that("avoid deleting comments #584 (see commit messages)", { capture.output(test_that("avoid removing roxygen mask (see commit messages in #584)", { - skip_if_not_installed("R.cache") on.exit(clear_testthat_cache()) clear_testthat_cache() activate_testthat_cache() diff --git a/tests/testthat/test-cache-with-r-cache.R b/tests/testthat/test-cache-with-r-cache.R index 1a35f3658..9f67e3781 100644 --- a/tests/testthat/test-cache-with-r-cache.R +++ b/tests/testthat/test-cache-with-r-cache.R @@ -1,24 +1,10 @@ - -capture.output(test_that("No warnings are issued when R.cache is installed", { - skip_if_not_installed("R.cache") - on.exit(clear_testthat_cache()) - expect_silent(assert_R.cache_installation(installation_only = TRUE)) - expect_silent(assert_R.cache_installation()) - expect_warning(style_text("1+1"), NA) - expect_warning(activate_testthat_cache(), NA) - expect_warning(style_text("1+1"), NA) - expect_silent(assert_R.cache_installation(installation_only = TRUE)) - expect_silent(assert_R.cache_installation()) -})) - -capture.output(test_that("Cache management works when R.cache is installed", { - skip_if_not_installed("R.cache") +capture.output(test_that("Cache management works", { on.exit(clear_testthat_cache()) clear_testthat_cache() # clearing a cache inactivates the caching functionality. expect_false(cache_info(format = "tabular")$activated) activate_testthat_cache() - # at fresh startup, with R.cache installed + # at fresh startup expect_s3_class(cache_info(format = "tabular"), "tbl_df") expect_error(cache_info(), NA) expect_equal(basename(cache_activate()), styler_version) diff --git a/tests/testthat/test-cache-without-r-cache.R b/tests/testthat/test-cache-without-r-cache.R deleted file mode 100644 index 7a70ce928..000000000 --- a/tests/testthat/test-cache-without-r-cache.R +++ /dev/null @@ -1,41 +0,0 @@ -test_that("Cache management fails mostly when R.cache is not installed", { - skip_if(rlang::is_installed("R.cache")) - expect_error(cache_info(), "is needed when the caching feature is activated") - expect_error(activate_testthat_cache(), "is needed when the caching feature is activated") - expect_error(cache_clear("testthat"), "is needed when the caching feature is activated") - expect_error(capture.output(cache_deactivate()), NA) - expect_silent(assert_R.cache_installation()) - expect_error( - assert_R.cache_installation(installation_only = TRUE), - "is needed when the caching feature is activated" - ) -}) - - -test_that("styling works when R.cache is not installed", { - skip_if(rlang::is_installed("R.cache")) - # warning for first time - expect_warning( - capture.output( - withr::with_options( - # simulate .onLoad() in fresh R session - list(styler.cache_name = cache_derive_name()), - style_text("1+1") - ) - ), - "Deactivating the caching feature for the current session" - ) - - # No warnings subsequently - expect_warning( - capture.output( - withr::with_options( - list(styler.cache_name = cache_derive_name()), { - suppressWarnings(style_text("1+1")) - style_text("1+1") - } - ) - ), - NA - ) -})