diff --git a/API b/API index 7ab80fe95..bef9c6cd4 100644 --- a/API +++ b/API @@ -3,7 +3,7 @@ ## Exported functions autoupdate(root = here::here()) -diff_requires_run_roxygenize(root = here::here()) +diff_requires_run_roxygenize(root = ".") dirs_R.cache(hook_id) install_precommit(force = FALSE) may_require_permanent_cache(temp_cache_is_enough = FALSE) diff --git a/DESCRIPTION b/DESCRIPTION index e065e2241..71e0f603d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -48,5 +48,5 @@ 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.2.0 +RoxygenNote: 7.2.1 SystemRequirements: git diff --git a/NEWS.md b/NEWS.md index 7c325f0e4..c51c25794 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,10 +4,20 @@ editor_options: wrap: 72 --- +# precommit v0.3.2.9001 (Development version) +- `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. + Defaults to `.` since for most R package git repos, the git and R package + root coincide. + # precommit v0.3.2.9000 - `use_ci()` is now documented to take `NA`, not `NULL` for argument `ci` (#431). +- `deps-in-desc`supports a `root` argument that 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. # precommit v0.3.2 diff --git a/R/roxygen2.R b/R/roxygen2.R index 2388570f0..19d2a5c9c 100644 --- a/R/roxygen2.R +++ b/R/roxygen2.R @@ -24,7 +24,7 @@ extract_diff_files <- function(files) { #' hook such as [roxygen2::roxygenize()] must run at all or not. #' @param root The root of project. #' @keywords internal -extract_diff_root <- function(root = here::here()) { +extract_diff_root <- function(root = ".") { assert_is_git_repo(root) repo <- git2r::repository(root) if (length(git2r::reflog(repo)) == 0) { @@ -57,7 +57,7 @@ extract_diff_root <- function(root = here::here()) { #' diff_requires_run_roxygenize() #' } #' @export -diff_requires_run_roxygenize <- function(root = here::here()) { +diff_requires_run_roxygenize <- function(root = ".") { if (rlang::with_handlers(withr::with_namespace("git2r", FALSE), error = function(...) TRUE)) { generic <- paste0( " Please add the package as a dependency to ", diff --git a/inst/hooks/exported/codemeta-description-updated.R b/inst/hooks/exported/codemeta-description-updated.R index 313ba738a..eed0ad831 100755 --- a/inst/hooks/exported/codemeta-description-updated.R +++ b/inst/hooks/exported/codemeta-description-updated.R @@ -1,5 +1,21 @@ #!/usr/bin/env Rscript +"A hook to make sure DESCRIPTION hasn’t been edited more recently than +codemeta.json. + +Usage: + codemeta-description-updated [--root=] ... + +Options: + --root= Path relative to the git root that contains the R package + root [default: .]. + +" -> doc + + +arguments <- docopt::docopt(doc) +setwd(arguments$root) + # adapted from https://github.com/lorenzwalthert/precommit/blob/f4413cfe6282c84f7176160d06e1560860c8bd3d/inst/hooks/exported/readme-rmd-rendered if (!file.exists("DESCRIPTION")) { rlang::abort("No `DESCRIPTION` found in repository.") diff --git a/inst/hooks/exported/roxygenize.R b/inst/hooks/exported/roxygenize.R index c0b30f421..e74a9eec6 100755 --- a/inst/hooks/exported/roxygenize.R +++ b/inst/hooks/exported/roxygenize.R @@ -14,13 +14,17 @@ This check should run *after* check that modify the files that are passed to them (like styler) because they will never modify their input .R files. Usage: - roxygenize [--no-warn-cache] ... + roxygenize [--no-warn-cache] [--root=] ... Options: --no-warn-cache Suppress the warning about a missing permanent cache. + --root= Path relative to the git root that contains the R package root [default: .]. " -> doc arguments <- docopt::docopt(doc) +arguments$files <- normalizePath(arguments$files) # because working directory changes to root +setwd(arguments$root) + if (packageVersion("precommit") < "0.1.3.9010") { rlang::abort(paste( "This hooks only works with the R package {precommit} >= 0.1.3.9010", diff --git a/inst/hooks/exported/use-tidy-description.R b/inst/hooks/exported/use-tidy-description.R index e5903e054..f141afe05 100755 --- a/inst/hooks/exported/use-tidy-description.R +++ b/inst/hooks/exported/use-tidy-description.R @@ -1,4 +1,24 @@ #!/usr/bin/env Rscript + +"A hook to run usethis::use_tidy_description() to ensure dependencies are +ordered alphabetically and fields are in standard order. + +Usage: + use-tidy-description [--root=] ... + +Options: + --root= Path relative to the git root that contains the R package root [default: .]. + +" -> doc + + +arguments <- docopt::docopt(doc) +setwd(arguments$root) + +if (!file.exists("DESCRIPTION")) { + rlang::abort("No `DESCRIPTION` found in repository.") +} + description <- desc::description$new() description_old <- description$clone(deep = TRUE) deps <- description$get_deps() diff --git a/man/diff_requires_run_roxygenize.Rd b/man/diff_requires_run_roxygenize.Rd index ae71ad474..e6246fd5b 100644 --- a/man/diff_requires_run_roxygenize.Rd +++ b/man/diff_requires_run_roxygenize.Rd @@ -4,7 +4,7 @@ \alias{diff_requires_run_roxygenize} \title{Check if we should run roxygen.} \usage{ -diff_requires_run_roxygenize(root = here::here()) +diff_requires_run_roxygenize(root = ".") } \arguments{ \item{root}{The root of project.} diff --git a/man/extract_diff_root.Rd b/man/extract_diff_root.Rd index c9138fe81..30d775047 100644 --- a/man/extract_diff_root.Rd +++ b/man/extract_diff_root.Rd @@ -4,7 +4,7 @@ \alias{extract_diff_root} \title{Extract old and new lines from \verb{git diff --cached}} \usage{ -extract_diff_root(root = here::here()) +extract_diff_root(root = ".") } \arguments{ \item{root}{The root of project.} diff --git a/man/git_init.Rd b/man/git_init.Rd index 5ad97130f..10de1b6e1 100644 --- a/man/git_init.Rd +++ b/man/git_init.Rd @@ -6,6 +6,9 @@ \usage{ git_init(path = ".") } +\arguments{ +\item{path}{A path to where to init a git repository} +} \description{ In particular, to avoid CRAN errors \href{https://github.com/lorenzwalthert/precommit/issues/320}{lorenzwalthert/precommit#320}. diff --git a/tests/testthat/test-hooks.R b/tests/testthat/test-hooks.R index de1fd9956..5cd3a4763 100644 --- a/tests/testthat/test-hooks.R +++ b/tests/testthat/test-hooks.R @@ -4,6 +4,26 @@ # success run_test("use-tidy-description", "DESCRIPTION", suffix = "") +# in sub directory with correct root +run_test("use-tidy-description", + "DESCRIPTION", + suffix = "", + cmd_args = "--root=rpkg", + artifacts = c("rpkg/DESCRIPTION" = test_path("in/DESCRIPTION")) +) + + + +# in sub directory with incorrect root +# Need to generate the directoy `rpkg` but without DESCRIPTION file. +run_test("use-tidy-description", + "DESCRIPTION", + suffix = "", + cmd_args = "--root=rpkg", + std_err = "No `DESCRIPTION` found in repository.", + artifacts = c("rpkg/README.md" = test_path("in/README.md")) +) + ### . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. ### style-files #### @@ -373,8 +393,47 @@ run_test("roxygenize", } ) +# with outdated Rd present in correct root +run_test("roxygenize", + file_name = c("rpkg/man/flie.Rd" = "flie.Rd"), + suffix = "", + std_err = NA, + cmd_args = "--root=rpkg", + std_out = "Writing NAMESPACE", + artifacts = c( + "rpkg/DESCRIPTION" = test_path("in/DESCRIPTION-no-deps.dcf"), + "rpkg/R/roxygenize.R" = test_path("in/roxygenize.R") + ), + file_transformer = function(files) { + withr::local_dir("rpkg") + git_init() + git2r::add(path = files) + # hack to add artifact to trigger diff_requires_roxygenize() + git2r::add(path = fs::path(fs::path_dir(fs::path_dir(files[1])), "R")) + files + } +) + # without Rd present +run_test("roxygenize", + file_name = c("rpkg1/R/roxygenize.R" = "roxygenize.R"), + suffix = "", + cmd_args = "--root=rpkg1", + std_err = "Please commit the new `.Rd` files", + artifacts = c( + "rpkg1/DESCRIPTION" = test_path("in/DESCRIPTION-no-deps.dcf"), + "rpkg2/R/roxygenize.R" = test_path("in/roxygenize.R") + ), + file_transformer = function(files) { + withr::local_dir("rpkg1") + git_init() + git2r::add(path = files) + files + } +) + +# with Rd present in wrong root run_test("roxygenize", file_name = c("R/roxygenize.R" = "roxygenize.R"), suffix = "", @@ -458,6 +517,46 @@ run_test("codemeta-description-update", } ) +# succeed in correct root +run_test("codemeta-description-update", + file_name = c( + "rpkg/DESCRIPTION" = "DESCRIPTION", + "rpkg/codemeta.json" = "codemeta.json" + ), + cmd_args = "--root=rpkg", + suffix = "", + file_transformer = function(files) { + if (length(files) > 1) { + # transformer is called once on all files and once per file + content_2 <- readLines(files[2]) + Sys.sleep(2) + writeLines(content_2, files[2]) + } + files + } +) + +# # fail in wrong root +run_test("codemeta-description-update", + file_name = c( + "rpkg/DESCRIPTION" = "DESCRIPTION", + "rpkg/codemeta.json" = "codemeta.json", + "rpkg2/codemeta.json" = "README.md" + ), + cmd_args = "--root=rpkg2", + std_err = "No `DESCRIPTION` found in repository.", + suffix = "", + file_transformer = function(files) { + if (length(files) > 1) { + # transformer is called once on all files and once per file + content_2 <- readLines(files[2]) + Sys.sleep(2) + writeLines(content_2, files[2]) + } + files + } +) + ### . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. ### readme-rmd-rendered #### if (has_git()) { diff --git a/vignettes/available-hooks.Rmd b/vignettes/available-hooks.Rmd index 37735f0f5..083f0ce54 100644 --- a/vignettes/available-hooks.Rmd +++ b/vignettes/available-hooks.Rmd @@ -223,6 +223,22 @@ 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** + + + + 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 @@ -248,7 +264,7 @@ your DESCRIPTION file. Note that `README.Rmd` is never checked. id: deps-in-desc - args: [--root=] + args: [--root=] This hook does not modify the file `DESCRIPTION` because the user should decide for each package if it should go to `Imports:` or `Suggests:`, @@ -261,6 +277,19 @@ are ordered alphabetically and fields are in standard order. This hook does modify the file `DESCRIPTION`. +**Arguments** + + + + 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. @@ -288,3 +317,16 @@ i.e. remind you to run `codemetar::write_codemeta()` in order to keep `codemeta.json` in sync with `DESCRIPTION`. This hook does not modify any file. + +**Arguments** + + + + 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.