diff --git a/.github/workflows/end-to-end.yml b/.github/workflows/end-to-end.yml index aaf293934..11f317445 100644 --- a/.github/workflows/end-to-end.yml +++ b/.github/workflows/end-to-end.yml @@ -11,6 +11,8 @@ jobs: env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: + - uses: r-lib/actions/setup-pandoc@v2 + - uses: r-lib/actions/setup-r@v2 - uses: actions/checkout@v2 @@ -69,6 +71,15 @@ jobs: pre-commit run --files DESCRIPTION git add README* pre-commit run --files README.Rmd + cp tests/testthat/in/_pkgdown-index-articles.yml _pkgdown.yml + rm -rf vignettes + mkdir vignettes + cp tests/testthat/in/pkgdown.Rmd vignettes/ + rm -rf man/ + mkdir -p man + cp tests/testthat/in/autoupdate.Rd man/ + pre-commit run --files _pkgdown.yml + pre-commit run --files man/autoupdate.Rd git reset HEAD --hard # restore initial state env: SKIP: consistent-release-tag diff --git a/.github/workflows/hook-dependencies-update.yml b/.github/workflows/hook-dependencies-update.yml index 72c80e7da..ed78d72e8 100644 --- a/.github/workflows/hook-dependencies-update.yml +++ b/.github/workflows/hook-dependencies-update.yml @@ -53,13 +53,13 @@ jobs: deps <- desc$get_deps() dont <- c( "yaml", "usethis", "withr", "rstudioapi", "precommit", - "httr" # lintr -> httr -> curl -> libcurl, but seems to give no erorr on - # loading lintr, plus https://github.com/jimhester/lintr/issues/861 + "pkgdown", "mockery", + "httr" ) - out <- c(out, "roxygen2", "spelling", "styler", "pkgload", "lintr", "knitr", "git2r", "desc") + out <- c(out, "roxygen2", "spelling", "styler", "pkgload", "lintr", "knitr", "git2r", "desc", "mockery") out <- setdiff(c(unique(c(out, deps[deps$type == "Imports", ]$package))), dont) out <- names(renv:::renv_package_dependencies(out)) - return(out) + return(sort(out)) } options(repos = c(CRAN = "https://packagemanager.rstudio.com/all/latest")) options(renv.snapshot.filter = hook_deps) diff --git a/.github/workflows/hook-tests.yaml b/.github/workflows/hook-tests.yaml index 8560022b5..26627da49 100644 --- a/.github/workflows/hook-tests.yaml +++ b/.github/workflows/hook-tests.yaml @@ -24,6 +24,7 @@ jobs: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: + - uses: r-lib/actions/setup-pandoc@v2 - uses: actions/checkout@v2 - uses: r-lib/actions/setup-r@v2 with: @@ -67,6 +68,9 @@ jobs: run: | source('renv/activate.R') renv::restore() + options(install.packages.compile.from.source = "never", pkgType = "binary") + # install hook-specific additional_dependencies from .pre-commit-config.yaml + renv::install(c('pkgdown', 'mockery')) renv::install(getwd(), dependencies = FALSE) # needed to make sure renv is activated in run_test() activate <- c( diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bd7c0e3f8..612e9d184 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -82,9 +82,11 @@ repos: (?x)^( tests/testthat/in/.*| inst/renv-update\.R| + inst/hooks/exported/pkgdown.R| renv/activate.R| vignettes/FAQ\.Rmd| )$ +# - id: pkgdown - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.3.0 hooks: diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index fc27bfc08..40d48d011 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -1,6 +1,6 @@ - id: roxygenize name: roxygenize - description: run roxygen2::roxygenize() + description: run `roxygen2::roxygenize()` entry: Rscript inst/hooks/exported/roxygenize.R language: r files: '^(R|man)/' @@ -8,14 +8,14 @@ minimum_pre_commit_version: "2.13.0" - id: use-tidy-description name: use-tidy-description - description: run usethis::use_tidy_description() + description: run `usethis::use_tidy_description()` entry: Rscript inst/hooks/exported/use-tidy-description.R language: r files: '^DESCRIPTION$' minimum_pre_commit_version: "2.13.0" - id: style-files name: style-files - description: style files with styler + description: style files with {styler} entry: Rscript inst/hooks/exported/style-files.R language: r files: '(\.[rR]profile|\.[rR]|\.[rR]md|\.[rR]nw|\.[qQ]md)$' @@ -44,21 +44,21 @@ minimum_pre_commit_version: "2.13.0" - id: readme-rmd-rendered name: readme-rmd-rendered - description: make sure README.Rmd hasn't been edited more recently than README.md + description: make sure README.Rmd hasn't been edited more recently than `README.md` entry: Rscript inst/hooks/exported/readme-rmd-rendered.R language: r files: 'README\.[Rr]?md$' minimum_pre_commit_version: "2.13.0" - 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. + description: make sure `codemeta.json` is in sync with `DESCRIPTION`. It should be run after use-tidy-description entry: Rscript inst/hooks/exported/codemeta-description-updated.R language: r files: '^DESCRIPTION$' minimum_pre_commit_version: "2.13.0" - id: spell-check name: spell-check - description: perform a spell check with spelling::spell_check_files() + description: perform a spell check with `spelling::spell_check_files()` entry: Rscript inst/hooks/exported/spell-check.R language: r exclude: > @@ -92,7 +92,7 @@ minimum_pre_commit_version: "2.13.0" - id: deps-in-desc name: deps-in-desc - description: Check if dependencies that can be parsed from code are in DESCRIPTION. + description: Check if dependencies that can be parsed from code are in `DESCRIPTION` entry: Rscript inst/hooks/exported/deps-in-desc.R language: r files: '(\.[rR]profile|\.R|\.Rmd|\.Rnw|\.r|\.rmd|\.rnw)$' @@ -100,9 +100,16 @@ minimum_pre_commit_version: "2.13.0" - id: lintr name: lintr - description: check if a .R file is lint free (using lintr) + description: check if a `.R` file is lint free (using {lintr}) entry: Rscript inst/hooks/exported/lintr.R language: r files: '(\.[rR]profile|\.R|\.Rmd|\.Rnw|\.r|\.rmd|\.rnw)$' exclude: 'renv/activate\.R' minimum_pre_commit_version: "2.13.0" +- id: pkgdown + name: pkgdown + description: check if your {pkgdown} config file has the correct entries for references and articles + entry: inst/hooks/exported/pkgdown.R + language: script + minimum_pre_commit_version: "2.13.0" + files: '^man/|_pkgdown\.yml' diff --git a/DESCRIPTION b/DESCRIPTION index ee5606ab3..5402836a7 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: precommit Title: Pre-Commit Hooks -Version: 0.3.2.9003 +Version: 0.3.2.9004 Author: Lorenz Walthert Maintainer: Lorenz Walthert Description: Useful git hooks for R building on top of the multi-language @@ -33,6 +33,7 @@ Suggests: lintr, mockery, pkgload, + pkgdown, reticulate (>= 1.16), rmarkdown, roxygen2, diff --git a/NEWS.md b/NEWS.md index 1aa026624..91b0b76c1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,8 +4,10 @@ editor_options: wrap: 72 --- -# precommit v0.3.2.9001 (Development version) +# precommit v0.3.2.9003 (Development version) +- new hook `pkgdown` to emulate a {pkgdown} build for reference and + articles (#393). - `codemeta-description-updated`, `roxygenize`, and `use-tidy-description` now all support a `root` argument that specifies the directory in the git repo that contains the R package. diff --git a/inst/hooks/exported/pkgdown.R b/inst/hooks/exported/pkgdown.R new file mode 100755 index 000000000..cbcd824d5 --- /dev/null +++ b/inst/hooks/exported/pkgdown.R @@ -0,0 +1,18 @@ +#!/usr/bin/env Rscript + +if (is.null(pkgdown:::pkgdown_config_path("."))) { + rlang::inform(paste0( + "{pkgdown} seems not configured, the remainder of the check is skipped. ", + "For this hook to not even be invoked, remove `id: pkgdown` from ", + "`.pre-commit-config.yaml`." + )) + quit() +} + +if (!require(pkgdown, quietly = TRUE)) { + stop("{pkgdown} could not be loaded, please install it.") +} +if (packageVersion("pkgdown") < package_version("2.0.4")) { + rlang::abort("You need at least version 2.0.4 of {pkgdown} to run this hook.") +} +check_pkgdown() diff --git a/inst/pre-commit-hooks.yaml b/inst/pre-commit-hooks.yaml index fc27bfc08..40d48d011 100644 --- a/inst/pre-commit-hooks.yaml +++ b/inst/pre-commit-hooks.yaml @@ -1,6 +1,6 @@ - id: roxygenize name: roxygenize - description: run roxygen2::roxygenize() + description: run `roxygen2::roxygenize()` entry: Rscript inst/hooks/exported/roxygenize.R language: r files: '^(R|man)/' @@ -8,14 +8,14 @@ minimum_pre_commit_version: "2.13.0" - id: use-tidy-description name: use-tidy-description - description: run usethis::use_tidy_description() + description: run `usethis::use_tidy_description()` entry: Rscript inst/hooks/exported/use-tidy-description.R language: r files: '^DESCRIPTION$' minimum_pre_commit_version: "2.13.0" - id: style-files name: style-files - description: style files with styler + description: style files with {styler} entry: Rscript inst/hooks/exported/style-files.R language: r files: '(\.[rR]profile|\.[rR]|\.[rR]md|\.[rR]nw|\.[qQ]md)$' @@ -44,21 +44,21 @@ minimum_pre_commit_version: "2.13.0" - id: readme-rmd-rendered name: readme-rmd-rendered - description: make sure README.Rmd hasn't been edited more recently than README.md + description: make sure README.Rmd hasn't been edited more recently than `README.md` entry: Rscript inst/hooks/exported/readme-rmd-rendered.R language: r files: 'README\.[Rr]?md$' minimum_pre_commit_version: "2.13.0" - 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. + description: make sure `codemeta.json` is in sync with `DESCRIPTION`. It should be run after use-tidy-description entry: Rscript inst/hooks/exported/codemeta-description-updated.R language: r files: '^DESCRIPTION$' minimum_pre_commit_version: "2.13.0" - id: spell-check name: spell-check - description: perform a spell check with spelling::spell_check_files() + description: perform a spell check with `spelling::spell_check_files()` entry: Rscript inst/hooks/exported/spell-check.R language: r exclude: > @@ -92,7 +92,7 @@ minimum_pre_commit_version: "2.13.0" - id: deps-in-desc name: deps-in-desc - description: Check if dependencies that can be parsed from code are in DESCRIPTION. + description: Check if dependencies that can be parsed from code are in `DESCRIPTION` entry: Rscript inst/hooks/exported/deps-in-desc.R language: r files: '(\.[rR]profile|\.R|\.Rmd|\.Rnw|\.r|\.rmd|\.rnw)$' @@ -100,9 +100,16 @@ minimum_pre_commit_version: "2.13.0" - id: lintr name: lintr - description: check if a .R file is lint free (using lintr) + description: check if a `.R` file is lint free (using {lintr}) entry: Rscript inst/hooks/exported/lintr.R language: r files: '(\.[rR]profile|\.R|\.Rmd|\.Rnw|\.r|\.rmd|\.rnw)$' exclude: 'renv/activate\.R' minimum_pre_commit_version: "2.13.0" +- id: pkgdown + name: pkgdown + description: check if your {pkgdown} config file has the correct entries for references and articles + entry: inst/hooks/exported/pkgdown.R + language: script + minimum_pre_commit_version: "2.13.0" + files: '^man/|_pkgdown\.yml' diff --git a/renv.lock b/renv.lock index 846b55680..c62db935c 100644 --- a/renv.lock +++ b/renv.lock @@ -1,6 +1,6 @@ { "R": { - "Version": "4.0.5", + "Version": "4.2.1", "Repositories": [ { "Name": "CRAN", @@ -13,7 +13,7 @@ "Package": "R.cache", "Version": "0.16.0", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Hash": "fe539ca3f8efb7410c3ae2cf5fe6c0f8", "Requirements": [ "R.methodsS3", @@ -26,7 +26,7 @@ "Package": "R.methodsS3", "Version": "1.8.2", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Hash": "278c286fd6e9e75d0c2e8f731ea445c8", "Requirements": [] }, @@ -34,7 +34,7 @@ "Package": "R.oo", "Version": "1.25.0", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Hash": "a0900a114f4f0194cf4aa8cd4a700681", "Requirements": [ "R.methodsS3" @@ -42,10 +42,10 @@ }, "R.utils": { "Package": "R.utils", - "Version": "2.12.0", + "Version": "2.12.1", "Source": "Repository", "Repository": "RSPM", - "Hash": "d31333e10f14027e1cbbc6f266512806", + "Hash": "1ed133420fcd2b93cf55a383b38fe27c", "Requirements": [ "R.methodsS3", "R.oo" @@ -63,7 +63,7 @@ "Package": "Rcpp", "Version": "1.0.9", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Hash": "e9c08b94391e9f3f97355841229124f2", "Requirements": [] }, @@ -85,10 +85,10 @@ }, "callr": { "Package": "callr", - "Version": "3.7.2", + "Version": "3.7.3", "Source": "Repository", "Repository": "RSPM", - "Hash": "358689cac9fe93b1bb3a19088d2dbed8", + "Hash": "9b2191ede20fa29828139b9900922e51", "Requirements": [ "R6", "processx" @@ -112,18 +112,18 @@ }, "commonmark": { "Package": "commonmark", - "Version": "1.8.0", + "Version": "1.8.1", "Source": "Repository", "Repository": "RSPM", - "Hash": "2ba81b120c1655ab696c935ef33ea716", + "Hash": "b6e3e947d1d7ebf3d2bdcea1bde63fe7", "Requirements": [] }, "cpp11": { "Package": "cpp11", - "Version": "0.4.2", + "Version": "0.4.3", "Source": "Repository", "Repository": "RSPM", - "Hash": "fa53ce256cd280f468c080a58ea5ba8c", + "Hash": "ed588261931ee3be2c700d22e94a29ab", "Requirements": [] }, "crayon": { @@ -138,7 +138,7 @@ "Package": "cyclocomp", "Version": "1.1.0", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Hash": "53cbed70a2f7472d48fb6aef08442f25", "Requirements": [ "callr", @@ -152,7 +152,7 @@ "Package": "desc", "Version": "1.4.2", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Hash": "6b9602c7ebbe87101a9c8edb6e8b6d21", "Requirements": [ "R6", @@ -162,26 +162,26 @@ }, "digest": { "Package": "digest", - "Version": "0.6.29", + "Version": "0.6.30", "Source": "Repository", - "Repository": "CRAN", - "Hash": "cf6b206a045a684728c3267ef7596190", + "Repository": "RSPM", + "Hash": "bf1cd206a5d170d132ef75c7537b9bdb", "Requirements": [] }, "docopt": { "Package": "docopt", "Version": "0.7.1", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Hash": "e9eeef7931ee99ca0093f3f20b88e09b", "Requirements": [] }, "evaluate": { "Package": "evaluate", - "Version": "0.16", + "Version": "0.18", "Source": "Repository", "Repository": "RSPM", - "Hash": "9a3d3c345f8a5648abe61608aaa29518", + "Hash": "6b6c0f8467cd4ce0b500cabbc1bd1763", "Requirements": [] }, "fs": { @@ -196,7 +196,7 @@ "Package": "git2r", "Version": "0.30.1", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Hash": "e0c6a04a3e7b90e64213d09128f74f1b", "Requirements": [] }, @@ -204,7 +204,7 @@ "Package": "glue", "Version": "1.6.2", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Hash": "4f2596dfb05dac67b9dc558e5c6fba2e", "Requirements": [] }, @@ -232,7 +232,7 @@ "Package": "hunspell", "Version": "3.0.2", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Hash": "656219b6f3f605499d7cdbe208656639", "Requirements": [ "Rcpp", @@ -241,17 +241,17 @@ }, "jsonlite": { "Package": "jsonlite", - "Version": "1.8.0", + "Version": "1.8.3", "Source": "Repository", "Repository": "RSPM", - "Hash": "d07e729b27b372429d42d24d503613a0", + "Hash": "8b1bd0be62956f2a6b91ce84fac79a45", "Requirements": [] }, "knitr": { "Package": "knitr", "Version": "1.40", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Hash": "caea8b0f899a0b1738444b9bc47067e7", "Requirements": [ "evaluate", @@ -265,16 +265,28 @@ "Package": "lazyeval", "Version": "0.2.2", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Hash": "d908914ae53b04d4c0c0fd72ecc35370", "Requirements": [] }, + "lifecycle": { + "Package": "lifecycle", + "Version": "1.0.3", + "Source": "Repository", + "Repository": "RSPM", + "Hash": "001cecbeac1cff9301bdc3775ee46a86", + "Requirements": [ + "cli", + "glue", + "rlang" + ] + }, "lintr": { "Package": "lintr", - "Version": "3.0.1", + "Version": "3.0.2", "Source": "Repository", "Repository": "RSPM", - "Hash": "41ca4b419351698a49c3a74f0281ffbd", + "Hash": "b21ebd652d940f099915221f3328ab7b", "Requirements": [ "backports", "codetools", @@ -293,16 +305,16 @@ "Package": "magrittr", "Version": "2.0.3", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Hash": "7ce2733a9826b3aeb1775d56fd305472", "Requirements": [] }, "pkgload": { "Package": "pkgload", - "Version": "1.3.0", + "Version": "1.3.1", "Source": "Repository", "Repository": "RSPM", - "Hash": "4b20f937a363c78a5730265c1925f54a", + "Hash": "3c0918b1792c75de2e640d1d8d12dead", "Requirements": [ "cli", "crayon", @@ -316,10 +328,10 @@ }, "processx": { "Package": "processx", - "Version": "3.7.0", + "Version": "3.8.0", "Source": "Repository", "Repository": "RSPM", - "Hash": "f91df0f5f31ffdf88bc0b624f5ebab0f", + "Hash": "a33ee2d9bf07564efb888ad98410da84", "Requirements": [ "R6", "ps" @@ -327,18 +339,18 @@ }, "ps": { "Package": "ps", - "Version": "1.7.1", + "Version": "1.7.2", "Source": "Repository", "Repository": "RSPM", - "Hash": "8b93531308c01ad0e56d9eadcc0c4fcd", + "Hash": "68dd03d98a5efd1eb3012436de45ba83", "Requirements": [] }, "purrr": { "Package": "purrr", - "Version": "0.3.4", + "Version": "0.3.5", "Source": "Repository", - "Repository": "CRAN", - "Hash": "97def703420c8ab10d8f0e6c72101e02", + "Repository": "RSPM", + "Hash": "54842a2443c76267152eface28d9e90a", "Requirements": [ "magrittr", "rlang" @@ -356,7 +368,7 @@ "Package": "rex", "Version": "1.2.1", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Hash": "ae34cd56890607370665bee5bd17812f", "Requirements": [ "lazyeval" @@ -374,7 +386,7 @@ "Package": "roxygen2", "Version": "7.2.1", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Hash": "da1f278262e563c835345872f2fef537", "Requirements": [ "R6", @@ -398,7 +410,7 @@ "Package": "rprojroot", "Version": "2.0.3", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Hash": "1de7ab598047a87bba48434ba35d497d", "Requirements": [] }, @@ -406,7 +418,7 @@ "Package": "spelling", "Version": "2.2", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Hash": "b8c899a5c83f0d897286550481c91798", "Requirements": [ "commonmark", @@ -419,7 +431,7 @@ "Package": "stringi", "Version": "1.7.8", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Hash": "a68b980681bcbc84c7a67003fa796bfb", "Requirements": [] }, @@ -427,7 +439,7 @@ "Package": "stringr", "Version": "1.4.1", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Hash": "a66ad12140cd34d4f9dfcc19e84fc2a5", "Requirements": [ "glue", @@ -437,15 +449,15 @@ }, "styler": { "Package": "styler", - "Version": "1.7.0.9003", + "Version": "1.8.1.9000", "Source": "GitHub", "RemoteType": "github", "RemoteUsername": "r-lib", "RemoteRepo": "styler", "RemoteRef": "HEAD", - "RemoteSha": "e8a0c4f7d018b02e0c310a4e39a66ac1d347820f", + "RemoteSha": "96f859daf39f5973851c06506d7827808eea28a8", "RemoteHost": "api.github.com", - "Hash": "42e5ab817da9eb17cbaff53d446bfb61", + "Hash": "1d898a96339553cc49c9afbc57e15713", "Requirements": [ "R.cache", "cli", @@ -459,13 +471,14 @@ }, "vctrs": { "Package": "vctrs", - "Version": "0.4.2", + "Version": "0.5.0", "Source": "Repository", "Repository": "RSPM", - "Hash": "0e3dfc070b2a8f0478fcdf86fb33355d", + "Hash": "001fd6a5ebfff8316baf9fb2b5516dc9", "Requirements": [ "cli", "glue", + "lifecycle", "rlang" ] }, @@ -473,16 +486,16 @@ "Package": "withr", "Version": "2.5.0", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Hash": "c0e49a9760983e81e55cdd9be92e7182", "Requirements": [] }, "xfun": { "Package": "xfun", - "Version": "0.33", + "Version": "0.34", "Source": "Repository", "Repository": "RSPM", - "Hash": "1a666f915cd65072f4ccf5b2888d5d39", + "Hash": "9eba2411b0b1f879797141bd24df7407", "Requirements": [] }, "xml2": { @@ -497,16 +510,16 @@ "Package": "xmlparsedata", "Version": "1.0.5", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Hash": "45e4bf3c46476896e821fc0a408fb4fc", "Requirements": [] }, "yaml": { "Package": "yaml", - "Version": "2.3.5", + "Version": "2.3.6", "Source": "Repository", - "Repository": "CRAN", - "Hash": "458bb38374d73bf83b1bb85e353da200", + "Repository": "RSPM", + "Hash": "9b570515751dcbae610f29885e025b41", "Requirements": [] } } diff --git a/renv/activate.R b/renv/activate.R index f958df789..019b5a669 100644 --- a/renv/activate.R +++ b/renv/activate.R @@ -2,7 +2,7 @@ local({ # the requested version of renv - version <- "0.15.2" + version <- "0.16.0" # the project directory project <- getwd() @@ -185,43 +185,80 @@ local({ if (fixup) mode <- "w+b" - utils::download.file( + args <- list( url = url, destfile = destfile, mode = mode, quiet = TRUE ) + if ("headers" %in% names(formals(utils::download.file))) + args$headers <- renv_bootstrap_download_custom_headers(url) + + do.call(utils::download.file, args) + + } + + renv_bootstrap_download_custom_headers <- function(url) { + + headers <- getOption("renv.download.headers") + if (is.null(headers)) + return(character()) + + if (!is.function(headers)) + stopf("'renv.download.headers' is not a function") + + headers <- headers(url) + if (length(headers) == 0L) + return(character()) + + if (is.list(headers)) + headers <- unlist(headers, recursive = FALSE, use.names = TRUE) + + ok <- + is.character(headers) && + is.character(names(headers)) && + all(nzchar(names(headers))) + + if (!ok) + stop("invocation of 'renv.download.headers' did not return a named character vector") + + headers + } renv_bootstrap_download_cran_latest <- function(version) { spec <- renv_bootstrap_download_cran_latest_find(version) + type <- spec$type + repos <- spec$repos message("* Downloading renv ", version, " ... ", appendLF = FALSE) - type <- spec$type - repos <- spec$repos + baseurl <- utils::contrib.url(repos = repos, type = type) + ext <- if (identical(type, "source")) + ".tar.gz" + else if (Sys.info()[["sysname"]] == "Windows") + ".zip" + else + ".tgz" + name <- sprintf("renv_%s%s", version, ext) + url <- paste(baseurl, name, sep = "/") - info <- tryCatch( - utils::download.packages( - pkgs = "renv", - destdir = tempdir(), - repos = repos, - type = type, - quiet = TRUE - ), + destfile <- file.path(tempdir(), name) + status <- tryCatch( + renv_bootstrap_download_impl(url, destfile), condition = identity ) - if (inherits(info, "condition")) { + if (inherits(status, "condition")) { message("FAILED") return(FALSE) } # report success and return message("OK (downloaded ", type, ")") - info[1, 2] + destfile } @@ -678,7 +715,7 @@ local({ return(profile) # check for a profile file (nothing to do if it doesn't exist) - path <- renv_bootstrap_paths_renv("profile", profile = FALSE) + path <- renv_bootstrap_paths_renv("profile", profile = FALSE, project = project) if (!file.exists(path)) return(NULL) @@ -805,9 +842,23 @@ local({ renv_json_read <- function(file = NULL, text = NULL) { + # if jsonlite is loaded, use that instead + if ("jsonlite" %in% loadedNamespaces()) + renv_json_read_jsonlite(file, text) + else + renv_json_read_default(file, text) + + } + + renv_json_read_jsonlite <- function(file = NULL, text = NULL) { text <- paste(text %||% read(file), collapse = "\n") + jsonlite::fromJSON(txt = text, simplifyVector = FALSE) + } + + renv_json_read_default <- function(file = NULL, text = NULL) { # find strings in the JSON + text <- paste(text %||% read(file), collapse = "\n") pattern <- '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' locs <- gregexpr(pattern, text, perl = TRUE)[[1]] @@ -838,8 +889,9 @@ local({ # transform the JSON into something the R parser understands transformed <- replaced - transformed <- gsub("[[{]", "list(", transformed) - transformed <- gsub("[]}]", ")", transformed) + transformed <- gsub("{}", "`names<-`(list(), character())", transformed, fixed = TRUE) + transformed <- gsub("[[{]", "list(", transformed, perl = TRUE) + transformed <- gsub("[]}]", ")", transformed, perl = TRUE) transformed <- gsub(":", "=", transformed, fixed = TRUE) text <- paste(transformed, collapse = "\n") diff --git a/tests/testthat/in/_pkgdown-articles.yml b/tests/testthat/in/_pkgdown-articles.yml new file mode 100644 index 000000000..324ba88cc --- /dev/null +++ b/tests/testthat/in/_pkgdown-articles.yml @@ -0,0 +1,6 @@ +articles: +- title: Get started + navbar: ~ + contents: + - why-use-hooks + - some-more diff --git a/tests/testthat/in/_pkgdown-index-articles.yml b/tests/testthat/in/_pkgdown-index-articles.yml new file mode 100644 index 000000000..59036a668 --- /dev/null +++ b/tests/testthat/in/_pkgdown-index-articles.yml @@ -0,0 +1,12 @@ +reference: +- title: "Workflow" + desc: > + Edit the pre-commit configuration +- contents: + - autoupdate + +articles: +- title: Get started + navbar: ~ + contents: + - pkgdown diff --git a/tests/testthat/in/_pkgdown-index.yml b/tests/testthat/in/_pkgdown-index.yml new file mode 100644 index 000000000..c28bb158c --- /dev/null +++ b/tests/testthat/in/_pkgdown-index.yml @@ -0,0 +1,6 @@ +reference: +- title: "Workflow" + desc: > + Edit the pre-commit configuration +- contents: + - autoupdate diff --git a/tests/testthat/in/autoupdate.Rd b/tests/testthat/in/autoupdate.Rd new file mode 100644 index 000000000..c08c7813d --- /dev/null +++ b/tests/testthat/in/autoupdate.Rd @@ -0,0 +1,22 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/setup.R +\name{autoupdate} +\alias{autoupdate} +\title{Auto-update your hooks} +\usage{ +autoupdate(root = here::here()) +} +\arguments{ +\item{root}{The path to the root directory of your project.} +} +\value{ +The exit status from \verb{pre-commit autoupdate} (invisibly). +} +\description{ +Runs \href{https://pre-commit.com/#pre-commit-autoupdate}{\verb{pre-commit autoupdate}}. +} +\examples{ +\dontrun{ +autoupdate() +} +} diff --git a/tests/testthat/in/pkgdown.Rmd b/tests/testthat/in/pkgdown.Rmd new file mode 100644 index 000000000..79c92b96e --- /dev/null +++ b/tests/testthat/in/pkgdown.Rmd @@ -0,0 +1,19 @@ +--- +title: "pkgdown" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{pkgdown} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +```{r setup} +library(precommit) +``` diff --git a/tests/testthat/reference-objects/pre-commit-config.yaml b/tests/testthat/reference-objects/pre-commit-config.yaml index ca063a877..6e614b9db 100644 --- a/tests/testthat/reference-objects/pre-commit-config.yaml +++ b/tests/testthat/reference-objects/pre-commit-config.yaml @@ -49,6 +49,7 @@ repos: - id: no-browser-statement - id: no-debug-statement - id: deps-in-desc + - id: pkgdown - repo: local hooks: - id: consistent-release-tag diff --git a/tests/testthat/test-hooks.R b/tests/testthat/test-hooks.R index 5cd3a4763..ae167fc6f 100644 --- a/tests/testthat/test-hooks.R +++ b/tests/testthat/test-hooks.R @@ -557,6 +557,54 @@ run_test("codemeta-description-update", } ) +### . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. +### pgkdown check #### + +# success index +run_test("pkgdown", + file_name = c( + "man/autoudpate.Rd" = "autoupdate.Rd", + "_pkgdown.yml" = "_pkgdown-index.yml", + "DESCRIPTION" = "DESCRIPTION" + ), + suffix = "", std_err = NULL +) + +# failed index +run_test("pkgdown", + file_name = c( + "man/flie-true.Rd" = "flie-true.Rd", + "_pkgdown.yml" = "_pkgdown-index.yml", + "DESCRIPTION" = "DESCRIPTION" + ), + suffix = "", + std_err = "topic must be a known" +) + +# failed articles +run_test("pkgdown", + file_name = c( + "vignettes/pkgdown.Rmd" = "pkgdown.Rmd", + "_pkgdown.yml" = "_pkgdown-articles.yml", + "DESCRIPTION" = "DESCRIPTION" + ), + suffix = "", + std_err = "why-use-hooks" +) + +# success index and article +run_test("pkgdown", + file_name = c( + "man/autoudpate.Rd" = "autoupdate.Rd", + "vignettes/pkgdown.Rmd" = "pkgdown.Rmd", + "_pkgdown.yml" = "_pkgdown-index-articles.yml", + "DESCRIPTION" = "DESCRIPTION" + ), + suffix = "", + std_err = NULL +) + + ### . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. ### readme-rmd-rendered #### if (has_git()) { diff --git a/vignettes/available-hooks.Rmd b/vignettes/available-hooks.Rmd index 083f0ce54..818c77640 100644 --- a/vignettes/available-hooks.Rmd +++ b/vignettes/available-hooks.Rmd @@ -223,7 +223,6 @@ 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`. - **Arguments** @@ -231,14 +230,11 @@ roclets you specified in `DESCRIPTION`. id: roxygenize args: [--root=] - - Argument `root` specifies the directory in the git repo that contains the R package. Defaults to `.` since for most R package git repos, the git and R package root coincide. Added in version 0.3.3.00000. - - ## `deps-in-desc` Checks if packages used with the `pkgname::fun()` syntax are listed in @@ -284,12 +280,11 @@ This hook does modify the file `DESCRIPTION`. id: use-tidy-description args: [--root=] - - Argument `root` specifies the directory in the git repo that contains the R package. Defaults to `.` since for most R package git repos, the git and R package root coincide. Added in version 0.3.3.00000. - + ## `lintr` A hook to run `lintr::lint()` to check that R files are lint free. @@ -325,8 +320,23 @@ This hook does not modify any file. id: codemeta-description-updated args: [--root=] - - Argument `root` specifies the directory in the git repo that contains the R package. Defaults to `.` since for most R package git repos, the git and R package root coincide. Added in version 0.3.3.00000. + + +## `pkgdown` + +Check if your {pkgdown} config file (e.g. `_pkgdown.yml` in your root) has the +correct entries for references and articles. +This hook skips the time-consuming parts of building the index and reference and +only performs the validation. Hence we don't rely on the extensive dependency +graph of {pkgdown} being installed, including packages with heavy build-time +dependencies and system libraries. + +For this check, we rely on the the global R package library and require all +development dependencies of the package you want to run this hook for to be +installed, as well as {pkgdown} (without its dependencies) and {mockery}. + +This hook does not modify files. Added in version 0.3.2.9003.