diff --git a/.Rbuildignore b/.Rbuildignore index f8befe49f..831696c22 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -1,3 +1,5 @@ +^renv$ +^renv\.lock$ ^README\.Rmd$ ^.*\.Rproj$ ^\.Rproj\.user$ diff --git a/.github/workflows/hook-tests.yaml b/.github/workflows/hook-tests.yaml new file mode 100644 index 000000000..bbd729110 --- /dev/null +++ b/.github/workflows/hook-tests.yaml @@ -0,0 +1,126 @@ +on: + push: + branches: + - master + pull_request: + branches: + - master + +name: Hook tests + +jobs: + hook-test: + runs-on: ${{ matrix.config.os }} + + name: ${{ matrix.config.os }} (${{ matrix.config.r }}) + + strategy: + fail-fast: false + matrix: + config: + - {os: macOS-latest, r: 'release'} + - {os: windows-latest, r: 'release'} + - {os: ubuntu-18.04, r: 'release', rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest", http-user-agent: "R/4.0.0 (ubuntu-18.04) R (4.0.0 x86_64-pc-linux-gnu x86_64 linux-gnu) on GitHub Actions" } + env: + RSPM: ${{ matrix.config.rspm }} + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + + steps: + - uses: actions/checkout@v2 + - uses: r-lib/actions/setup-r@master + with: + r-version: ${{ matrix.config.r }} + http-user-agent: ${{ matrix.config.http-user-agent }} + - name: Query dependencies + run: | + writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version") + shell: Rscript {0} + - name: Cache R packages (macOs) + if: startsWith(runner.os, 'macOS') + uses: actions/cache@v2 + with: + path: ~/Library/Application Support/renv + key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-${{ hashFiles('renv.lock') }} + restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1- + - name: Cache R packages (Linux) + if: startsWith(runner.os, 'Linux') + uses: actions/cache@v2 + with: + path: ~/.local/share/renv + key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-${{ hashFiles('renv.lock') }} + restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1- + - name: Cache R packages (Windows) + if: startsWith(runner.os, 'Windows') + uses: actions/cache@v2 + with: + path: ~\AppData\Local\renv + key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-${{ hashFiles('renv.lock') }} + restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1- + + - name: Install system dependencies (Linux) + if: runner.os == 'Linux' + run: | + Rscript -e "install.packages('remotes', repos = Sys.getenv('RSPM'))" + while read -r cmd + do + eval sudo $cmd + done < <(Rscript -e 'cat(remotes::system_requirements("ubuntu", "18.04"), sep = "\n")') + - name: Prepare hook environment + run: | + source('renv/activate.R') + renv::restore() + renv::install(getwd(), dependencies = FALSE) + # needed to make sure renv is activated in run_test() + activate <- c( + "if (nzchar(Sys.getenv('R_PRECOMMIT_HOOK_ENV')))", + paste0("renv::load('", getwd(), "')") + ) + writeLines(activate, '~/.Rprofile') + shell: Rscript {0} + - name: Perpare testing environment + run: | + # testing dependencies (incl. {precommit}) live in global R library, + # hook dependencies in renv, which is only activated when child R + # process is invoked, e.g. as in run_test() + if (!requireNamespace("renv", quietly = TRUE)) { + install.packages("renv", repos = c(CRAN = "https://cloud.r-project.org")) + } + renv::install(c('testthat', 'devtools')) + # some testing infrastructure we need is in R/testing.R + renv::install(getwd(), dependencies = TRUE) + shell: Rscript {0} + - name: Session info (testing environment) + run: | + renv::install('sessioninfo', repos = 'cloud.r-project.org') + options(width = 100) + pkgs <- installed.packages()[, "Package"] + sessioninfo::session_info(pkgs, include_base = TRUE) + shell: Rscript {0} + - name: Test + run: | + devtools::load_all() + testthat::test_file( + "tests/testthat/test-hooks.R", + reporter = testthat::MultiReporter$new(list( + testthat::CheckReporter$new(), testthat::FailReporter$new() + )) + ) + shell: Rscript {0} + - name: Show testthat output + if: always() + run: find check -name 'testthat.Rout*' -exec cat '{}' \; || true + shell: bash + - name: Assert no leakage from testing to hook env (1/2) + run: | + Rscript -e "renv::install('usethis'); path_pkg <- file.path(tempdir(), 'someP'); usethis::create_package(path_pkg); renv::install(path_pkg)" + - name: Assert no leakage from testing to hook env (2/2) + env: + R_PRECOMMIT_HOOK_ENV: "1" + run: | + Rscript -e "if ('someP' %in% rownames(installed.packages())) stop('environment isolation not working: You installed a package into the testing environment and it is available in the hook environment')" + - name: Upload check results + if: failure() + uses: actions/upload-artifact@main + with: + name: ${{ runner.os }}-r${{ matrix.config.r }}-results + path: check diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b103df18c..bb4035eed 100755 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,11 +3,15 @@ default_stages: ["commit"] repos: - repo: https://github.com/lorenzwalthert/precommit - rev: v0.1.3 + rev: acc8657498d5bfb9e9891098ba00b36e82c7ebd6 hooks: - id: style-files args: [--style_pkg=styler, --style_fun=tidyverse_style] - exclude: '^tests/testthat/in/.*\.R' + exclude: > + (?x)^( + tests/testthat/in/.*\.R| + renv/.* + )$ - id: roxygenize # codemeta must be above use-tidy-description when both are used # - id: codemeta-description-updated diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 818390905..6e69987bb 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -1,51 +1,59 @@ - id: roxygenize name: roxygenize description: run roxygen2::roxygenize() - entry: inst/bin/roxygenize - language: script + entry: Rscript inst/bin/roxygenize + language: r files: '^(R|man)/' + require_serial: true + minimum_pre_commit_version: "2.12" - id: use-tidy-description name: use-tidy-description description: run usethis::use_tidy_description() - entry: inst/bin/use-tidy-description - language: script + entry: Rscript inst/bin/use-tidy-description + language: r files: '^DESCRIPTION$' + minimum_pre_commit_version: "2.12" - id: style-files name: style-files description: style files with styler - entry: inst/bin/style-files - language: script + entry: Rscript inst/bin/style-files + language: r files: '(\.R|\.Rmd|\.Rnw|\.r|\.rmd|\.rnw)$' exclude: 'renv/activate\.R' + minimum_pre_commit_version: "2.12" - id: no-browser-statement name: no-browser-statement description: check if a .R file contains a `browser()` statement - entry: inst/bin/no-browser-statement - language: script + entry: Rscript inst/bin/no-browser-statement + language: r files: '\.[rR]$' + minimum_pre_commit_version: "2.12" - id: parsable-R name: parsable-R description: check if a .R file is parsable - entry: inst/bin/parsable-R - language: script + entry: Rscript inst/bin/parsable-R + language: r files: '\.[rR]$' + minimum_pre_commit_version: "2.12" - id: readme-rmd-rendered name: readme-rmd-rendered description: make sure README.Rmd hasn't been edited more recently than README.md entry: inst/bin/readme-rmd-rendered language: script files: 'README\.[Rr]?md$' + minimum_pre_commit_version: "2.12" - id: codemeta-description-updated name: codemeta-description-updated description: make sure codemeta.json is in sync with DESCRIPTION. It should be run after use-tidy-description. - entry: inst/bin/codemeta-description-updated - language: script + entry: Rscript inst/bin/codemeta-description-updated + language: r files: '^DESCRIPTION$' + minimum_pre_commit_version: "2.12" - id: spell-check name: spell-check description: perform a spell check with spelling::spell_check_files() - entry: inst/bin/spell-check - language: script + entry: Rscript inst/bin/spell-check + language: r exclude: > (?x)^( data/.*| @@ -70,17 +78,20 @@ .*\.RData )$ require_serial: true + minimum_pre_commit_version: "2.12" - id: deps-in-desc name: deps-in-desc description: Check if dependencies that can be parsed from code are in DESCRIPTION. - entry: inst/bin/deps-in-desc - language: script + entry: Rscript inst/bin/deps-in-desc + language: r files: '(\.[rR]profile|\.R|\.Rmd|\.Rnw|\.r|\.rmd|\.rnw)$' exclude: 'renv/activate\.R' + minimum_pre_commit_version: "2.12" - id: lintr name: lintr description: check if a .R file is lint free (using lintr) - entry: inst/bin/lintr - language: script + entry: Rscript inst/bin/lintr + language: r files: '\.[rR]$' exclude: 'renv/activate\.R' + minimum_pre_commit_version: "2.12" diff --git a/DESCRIPTION b/DESCRIPTION index c50e0bcfa..3b43f61db 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -3,11 +3,11 @@ Title: Pre-Commit Hooks Version: 0.1.3.9000 Author: Lorenz Walthert Maintainer: Lorenz Walthert -Description: Useful git hooks for R building on top of the - multi-language framework 'pre-commit' for hook management. This - package provides git hooks for common tasks like formatting files with - 'styler' or spell checking as well as wrapper functions to access the - 'pre-commit' executable. +Description: Useful git hooks for R building on top of the multi-language + framework 'pre-commit' for hook management. This package provides git + hooks for common tasks like formatting files with 'styler' or spell + checking as well as wrapper functions to access the 'pre-commit' + executable. License: GPL-3 URL: https://lorenzwalthert.github.io/precommit/, https://github.com/lorenzwalthert/precommit @@ -41,8 +41,8 @@ VignetteBuilder: Remotes: r-lib/styler Encoding: UTF-8 -Roxygen: list(markdown = TRUE, roclets = c( "rd", "namespace", - "collate", if (rlang::is_installed("pkgapi")) "pkgapi::api_roclet" - else { warning("Please install r-lib/pkgapi to make sure the file API - is kept up to date"); NULL} ) ) -RoxygenNote: 7.1.1 +Roxygen: list(markdown = TRUE, roclets = c( "rd", "namespace", "collate", + if (rlang::is_installed("pkgapi")) "pkgapi::api_roclet" else { + warning("Please install r-lib/pkgapi to make sure the file API is kept + up to date"); NULL} ) ) +RoxygenNote: 7.1.1.9001 diff --git a/NEWS.md b/NEWS.md index fa8dbf763..843036831 100644 --- a/NEWS.md +++ b/NEWS.md @@ -12,6 +12,13 @@ `{R.cache}` cache set up. You can silence the warning with the hook argument `--no-warn-cache` (#225). +**Major Changes** + +- {precommit} now uses [`language: r`](https://pre-commit.com/#r) instead of + `language: script` from the [pre-commit framework](https://pre-commit.com). + This requires `pre-commit >= 2.11.1`. All hooks and dependencies are now + contained in a virtual environment with [`{renv}`](https://rstudio.github.io/renv/) + (#233). **Minor changes** diff --git a/R/setup.R b/R/setup.R index e1a5fcccb..6dcb10fba 100644 --- a/R/setup.R +++ b/R/setup.R @@ -1,6 +1,6 @@ -#' Set up pre-commit +#' Get started with pre-commit #' -#' Get started. +#' This function sets up pre-commit for your git repo. #' @param install_hooks Whether to install environments for all available hooks. #' If `FALSE`, environments are installed with first commit. #' @param legacy_hooks How to treat hooks already in the repo which are not diff --git a/R/testing.R b/R/testing.R index aa7455e4b..351213ceb 100644 --- a/R/testing.R +++ b/R/testing.R @@ -1,7 +1,8 @@ #' Run a test #' #' Tests for the executables used as pre-commit hooks via `entrypoint` in -#' `.pre-commit-config.yaml`. +#' `.pre-commit-config.yaml`. Set's the env variable `R_PRECOMMIT_HOOK_ENV` to +#' when running. #' @details #' Two potential outcomes of a hooks are pass or fail. This is reflected on the #' level of the executable: Fail means the executable fails or the file is @@ -15,7 +16,6 @@ #' executable. To check for failed executable, we set `error_msg` to #' the message we expect. To check changed file content, we set `error_msg` to #' `NA`. -#' #' @param hook_name The name of the hook in `bin/`. #' @param file_name The file to test in `tests/in` (without extension). #' @param suffix The suffix of `file_name`. @@ -39,6 +39,7 @@ run_test <- function(hook_name, copy = NULL, file_transformer = function(files) files, env = character()) { + withr::local_envvar(list(R_PRECOMMIT_HOOK_ENV = "1")) path_executable <- system.file( fs::path("bin", hook_name), package = "precommit" @@ -87,7 +88,7 @@ run_test_impl <- function(path_executable, tempdir <- fs::dir_create(fs::file_temp()) if (!is.null(copy)) { if (is.null(names(copy))) { - # no names, take basename + # not namesm take directory name new_dirs <- fs::path(tempdir, fs::path_dir(copy)) fs::dir_create(new_dirs) paths_copy <- fs::path(new_dirs, fs::path_file(copy)) diff --git a/README.Rmd b/README.Rmd index 63fa0a472..69e5c28d4 100644 --- a/README.Rmd +++ b/README.Rmd @@ -19,7 +19,8 @@ knitr::opts_chunk$set( status](https://www.r-pkg.org/badges/version/precommit)](https://CRAN.R-project.org/package=precommit) [![Lifecycle: experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://www.tidyverse.org/lifecycle/#experimental) -[![R build status](https://github.com/lorenzwalthert/precommit/workflows/R-CMD-check/badge.svg)](https://github.com/lorenzwalthert/precommit/actions) +[![R build +status](https://github.com/lorenzwalthert/precommit/workflows/R-CMD-check/badge.svg)](https://github.com/lorenzwalthert/precommit/actions) [Pre-commit hooks](https://pre-commit.com) are tests that run each time you @@ -29,7 +30,8 @@ forgotten a comma, brace or quote. The goal of this package is to twofold: -- Provide a [set of hooks](https://lorenzwalthert.github.io/precommit/articles/available-hooks.html) +- Provide a [set of + hooks](https://lorenzwalthert.github.io/precommit/articles/available-hooks.html) that are useful when your git repo contains R code. - Provide [usethis](https://github.com/r-lib/usethis)-like functionality for @@ -39,7 +41,14 @@ The following online docs are available: - [latest CRAN release](https://lorenzwalthert.github.io/precommit/). -- [GitHub development version](https://lorenzwalthert.github.io/precommit/dev/). +- [GitHub development + version](https://lorenzwalthert.github.io/precommit/dev/). + +These only cover the functionality added on top of the pre-commit framework by +this package. Everything else is covered in the extensive [online +documentation](https://pre-commit.com) of the pre-commit framework itself, +including how to create hooks for actions like `git push` or `git checkout`, +create local hooks etc. ## Installation @@ -50,21 +59,22 @@ install.packages("precommit") ``` To access pre-commit functionality from R, you also need to install the -[pre-commit framework](https://pre-commit.com). The following command line methods are tested to work with -this R package (and accessing them from outside R is easier and use is slightly faster): +[pre-commit framework](https://pre-commit.com) on which the hook from this repo +build. The following command line methods are tested to work with this R package +(and accessing them from outside R is easier and use is slightly faster): -- `$ pip3 install pre-commit --user` (macOS, Linux and Windows) **outside** a +- `$ pip3 install pre-commit --user` (macOS, Linux and Windows) **outside** a conda or virtual environment. - `$ brew install pre-commit` (macOS). -Alternatively, you can handle the installation from R using +Alternatively, you can handle the installation from R using [miniconda](https://docs.conda.io/en/latest/miniconda.html): -- install miniconda if you don't have it already: `reticulate::install_miniconda()`. - This needs reticulate >= 1.14. +- install miniconda if you don't have it already: + `reticulate::install_miniconda()`. This needs reticulate >= 1.14. -- install the pre-commit framework with `precommit::install_precommit()` into +- install the pre-commit framework with `precommit::install_precommit()` into the conda environment `r-precommit`. Do not install other packages into this environment. @@ -92,14 +102,14 @@ function `precommit::open_config()` let's you open and edit the `.pre-commit-config.yaml` conveniently from the RStudio console. When any file is changed due to running a hook or the hook script errors, the commit will fail. You can inspect the changes introduced by the hook and if satisfied, you -can add the changes made by the hook to the index with `git add path/to/file` -and attempt to commit again. Some hooks change files, like the styler hook, so -all you need to do to make the hook pass is `git add` the changes -introduced by the hook. Other hooks, like the parsable-R hook, will need -your action, e.g. add a missing closing brace to a call like `library(styler`, -before they pass at the next attempt. If all hooks pass, the commit is made. You -can also [temporarily disable hooks](https://pre-commit.com/#temporarily-disabling-hooks). -If you succeed, it should look like this: +can add the changes made by the hook to the index with `git add path/to/file` +and attempt to commit again. Some hooks change files, like the styler hook, so +all you need to do to make the hook pass is `git add` the changes introduced by +the hook. Other hooks, like the parsable-R hook, will need your action, e.g. add +a missing closing brace to a call like `library(styler`, before they pass at the +next attempt. If all hooks pass, the commit is made. You can also [temporarily +disable hooks](https://pre-commit.com/#temporarily-disabling-hooks). If you +succeed, it should look like this: ```{r, echo = FALSE, eval = TRUE} knitr::include_graphics("man/figures/screenshot.png") @@ -120,53 +130,25 @@ To update the hook revisions, run `precommit::autoupdate()`. ## Caution -- **Do not abort while hooks are running in RStudio git tab.** Non-staged - changes are stashed to a temp directory and when you abort in RStudio, these - changes are not brought back to you repo. Upvote [this - issue](https://github.com/rstudio/rstudio/issues/6471) to change this. We hope - that in the future, the changes will be recovered in RStudio too. Note that - this is only an issue with RStudio. Stashes are restored when you abort a `git - commit` with `INT` (e.g. Ctrl+C) on the command line. To restore stashes, - manually after hitting *abort* in the RStudio git tab, you can `git - apply /path/to/patch_with_id` whereas you find the patch under your pre-commit - cache, which is usually under `$HOME/.cache/pre-commit/`. - -- Because R is not officially supported as a language in the pre-commit - framework (yet), there is no R package dependency management for the R hooks - provided in this repo. If an R package that is needed by a hook is not yet - installed, you might get this error: - -```{r} -# > Error in loadNamespace(name) : there is no package called ‘__name_of_package__’ -``` - In that case, just install the package with `install.packages()` once and - try to commit again. - All R dependencies of the pre-commit hooks provided in this repo are suggested - dependencies of this R package, so if you want to install them all, just - `install.packages("precommit", dependencies = c("Imports", "Suggests"))`. - -## Documentation - -The [online -documentation](https://lorenzwalthert.github.io/precommit/index.html) of this -package only covers the functionality added on top of pre-commit by this -package. Everything else is covered in the extensive [online -documentation](https://pre-commit.com) of the pre-commit framework itself, -including how to: - -- create pre-push hooks - -- create local hooks - -- and more +**Do not abort while hooks are running in RStudio git tab.** Non-staged changes +are stashed to a temp directory and when you abort in RStudio, these changes are +not brought back to you repo. Upvote [this +issue](https://github.com/rstudio/rstudio/issues/6471) to change this. We hope +that in the future, the changes will be recovered in RStudio too. Note that this +is only an issue with RStudio. Stashes are restored when you abort a `git +commit` with `INT` (e.g. Ctrl+C) on the command line. To restore stashes, +manually after hitting *abort* in the RStudio git tab, you can `git apply +/path/to/patch_with_id` whereas you find the patch under your pre-commit cache, +which is usually under `$HOME/.cache/pre-commit/`. ## Update -To update the pre-commit executable, use the update utilities provided by -your installation method. If you chose conda, you can use +To update the pre-commit executable, use the update utilities provided by your +installation method. If you chose conda, you can use `precommit::update_precommit()`. -You can check the version of you executable with `precommit::version_precommit()`. +You can check the version of you executable with +`precommit::version_precommit()`. ## Uninstallation diff --git a/README.md b/README.md index 6219db7de..f8bfa7ba2 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,12 @@ The following online docs are available: - [GitHub development version](https://lorenzwalthert.github.io/precommit/dev/). +These only cover the functionality added on top of the pre-commit +framework by this package. Everything else is covered in the extensive +[online documentation](https://pre-commit.com) of the pre-commit +framework itself, including how to create hooks for actions like +`git push` or `git checkout`, create local hooks etc. + ## Installation You can install the package from CRAN: @@ -44,9 +50,10 @@ install.packages("precommit") ``` To access pre-commit functionality from R, you also need to install the -[pre-commit framework](https://pre-commit.com). The following command -line methods are tested to work with this R package (and accessing them -from outside R is easier and use is slightly faster): +[pre-commit framework](https://pre-commit.com) on which the hook from +this repo build. The following command line methods are tested to work +with this R package (and accessing them from outside R is easier and use +is slightly faster): - `$ pip3 install pre-commit --user` (macOS, Linux and Windows) **outside** a conda or virtual environment. @@ -114,49 +121,17 @@ To update the hook revisions, run `precommit::autoupdate()`. ## Caution -- **Do not abort while hooks are running in RStudio git tab.** - Non-staged changes are stashed to a temp directory and when you - abort in RStudio, these changes are not brought back to you repo. - Upvote [this issue](https://github.com/rstudio/rstudio/issues/6471) - to change this. We hope that in the future, the changes will be - recovered in RStudio too. Note that this is only an issue with - RStudio. Stashes are restored when you abort a `git commit` with - `INT` (e.g. Ctrl+C) on the command line. To restore stashes, - manually after hitting *abort* in the RStudio git tab, you can - `git apply /path/to/patch_with_id` whereas you find the patch - under your pre-commit cache, which is usually under - `$HOME/.cache/pre-commit/`. - -- Because R is not officially supported as a language in the - pre-commit framework (yet), there is no R package dependency - management for the R hooks provided in this repo. If an R package - that is needed by a hook is not yet installed, you might get this - error: - -``` r -# > Error in loadNamespace(name) : there is no package called ‘__name_of_package__’ -``` - -In that case, just install the package with `install.packages()` once -and try to commit again. All R dependencies of the pre-commit hooks -provided in this repo are suggested dependencies of this R package, so -if you want to install them all, just -`install.packages("precommit", dependencies = c("Imports", "Suggests"))`. - -## Documentation - -The [online -documentation](https://lorenzwalthert.github.io/precommit/index.html) of -this package only covers the functionality added on top of pre-commit by -this package. Everything else is covered in the extensive [online -documentation](https://pre-commit.com) of the pre-commit framework -itself, including how to: - -- create pre-push hooks - -- create local hooks - -- and more +**Do not abort while hooks are running in RStudio git tab.** Non-staged +changes are stashed to a temp directory and when you abort in RStudio, +these changes are not brought back to you repo. Upvote [this +issue](https://github.com/rstudio/rstudio/issues/6471) to change this. +We hope that in the future, the changes will be recovered in RStudio +too. Note that this is only an issue with RStudio. Stashes are restored +when you abort a `git commit` with `INT` (e.g. Ctrl+C) on the command +line. To restore stashes, manually after hitting *abort* in the RStudio +git tab, you can `git apply /path/to/patch_with_id` whereas you find the +patch under your pre-commit cache, which is usually under +`$HOME/.cache/pre-commit/`. ## Update diff --git a/inst/pre-commit-hooks.yaml b/inst/pre-commit-hooks.yaml index 818390905..6e69987bb 100644 --- a/inst/pre-commit-hooks.yaml +++ b/inst/pre-commit-hooks.yaml @@ -1,51 +1,59 @@ - id: roxygenize name: roxygenize description: run roxygen2::roxygenize() - entry: inst/bin/roxygenize - language: script + entry: Rscript inst/bin/roxygenize + language: r files: '^(R|man)/' + require_serial: true + minimum_pre_commit_version: "2.12" - id: use-tidy-description name: use-tidy-description description: run usethis::use_tidy_description() - entry: inst/bin/use-tidy-description - language: script + entry: Rscript inst/bin/use-tidy-description + language: r files: '^DESCRIPTION$' + minimum_pre_commit_version: "2.12" - id: style-files name: style-files description: style files with styler - entry: inst/bin/style-files - language: script + entry: Rscript inst/bin/style-files + language: r files: '(\.R|\.Rmd|\.Rnw|\.r|\.rmd|\.rnw)$' exclude: 'renv/activate\.R' + minimum_pre_commit_version: "2.12" - id: no-browser-statement name: no-browser-statement description: check if a .R file contains a `browser()` statement - entry: inst/bin/no-browser-statement - language: script + entry: Rscript inst/bin/no-browser-statement + language: r files: '\.[rR]$' + minimum_pre_commit_version: "2.12" - id: parsable-R name: parsable-R description: check if a .R file is parsable - entry: inst/bin/parsable-R - language: script + entry: Rscript inst/bin/parsable-R + language: r files: '\.[rR]$' + minimum_pre_commit_version: "2.12" - id: readme-rmd-rendered name: readme-rmd-rendered description: make sure README.Rmd hasn't been edited more recently than README.md entry: inst/bin/readme-rmd-rendered language: script files: 'README\.[Rr]?md$' + minimum_pre_commit_version: "2.12" - id: codemeta-description-updated name: codemeta-description-updated description: make sure codemeta.json is in sync with DESCRIPTION. It should be run after use-tidy-description. - entry: inst/bin/codemeta-description-updated - language: script + entry: Rscript inst/bin/codemeta-description-updated + language: r files: '^DESCRIPTION$' + minimum_pre_commit_version: "2.12" - id: spell-check name: spell-check description: perform a spell check with spelling::spell_check_files() - entry: inst/bin/spell-check - language: script + entry: Rscript inst/bin/spell-check + language: r exclude: > (?x)^( data/.*| @@ -70,17 +78,20 @@ .*\.RData )$ require_serial: true + minimum_pre_commit_version: "2.12" - id: deps-in-desc name: deps-in-desc description: Check if dependencies that can be parsed from code are in DESCRIPTION. - entry: inst/bin/deps-in-desc - language: script + entry: Rscript inst/bin/deps-in-desc + language: r files: '(\.[rR]profile|\.R|\.Rmd|\.Rnw|\.r|\.rmd|\.rnw)$' exclude: 'renv/activate\.R' + minimum_pre_commit_version: "2.12" - id: lintr name: lintr description: check if a .R file is lint free (using lintr) - entry: inst/bin/lintr - language: script + entry: Rscript inst/bin/lintr + language: r files: '\.[rR]$' exclude: 'renv/activate\.R' + minimum_pre_commit_version: "2.12" diff --git a/man/precommit-package.Rd b/man/precommit-package.Rd index 0e621f0a8..fb117b524 100644 --- a/man/precommit-package.Rd +++ b/man/precommit-package.Rd @@ -6,11 +6,11 @@ \alias{precommit-package} \title{precommit: Pre-Commit Hooks} \description{ -Useful git hooks for R building on top of the - multi-language framework 'pre-commit' for hook management. This - package provides git hooks for common tasks like formatting files with - 'styler' or spell checking as well as wrapper functions to access the - 'pre-commit' executable. +Useful git hooks for R building on top of the multi-language + framework 'pre-commit' for hook management. This package provides git + hooks for common tasks like formatting files with 'styler' or spell + checking as well as wrapper functions to access the 'pre-commit' + executable. } \seealso{ Useful links: diff --git a/man/run_test.Rd b/man/run_test.Rd index 319500cf7..f8da6b20e 100644 --- a/man/run_test.Rd +++ b/man/run_test.Rd @@ -53,7 +53,8 @@ made.} } \description{ Tests for the executables used as pre-commit hooks via \code{entrypoint} in -\code{.pre-commit-config.yaml}. +\code{.pre-commit-config.yaml}. Set's the env variable \code{R_PRECOMMIT_HOOK_ENV} to +when running. } \details{ Two potential outcomes of a hooks are pass or fail. This is reflected on the diff --git a/man/use_precommit.Rd b/man/use_precommit.Rd index 2fb7c293b..666137da4 100644 --- a/man/use_precommit.Rd +++ b/man/use_precommit.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/setup.R \name{use_precommit} \alias{use_precommit} -\title{Set up pre-commit} +\title{Get started with pre-commit} \usage{ use_precommit( config_source = getOption("precommit.config_source"), @@ -40,7 +40,7 @@ If \code{FALSE}, environments are installed with first commit.} \code{NULL} (invisibly). The function is called for its side effects. } \description{ -Get started. +This function sets up pre-commit for your git repo. } \section{When to call this function?}{ diff --git a/renv.lock b/renv.lock new file mode 100644 index 000000000..2fb36fdb8 --- /dev/null +++ b/renv.lock @@ -0,0 +1,651 @@ +{ + "R": { + "Version": "4.0.3", + "Repositories": [ + { + "Name": "CRAN", + "URL": "https://cran.rstudio.com" + } + ] + }, + "Packages": { + "Matrix": { + "Package": "Matrix", + "Version": "1.3-2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "ff280503079ad8623d3c4b1519b24ea2" + }, + "R.cache": { + "Package": "R.cache", + "Version": "0.14.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "1ca02d43e1a4d49e616bd23bb39b17e6" + }, + "R.methodsS3": { + "Package": "R.methodsS3", + "Version": "1.8.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "4bf6453323755202d5909697b6f7c109" + }, + "R.oo": { + "Package": "R.oo", + "Version": "1.24.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "5709328352717e2f0a9c012be8a97554" + }, + "R.utils": { + "Package": "R.utils", + "Version": "2.10.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "a9e316277ff12a43997266f2f6567780" + }, + "R6": { + "Package": "R6", + "Version": "2.5.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "b203113193e70978a696b2809525649d" + }, + "Rcpp": { + "Package": "Rcpp", + "Version": "1.0.6", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "dbb5e436998a7eba5a9d682060533338" + }, + "askpass": { + "Package": "askpass", + "Version": "1.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "e8a22846fff485f0be3770c2da758713" + }, + "backports": { + "Package": "backports", + "Version": "1.2.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "644043219fc24e190c2f620c1a380a69" + }, + "base64enc": { + "Package": "base64enc", + "Version": "0.1-3", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "543776ae6848fde2f48ff3816d0628bc" + }, + "brew": { + "Package": "brew", + "Version": "1.0-6", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "92a5f887f9ae3035ac7afde22ba73ee9" + }, + "brio": { + "Package": "brio", + "Version": "1.1.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "2f01e16ff9571fe70381c7b9ae560dc4" + }, + "callr": { + "Package": "callr", + "Version": "3.7.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "461aa75a11ce2400245190ef5d3995df" + }, + "cli": { + "Package": "cli", + "Version": "2.5.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "a94ba44cee3ea571e813721e64184172" + }, + "clipr": { + "Package": "clipr", + "Version": "0.7.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "ebaa97ac99cc2daf04e77eecc7b781d7" + }, + "codetools": { + "Package": "codetools", + "Version": "0.2-18", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "019388fc48e48b3da0d3a76ff94608a8" + }, + "commonmark": { + "Package": "commonmark", + "Version": "1.7", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "0f22be39ec1d141fd03683c06f3a6e67" + }, + "cpp11": { + "Package": "cpp11", + "Version": "0.2.7", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "730eebcc741a5c36761f7d4d0f5e37b8" + }, + "crayon": { + "Package": "crayon", + "Version": "1.4.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "e75525c55c70e5f4f78c9960a4b402e9" + }, + "credentials": { + "Package": "credentials", + "Version": "1.3.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "a96728288c75a814c900af9da84387be" + }, + "curl": { + "Package": "curl", + "Version": "4.3", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "2b7d10581cc730804e9ed178c8374bd6" + }, + "cyclocomp": { + "Package": "cyclocomp", + "Version": "1.1.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "53cbed70a2f7472d48fb6aef08442f25" + }, + "desc": { + "Package": "desc", + "Version": "1.3.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "b6963166f7f10b970af1006c462ce6cd" + }, + "diffobj": { + "Package": "diffobj", + "Version": "0.3.4", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "feb5b7455eba422a2c110bb89852e6a3" + }, + "digest": { + "Package": "digest", + "Version": "0.6.27", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "a0cbe758a531d054b537d16dff4d58a1" + }, + "docopt": { + "Package": "docopt", + "Version": "0.7.1", + "Source": "GitHub", + "RemoteType": "github", + "RemoteUsername": "docopt", + "RemoteRepo": "docopt.R", + "RemoteRef": "HEAD", + "RemoteSha": "ebdeb31d911584eab409799423edce3e48a85a2c", + "RemoteHost": "api.github.com", + "Hash": "29e92f2df5a13ca12520224b00a4f488" + }, + "ellipsis": { + "Package": "ellipsis", + "Version": "0.3.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "fd2844b3a43ae2d27e70ece2df1b4e2a" + }, + "evaluate": { + "Package": "evaluate", + "Version": "0.14", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "ec8ca05cffcc70569eaaad8469d2a3a7" + }, + "fansi": { + "Package": "fansi", + "Version": "0.4.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "fea074fb67fe4c25d47ad09087da847d" + }, + "fs": { + "Package": "fs", + "Version": "1.5.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "44594a07a42e5f91fac9f93fda6d0109" + }, + "gert": { + "Package": "gert", + "Version": "1.3.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "56f398846cd40937be6b435a66bd3f37" + }, + "gh": { + "Package": "gh", + "Version": "1.2.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "346cc58165d33da095c7e67487ec6bca" + }, + "git2r": { + "Package": "git2r", + "Version": "0.28.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "f64fd34026f6025de71a4354800e6d79" + }, + "gitcreds": { + "Package": "gitcreds", + "Version": "0.1.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "f3aefccc1cc50de6338146b62f115de8" + }, + "glue": { + "Package": "glue", + "Version": "1.4.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "6efd734b14c6471cfe443345f3e35e29" + }, + "here": { + "Package": "here", + "Version": "1.0.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "24b224366f9c2e7534d2344d10d59211" + }, + "highr": { + "Package": "highr", + "Version": "0.9", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "8eb36c8125038e648e5d111c0d7b2ed4" + }, + "htmltools": { + "Package": "htmltools", + "Version": "0.5.1.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "af2c2531e55df5cf230c4b5444fc973c" + }, + "httr": { + "Package": "httr", + "Version": "1.4.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "a525aba14184fec243f9eaec62fbed43" + }, + "hunspell": { + "Package": "hunspell", + "Version": "3.0.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "3987784c19192ad0f2261c456d936df1" + }, + "ini": { + "Package": "ini", + "Version": "0.3.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "6154ec2223172bce8162d4153cda21f7" + }, + "jsonlite": { + "Package": "jsonlite", + "Version": "1.7.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "98138e0994d41508c7a6b84a0600cfcb" + }, + "knitr": { + "Package": "knitr", + "Version": "1.33", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "0bc1b5da1b0eb07cd4b727e95e9ff0b8" + }, + "lattice": { + "Package": "lattice", + "Version": "0.20-41", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "fbd9285028b0263d76d18c95ae51a53d" + }, + "lazyeval": { + "Package": "lazyeval", + "Version": "0.2.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "d908914ae53b04d4c0c0fd72ecc35370" + }, + "lifecycle": { + "Package": "lifecycle", + "Version": "1.0.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "3471fb65971f1a7b2d4ae7848cf2db8d" + }, + "lintr": { + "Package": "lintr", + "Version": "2.0.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "023cecbdc0a32f86ad3cb1734c018d2e" + }, + "magrittr": { + "Package": "magrittr", + "Version": "2.0.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "41287f1ac7d28a92f0a286ed507928d3" + }, + "markdown": { + "Package": "markdown", + "Version": "1.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "61e4a10781dd00d7d81dd06ca9b94e95" + }, + "mime": { + "Package": "mime", + "Version": "0.10", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "26fa77e707223e1ce042b2b5d09993dc" + }, + "openssl": { + "Package": "openssl", + "Version": "1.4.3", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "a399e4773075fc2375b71f45fca186c4" + }, + "pillar": { + "Package": "pillar", + "Version": "1.6.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "a8c755912ae31910ba6a5d42f5526b6b" + }, + "pkgconfig": { + "Package": "pkgconfig", + "Version": "2.0.3", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "01f28d4278f15c76cddbea05899c5d6f" + }, + "pkgload": { + "Package": "pkgload", + "Version": "1.2.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "463642747f81879e6752485aefb831cf" + }, + "png": { + "Package": "png", + "Version": "0.1-7", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "03b7076c234cb3331288919983326c55" + }, + "praise": { + "Package": "praise", + "Version": "1.0.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "a555924add98c99d2f411e37e7d25e9f" + }, + "processx": { + "Package": "processx", + "Version": "3.5.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "5ee87b05936a4aa9d8d026eb1a51314b" + }, + "ps": { + "Package": "ps", + "Version": "1.6.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "32620e2001c1dce1af49c49dccbb9420" + }, + "purrr": { + "Package": "purrr", + "Version": "0.3.4", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "97def703420c8ab10d8f0e6c72101e02" + }, + "rappdirs": { + "Package": "rappdirs", + "Version": "0.3.3", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "5e3c5dc0b071b21fa128676560dbe94d" + }, + "rematch2": { + "Package": "rematch2", + "Version": "2.1.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "76c9e04c712a05848ae7a23d2f170a40" + }, + "remotes": { + "Package": "remotes", + "Version": "2.3.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "92ea77818b3bb83c699008451af32b86" + }, + "renv": { + "Package": "renv", + "Version": "0.13.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "079cb1f03ff972b30401ed05623cbe92" + }, + "reticulate": { + "Package": "reticulate", + "Version": "1.19", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "a793719f1b17126b503feef01ce63410" + }, + "rex": { + "Package": "rex", + "Version": "1.2.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "093584b944440c5cd07a696b3c8e0e4c" + }, + "rlang": { + "Package": "rlang", + "Version": "0.4.10", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "599df23c40a4fce9c7b4764f28c37857" + }, + "rmarkdown": { + "Package": "rmarkdown", + "Version": "2.7", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "edbf4cb1aefae783fd8d3a008ae51943" + }, + "roxygen2": { + "Package": "roxygen2", + "Version": "7.1.1.9001", + "Source": "GitHub", + "RemoteType": "github", + "RemoteUsername": "r-lib", + "RemoteRepo": "roxygen2", + "RemoteRef": "HEAD", + "RemoteSha": "23261728c184743ec2ab4322f5c6cb6f42bd4865", + "RemoteHost": "api.github.com", + "Hash": "796272644c17da61395c0977c0840cf6" + }, + "rprojroot": { + "Package": "rprojroot", + "Version": "2.0.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "249d8cd1e74a8f6a26194a91b47f21d1" + }, + "rstudioapi": { + "Package": "rstudioapi", + "Version": "0.13", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "06c85365a03fdaf699966cc1d3cf53ea" + }, + "spelling": { + "Package": "spelling", + "Version": "2.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "b8c899a5c83f0d897286550481c91798" + }, + "stringi": { + "Package": "stringi", + "Version": "1.5.3", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "a063ebea753c92910a4cca7b18bc1f05" + }, + "stringr": { + "Package": "stringr", + "Version": "1.4.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "0759e6b6c0957edb1311028a49a35e76" + }, + "styler": { + "Package": "styler", + "Version": "1.4.1.9001", + "Source": "GitHub", + "RemoteType": "github", + "RemoteUsername": "r-lib", + "RemoteRepo": "styler", + "RemoteRef": "HEAD", + "RemoteSha": "4250d57bd638e745dd7a09aee8cf49064d672a40", + "RemoteHost": "api.github.com", + "Hash": "c19fb6d7c036e4b733594db58061420c" + }, + "sys": { + "Package": "sys", + "Version": "3.4", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "b227d13e29222b4574486cfcbde077fa" + }, + "testthat": { + "Package": "testthat", + "Version": "3.0.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "495e0434d9305716b6a87031570ce109" + }, + "tibble": { + "Package": "tibble", + "Version": "3.1.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "fbbca141541ee9242233ba50b0fcb843" + }, + "tinytex": { + "Package": "tinytex", + "Version": "0.31", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "25b572f764f3c19fef9aac33b5724f3d" + }, + "usethis": { + "Package": "usethis", + "Version": "2.0.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "360e904f9e623286e1a0c6ca0a98c5f6" + }, + "utf8": { + "Package": "utf8", + "Version": "1.2.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "c3ad47dc6da0751f18ed53c4613e3ac7" + }, + "vctrs": { + "Package": "vctrs", + "Version": "0.3.7", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "5540dc30a203a43a1ce5dc6a89532b3b" + }, + "waldo": { + "Package": "waldo", + "Version": "0.2.5", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "20c45f1d511a3f730b7b469f4d11e104" + }, + "whisker": { + "Package": "whisker", + "Version": "0.4", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "ca970b96d894e90397ed20637a0c1bbe" + }, + "withr": { + "Package": "withr", + "Version": "2.4.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "ad03909b44677f930fa156d47d7a3aeb" + }, + "xfun": { + "Package": "xfun", + "Version": "0.22", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "eab2f8ba53809c321813e72ecbbd19ba" + }, + "xml2": { + "Package": "xml2", + "Version": "1.3.2", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "d4d71a75dd3ea9eb5fa28cc21f9585e2" + }, + "xmlparsedata": { + "Package": "xmlparsedata", + "Version": "1.0.5", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "45e4bf3c46476896e821fc0a408fb4fc" + }, + "yaml": { + "Package": "yaml", + "Version": "2.2.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "2826c5d9efb0a88f657c7a679c7106db" + }, + "zip": { + "Package": "zip", + "Version": "2.1.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "3bc8405c637d988801ec5ea88372d0c2" + } + } +} diff --git a/renv/.gitignore b/renv/.gitignore new file mode 100644 index 000000000..5246cf196 --- /dev/null +++ b/renv/.gitignore @@ -0,0 +1,5 @@ +local/ +library/ +lock/ +python/ +staging/ diff --git a/renv/activate.R b/renv/activate.R new file mode 100644 index 000000000..b852628d0 --- /dev/null +++ b/renv/activate.R @@ -0,0 +1,654 @@ + +local({ + + # the requested version of renv + version <- "0.13.2" + + # the project directory + project <- getwd() + + # avoid recursion + if (!is.na(Sys.getenv("RENV_R_INITIALIZING", unset = NA))) + return(invisible(TRUE)) + + # signal that we're loading renv during R startup + Sys.setenv("RENV_R_INITIALIZING" = "true") + on.exit(Sys.unsetenv("RENV_R_INITIALIZING"), add = TRUE) + + # signal that we've consented to use renv + options(renv.consent = TRUE) + + # load the 'utils' package eagerly -- this ensures that renv shims, which + # mask 'utils' packages, will come first on the search path + library(utils, lib.loc = .Library) + + # check to see if renv has already been loaded + if ("renv" %in% loadedNamespaces()) { + + # if renv has already been loaded, and it's the requested version of renv, + # nothing to do + spec <- .getNamespaceInfo(.getNamespace("renv"), "spec") + if (identical(spec[["version"]], version)) + return(invisible(TRUE)) + + # otherwise, unload and attempt to load the correct version of renv + unloadNamespace("renv") + + } + + # load bootstrap tools + bootstrap <- function(version, library) { + + # attempt to download renv + tarball <- tryCatch(renv_bootstrap_download(version), error = identity) + if (inherits(tarball, "error")) + stop("failed to download renv ", version) + + # now attempt to install + status <- tryCatch(renv_bootstrap_install(version, tarball, library), error = identity) + if (inherits(status, "error")) + stop("failed to install renv ", version) + + } + + renv_bootstrap_tests_running <- function() { + getOption("renv.tests.running", default = FALSE) + } + + renv_bootstrap_repos <- function() { + + # check for repos override + repos <- Sys.getenv("RENV_CONFIG_REPOS_OVERRIDE", unset = NA) + if (!is.na(repos)) + return(repos) + + # if we're testing, re-use the test repositories + if (renv_bootstrap_tests_running()) + return(getOption("renv.tests.repos")) + + # retrieve current repos + repos <- getOption("repos") + + # ensure @CRAN@ entries are resolved + repos[repos == "@CRAN@"] <- getOption( + "renv.repos.cran", + "https://cloud.r-project.org" + ) + + # add in renv.bootstrap.repos if set + default <- c(FALLBACK = "https://cloud.r-project.org") + extra <- getOption("renv.bootstrap.repos", default = default) + repos <- c(repos, extra) + + # remove duplicates that might've snuck in + dupes <- duplicated(repos) | duplicated(names(repos)) + repos[!dupes] + + } + + renv_bootstrap_download <- function(version) { + + # if the renv version number has 4 components, assume it must + # be retrieved via github + nv <- numeric_version(version) + components <- unclass(nv)[[1]] + + methods <- if (length(components) == 4L) { + list( + renv_bootstrap_download_github + ) + } else { + list( + renv_bootstrap_download_cran_latest, + renv_bootstrap_download_cran_archive + ) + } + + for (method in methods) { + path <- tryCatch(method(version), error = identity) + if (is.character(path) && file.exists(path)) + return(path) + } + + stop("failed to download renv ", version) + + } + + renv_bootstrap_download_impl <- function(url, destfile) { + + mode <- "wb" + + # https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17715 + fixup <- + Sys.info()[["sysname"]] == "Windows" && + substring(url, 1L, 5L) == "file:" + + if (fixup) + mode <- "w+b" + + utils::download.file( + url = url, + destfile = destfile, + mode = mode, + quiet = TRUE + ) + + } + + renv_bootstrap_download_cran_latest <- function(version) { + + spec <- renv_bootstrap_download_cran_latest_find(version) + + message("* Downloading renv ", version, " ... ", appendLF = FALSE) + + type <- spec$type + repos <- spec$repos + + info <- tryCatch( + utils::download.packages( + pkgs = "renv", + destdir = tempdir(), + repos = repos, + type = type, + quiet = TRUE + ), + condition = identity + ) + + if (inherits(info, "condition")) { + message("FAILED") + return(FALSE) + } + + # report success and return + message("OK (downloaded ", type, ")") + info[1, 2] + + } + + renv_bootstrap_download_cran_latest_find <- function(version) { + + # check whether binaries are supported on this system + binary <- + getOption("renv.bootstrap.binary", default = TRUE) && + !identical(.Platform$pkgType, "source") && + !identical(getOption("pkgType"), "source") && + Sys.info()[["sysname"]] %in% c("Darwin", "Windows") + + types <- c(if (binary) "binary", "source") + + # iterate over types + repositories + for (type in types) { + for (repos in renv_bootstrap_repos()) { + + # retrieve package database + db <- tryCatch( + as.data.frame( + utils::available.packages(type = type, repos = repos), + stringsAsFactors = FALSE + ), + error = identity + ) + + if (inherits(db, "error")) + next + + # check for compatible entry + entry <- db[db$Package %in% "renv" & db$Version %in% version, ] + if (nrow(entry) == 0) + next + + # found it; return spec to caller + spec <- list(entry = entry, type = type, repos = repos) + return(spec) + + } + } + + # if we got here, we failed to find renv + fmt <- "renv %s is not available from your declared package repositories" + stop(sprintf(fmt, version)) + + } + + renv_bootstrap_download_cran_archive <- function(version) { + + name <- sprintf("renv_%s.tar.gz", version) + repos <- renv_bootstrap_repos() + urls <- file.path(repos, "src/contrib/Archive/renv", name) + destfile <- file.path(tempdir(), name) + + message("* Downloading renv ", version, " ... ", appendLF = FALSE) + + for (url in urls) { + + status <- tryCatch( + renv_bootstrap_download_impl(url, destfile), + condition = identity + ) + + if (identical(status, 0L)) { + message("OK") + return(destfile) + } + + } + + message("FAILED") + return(FALSE) + + } + + renv_bootstrap_download_github <- function(version) { + + enabled <- Sys.getenv("RENV_BOOTSTRAP_FROM_GITHUB", unset = "TRUE") + if (!identical(enabled, "TRUE")) + return(FALSE) + + # prepare download options + pat <- Sys.getenv("GITHUB_PAT") + if (nzchar(Sys.which("curl")) && nzchar(pat)) { + fmt <- "--location --fail --header \"Authorization: token %s\"" + extra <- sprintf(fmt, pat) + saved <- options("download.file.method", "download.file.extra") + options(download.file.method = "curl", download.file.extra = extra) + on.exit(do.call(base::options, saved), add = TRUE) + } else if (nzchar(Sys.which("wget")) && nzchar(pat)) { + fmt <- "--header=\"Authorization: token %s\"" + extra <- sprintf(fmt, pat) + saved <- options("download.file.method", "download.file.extra") + options(download.file.method = "wget", download.file.extra = extra) + on.exit(do.call(base::options, saved), add = TRUE) + } + + message("* Downloading renv ", version, " from GitHub ... ", appendLF = FALSE) + + url <- file.path("https://api.github.com/repos/rstudio/renv/tarball", version) + name <- sprintf("renv_%s.tar.gz", version) + destfile <- file.path(tempdir(), name) + + status <- tryCatch( + renv_bootstrap_download_impl(url, destfile), + condition = identity + ) + + if (!identical(status, 0L)) { + message("FAILED") + return(FALSE) + } + + message("OK") + return(destfile) + + } + + renv_bootstrap_install <- function(version, tarball, library) { + + # attempt to install it into project library + message("* Installing renv ", version, " ... ", appendLF = FALSE) + dir.create(library, showWarnings = FALSE, recursive = TRUE) + + # invoke using system2 so we can capture and report output + bin <- R.home("bin") + exe <- if (Sys.info()[["sysname"]] == "Windows") "R.exe" else "R" + r <- file.path(bin, exe) + args <- c("--vanilla", "CMD", "INSTALL", "-l", shQuote(library), shQuote(tarball)) + output <- system2(r, args, stdout = TRUE, stderr = TRUE) + message("Done!") + + # check for successful install + status <- attr(output, "status") + if (is.numeric(status) && !identical(status, 0L)) { + header <- "Error installing renv:" + lines <- paste(rep.int("=", nchar(header)), collapse = "") + text <- c(header, lines, output) + writeLines(text, con = stderr()) + } + + status + + } + + renv_bootstrap_platform_prefix <- function() { + + # construct version prefix + version <- paste(R.version$major, R.version$minor, sep = ".") + prefix <- paste("R", numeric_version(version)[1, 1:2], sep = "-") + + # include SVN revision for development versions of R + # (to avoid sharing platform-specific artefacts with released versions of R) + devel <- + identical(R.version[["status"]], "Under development (unstable)") || + identical(R.version[["nickname"]], "Unsuffered Consequences") + + if (devel) + prefix <- paste(prefix, R.version[["svn rev"]], sep = "-r") + + # build list of path components + components <- c(prefix, R.version$platform) + + # include prefix if provided by user + prefix <- renv_bootstrap_platform_prefix_impl() + if (!is.na(prefix) && nzchar(prefix)) + components <- c(prefix, components) + + # build prefix + paste(components, collapse = "/") + + } + + renv_bootstrap_platform_prefix_impl <- function() { + + # if an explicit prefix has been supplied, use it + prefix <- Sys.getenv("RENV_PATHS_PREFIX", unset = NA) + if (!is.na(prefix)) + return(prefix) + + # if the user has requested an automatic prefix, generate it + auto <- Sys.getenv("RENV_PATHS_PREFIX_AUTO", unset = NA) + if (auto %in% c("TRUE", "True", "true", "1")) + return(renv_bootstrap_platform_prefix_auto()) + + # empty string on failure + "" + + } + + renv_bootstrap_platform_prefix_auto <- function() { + + prefix <- tryCatch(renv_bootstrap_platform_os(), error = identity) + if (inherits(prefix, "error") || prefix %in% "unknown") { + + msg <- paste( + "failed to infer current operating system", + "please file a bug report at https://github.com/rstudio/renv/issues", + sep = "; " + ) + + warning(msg) + + } + + prefix + + } + + renv_bootstrap_platform_os <- function() { + + sysinfo <- Sys.info() + sysname <- sysinfo[["sysname"]] + + # handle Windows + macOS up front + if (sysname == "Windows") + return("windows") + else if (sysname == "Darwin") + return("macos") + + # check for os-release files + for (file in c("/etc/os-release", "/usr/lib/os-release")) + if (file.exists(file)) + return(renv_bootstrap_platform_os_via_os_release(file, sysinfo)) + + # check for redhat-release files + if (file.exists("/etc/redhat-release")) + return(renv_bootstrap_platform_os_via_redhat_release()) + + "unknown" + + } + + renv_bootstrap_platform_os_via_os_release <- function(file, sysinfo) { + + # read /etc/os-release + release <- utils::read.table( + file = file, + sep = "=", + quote = c("\"", "'"), + col.names = c("Key", "Value"), + comment.char = "#", + stringsAsFactors = FALSE + ) + + vars <- as.list(release$Value) + names(vars) <- release$Key + + # get os name + os <- tolower(sysinfo[["sysname"]]) + + # read id + id <- "unknown" + for (field in c("ID", "ID_LIKE")) { + if (field %in% names(vars) && nzchar(vars[[field]])) { + id <- vars[[field]] + break + } + } + + # read version + version <- "unknown" + for (field in c("UBUNTU_CODENAME", "VERSION_CODENAME", "VERSION_ID", "BUILD_ID")) { + if (field %in% names(vars) && nzchar(vars[[field]])) { + version <- vars[[field]] + break + } + } + + # join together + paste(c(os, id, version), collapse = "-") + + } + + renv_bootstrap_platform_os_via_redhat_release <- function() { + + # read /etc/redhat-release + contents <- readLines("/etc/redhat-release", warn = FALSE) + + # infer id + id <- if (grepl("centos", contents, ignore.case = TRUE)) + "centos" + else if (grepl("redhat", contents, ignore.case = TRUE)) + "redhat" + else + "unknown" + + # try to find a version component (very hacky) + version <- "unknown" + + parts <- strsplit(contents, "[[:space:]]")[[1L]] + for (part in parts) { + + nv <- tryCatch(numeric_version(part), error = identity) + if (inherits(nv, "error")) + next + + version <- nv[1, 1] + break + + } + + paste(c("linux", id, version), collapse = "-") + + } + + renv_bootstrap_library_root_name <- function(project) { + + # use project name as-is if requested + asis <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT_ASIS", unset = "FALSE") + if (asis) + return(basename(project)) + + # otherwise, disambiguate based on project's path + id <- substring(renv_bootstrap_hash_text(project), 1L, 8L) + paste(basename(project), id, sep = "-") + + } + + renv_bootstrap_library_root <- function(project) { + + path <- Sys.getenv("RENV_PATHS_LIBRARY", unset = NA) + if (!is.na(path)) + return(path) + + path <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT", unset = NA) + if (!is.na(path)) { + name <- renv_bootstrap_library_root_name(project) + return(file.path(path, name)) + } + + prefix <- renv_bootstrap_profile_prefix() + paste(c(project, prefix, "renv/library"), collapse = "/") + + } + + renv_bootstrap_validate_version <- function(version) { + + loadedversion <- utils::packageDescription("renv", fields = "Version") + if (version == loadedversion) + return(TRUE) + + # assume four-component versions are from GitHub; three-component + # versions are from CRAN + components <- strsplit(loadedversion, "[.-]")[[1]] + remote <- if (length(components) == 4L) + paste("rstudio/renv", loadedversion, sep = "@") + else + paste("renv", loadedversion, sep = "@") + + fmt <- paste( + "renv %1$s was loaded from project library, but this project is configured to use renv %2$s.", + "Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile.", + "Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library.", + sep = "\n" + ) + + msg <- sprintf(fmt, loadedversion, version, remote) + warning(msg, call. = FALSE) + + FALSE + + } + + renv_bootstrap_hash_text <- function(text) { + + hashfile <- tempfile("renv-hash-") + on.exit(unlink(hashfile), add = TRUE) + + writeLines(text, con = hashfile) + tools::md5sum(hashfile) + + } + + renv_bootstrap_load <- function(project, libpath, version) { + + # try to load renv from the project library + if (!requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) + return(FALSE) + + # warn if the version of renv loaded does not match + renv_bootstrap_validate_version(version) + + # load the project + renv::load(project) + + TRUE + + } + + renv_bootstrap_profile_load <- function(project) { + + # if RENV_PROFILE is already set, just use that + profile <- Sys.getenv("RENV_PROFILE", unset = NA) + if (!is.na(profile) && nzchar(profile)) + return(profile) + + # check for a profile file (nothing to do if it doesn't exist) + path <- file.path(project, "renv/local/profile") + if (!file.exists(path)) + return(NULL) + + # read the profile, and set it if it exists + contents <- readLines(path, warn = FALSE) + if (length(contents) == 0L) + return(NULL) + + # set RENV_PROFILE + profile <- contents[[1L]] + if (nzchar(profile)) + Sys.setenv(RENV_PROFILE = profile) + + profile + + } + + renv_bootstrap_profile_prefix <- function() { + profile <- renv_bootstrap_profile_get() + if (!is.null(profile)) + return(file.path("renv/profiles", profile)) + } + + renv_bootstrap_profile_get <- function() { + profile <- Sys.getenv("RENV_PROFILE", unset = "") + renv_bootstrap_profile_normalize(profile) + } + + renv_bootstrap_profile_set <- function(profile) { + profile <- renv_bootstrap_profile_normalize(profile) + if (is.null(profile)) + Sys.unsetenv("RENV_PROFILE") + else + Sys.setenv(RENV_PROFILE = profile) + } + + renv_bootstrap_profile_normalize <- function(profile) { + + if (is.null(profile) || profile %in% c("", "default")) + return(NULL) + + profile + + } + + # load the renv profile, if any + renv_bootstrap_profile_load(project) + + # construct path to library root + root <- renv_bootstrap_library_root(project) + + # construct library prefix for platform + prefix <- renv_bootstrap_platform_prefix() + + # construct full libpath + libpath <- file.path(root, prefix) + + # attempt to load + if (renv_bootstrap_load(project, libpath, version)) + return(TRUE) + + # load failed; inform user we're about to bootstrap + prefix <- paste("# Bootstrapping renv", version) + postfix <- paste(rep.int("-", 77L - nchar(prefix)), collapse = "") + header <- paste(prefix, postfix) + message(header) + + # perform bootstrap + bootstrap(version, libpath) + + # exit early if we're just testing bootstrap + if (!is.na(Sys.getenv("RENV_BOOTSTRAP_INSTALL_ONLY", unset = NA))) + return(TRUE) + + # try again to load + if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) { + message("* Successfully installed and loaded renv ", version, ".") + return(renv::load()) + } + + # failed to download or load renv; warn the user + msg <- c( + "Failed to find an renv installation: the project will not be loaded.", + "Use `renv::activate()` to re-initialize the project." + ) + + warning(paste(msg, collapse = "\n"), call. = FALSE) + +}) diff --git a/renv/settings.dcf b/renv/settings.dcf new file mode 100644 index 000000000..175521fb7 --- /dev/null +++ b/renv/settings.dcf @@ -0,0 +1,7 @@ +external.libraries: +ignored.packages: +package.dependency.fields: Imports, Depends, LinkingTo +r.version: +snapshot.type: explicit +use.cache: TRUE +vcs.ignore.library: TRUE diff --git a/tests/testthat/setup-git2r.R b/tests/testthat/setup-git2r.R deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/testthat/test-assumptions.R b/tests/testthat/test-assumptions.R index cfe912634..e69de29bb 100644 --- a/tests/testthat/test-assumptions.R +++ b/tests/testthat/test-assumptions.R @@ -1,6 +0,0 @@ -test_that("documentation regarding desc is still accurate", { - skip_on_cran() - if (packageVersion("desc") >= 1.3 && Sys.Date() > as.Date("2021-04-01")) { - rlang::abort("newer version of desc on CRAN. Adapt the warning and maybe add minimal version requirement?") - } -}) diff --git a/tests/testthat/test-all.R b/tests/testthat/test-hooks.R similarity index 100% rename from tests/testthat/test-all.R rename to tests/testthat/test-hooks.R diff --git a/vignettes/FAQ.Rmd b/vignettes/FAQ.Rmd index a89b5a9c6..31e962757 100644 --- a/vignettes/FAQ.Rmd +++ b/vignettes/FAQ.Rmd @@ -24,7 +24,7 @@ directory, people wrote frameworks to basically maintain these files. One of them is [pre-commit.com](https://pre-commit.com). So you call git to commit, git calls its internal hooks, these hooks (bash scripts in the simplest case) are provided by the pre-commit framework. And where does pre-commit get all it's nice hooks -from? From us. +from? From us. ## How are hooks accessed? What happens if there's no internet connection? @@ -32,9 +32,21 @@ Internet connection is required during installation (`precommit::install_precommit()`) and project initialization (`precommit::use_precommit()`) as well as when hooks are updated (`precommit::autoupdate()`). Otherwise, no internet connection is required. -Hooks will be placed into `.git/` during calling the -`precommit::use_precommit()` and afterwards you can `precommit::autoupdate()` -to replace the hooks with their new version (that's what I think happens). +During initialization, hooks from this repo will be placed in a virtual +environment within the user cache and upon committing, they are called from a +generic hook helper in `.git/hooks/`. + +## Why do some hooks not give me the same results as running the command interactively? + +Note that starting with `precommit > 0.1.3`, hooks run in an isolated +[`{renv}`](https://rstudio.github.io/renv/), leveraging [R as a supported language](https://pre-commit.com/#r) in the pre-commit framework. The version of a package you use interactively +(e.g. `{roxygen2}` to document) might for that reason be different from the one +pre-commit uses. The point of using pre-commit is to take mental burden off your +shoulders (and sometimes even caches results for speed), so there is no need to +run functionality covered by the hooks manually anyways. If you need to know +which package versions are used, look for the `renv.lock` file in +https://github.com/lorenzwalthert/precommit at the git tag specified under +`rev:` in your `.pre-commit-config.yaml`. ## Can you use it outside RStudio? @@ -42,12 +54,9 @@ Yes, all but the `open_config()` and `open_wordlist()` to open files in RStudio. ## Can I use the hooks provided in this package without installing the R package? -Yes, apart from the `roxygenize` hook (which uses an exported function from -{precommit}). The hooks work even if you don't have the R package installed -because all you need to have for the hooks to work is the pre-commit executable. -It will `git clone` the hooks from this repo into `.git/hooks` or similar. All -exported functions of this package are just for the users convenience. - +Yes, you don't need to manually install this package. Although technically +speaking, this package will get installed into a virtual environment isolated +from your global and project library. ## How can I make sure that my contributors are using the hooks? @@ -83,19 +92,6 @@ described [here](https://pre-commit.com/#temporarily-disabling-hooks). How to contribute new hooks is explained in [`CONTRIBUTING.md`](https://github.com/lorenzwalthert/precommit/blob/master/CONTRIBUTING.md). -## Why are my hooks running slowly? - -Some of the hooks depend on R functions that run slowly, e.g. the `style-files` -hook depends on `styler`, which is not very fast. Also, note that for each hook, -R is started. Make sure your startup process is quick for non-interactive use, -e.g. your `.Rprofile` and related files do not have a long execution time when -pre-commit calls them. You can wrap code in `if (interactive()) ` to only -execute it in an interactive session or wrap it in -`if (Sys.getenv("PRE_COMMIT") != "1")` (if you have `pre-commit >= 2.5.0`), so -it won't run when pre-commit hooks are ran. Find out more about the startup -process with `?startup`. - - *** There is more. Check out the documentation of the [pre-commit](https://pre-commit.com) framework. diff --git a/vignettes/available-hooks.Rmd b/vignettes/available-hooks.Rmd index 65d5f0d03..900421443 100644 --- a/vignettes/available-hooks.Rmd +++ b/vignettes/available-hooks.Rmd @@ -165,6 +165,22 @@ exists, the hook emits a warning which you can silence with args: [--no-warn-cache] ``` +Because the hook will write the version of {roxygen2} to `DESCRIPTON`, you +should either make sure the version you use when you call {roxygen2} +interactively matches the one from in {precommit} or simply not run {roxygen2} +manually. + +If you specify additional roclets through the `Roxygen:` field in `DESCRIPTION`, +e.g. from [{pkgapi}](https://github.com/r-lib/pkgapi) you must specify the +dependencies explicitly such that `renv::install()` understands it, e.g. + +``` + id: roxygenize + additional_dependencies: + - r-lib/pkgapi + +``` + This hook does not modify input files, but writes to `.Rd` files in `man/`, `NAMESPACE` and potentially others depending on which roxygen roclets you specified in `DESCRIPTION`. @@ -183,12 +199,7 @@ Flag not set by default, i.e. the hook will fail if such a call is found. This hook does not modify the file `DESCRIPTION` because the user should decide for each package if it should go to `Imports:` or `Suggests:`, which can be done -easily with `usethis::use_package()`. For those who use -`usethis::use_package()`: As long as the CRAN version of the dependency {desc} -is `v1.2.0`, we recommend you to install the GitHub version because otherwise, -the new dependencies won't be added in alphabetical order and after adding a -dependency, `use-tidy-description` will fail in most cases -(#85)[https://github.com/r-lib/desc/pull/85]. +easily with `usethis::use_package()`. ## `use-tidy-description` @@ -212,8 +223,7 @@ should set this with the field `verbose: true`. When configured this way, lintr prints lint errors as they appear. Other arguments are not supported. Instead, `lintr` config should be specified in a `.lintr` config file in Debian Control Field Format as specified in the -[`.lintr` -documentation](https://github.com/jimhester/lintr#project-configuration). +[`.lintr` documentation](https://github.com/jimhester/lintr#project-configuration). This hook does not modify any file. diff --git a/vignettes/testing.Rmd b/vignettes/testing.Rmd new file mode 100644 index 000000000..a161fb34d --- /dev/null +++ b/vignettes/testing.Rmd @@ -0,0 +1,38 @@ +--- +title: "testing" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{testing} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +pre-commit >= 2.11.0 supports R as a language and each hook repo has its own +virtual environment with package versions locked. For that reason, we should +also test with exactly these versions. + +This package has three testing worfklows: + +* hook testing. Tests the hooks (as well as hook script helpers?) in the renv in + which they'll be shipped. No R CMD Check or pre-commit executable needed. + All platforms. To avoid convolution of the testing environment + (that contains testthat and other packages) and the hook environment + (specified in `renv.lock`), we must only activate the hook environment right + when the script is called, but `run_test()` must run in the testing + environment. Since `--vanilla` is inherited in the child process initiated + from `run_test()`, the only way to do this is to set an env variable when + running `run_test()` and check in the user R profile if it is set, and then + activate the renv. This is done with `R_PRECOMMIT_HOOK_ENV`. + +* complete testing: Tests hooks as well as usethis like access functionality + with latest CRAN packges, on all platforms, with all installation methods. + +* CRAN testing. On CRAN, complete testing is ran, tests that check pre-commit + executable access are disabled.