From cabc386979336e42c83a1734d1c535458756b543 Mon Sep 17 00:00:00 2001 From: assignUser Date: Mon, 13 Sep 2021 16:02:06 +0200 Subject: [PATCH 01/15] add dir to rbuildignore --- R/use.R | 7 +++++++ R/utils.R | 15 +++++++++++++++ man/use_touchstone.Rd | 7 ++++++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/R/use.R b/R/use.R index c7f3042..4d3151b 100644 --- a/R/use.R +++ b/R/use.R @@ -1,10 +1,15 @@ #' Initiate {touchstone} #' +#' This function will initialize {touchstone} in your package repository, use +#' from root directory. #' @param cancel Whether or not to also introduce a GitHub Actions #' [cancel workflow](https://github.com/marketplace/actions/cancel-workflow-action) #' for canceling old runs when new ones are started. This makes sense because #' touchstone runs can take a lot of time and compute resources and you usually #' don't care about old runs when you pushed new code. +#' @details +#' For more information see the 'Using touchstone' vignette: +#' `vignette("touchstone", package = "touchstone") #' @return #' The function is called for its side effects and returns `NULL` (invisibly). #' @export @@ -47,6 +52,8 @@ use_touchstone <- function(cancel = TRUE) { fs::path(workflows, "touchstone-comment.yaml") ) + append_rbuildignore("touchstone") + if (cancel) { target <- fs::path(workflows, "cancel.yaml") if (fs::file_exists(target)) { diff --git a/R/utils.R b/R/utils.R index e984601..c374822 100644 --- a/R/utils.R +++ b/R/utils.R @@ -319,3 +319,18 @@ get_asset_dir <- function(ref, verb = "find") { path_pr_comment <- function() { fs::path(dir_touchstone(), "pr-comment/info.txt") } + +append_rbuildignore <- function(dir) { + ignore <- ".Rbuildignore" + if (fs::file_exists(ignore)) { + cat( + glue::glue("^{dir}$"), + sep = "\n", file = ignore, append = TRUE + ) + cli::cli_alert_success("Added {.path {dir}} to {.file {ignore}}.") + } else { + cli::cli_alert_warning( + "Could not find {.file {ignore}} to add {.path {dir}}." + ) + } +} diff --git a/man/use_touchstone.Rd b/man/use_touchstone.Rd index 9c8d291..38a45bf 100644 --- a/man/use_touchstone.Rd +++ b/man/use_touchstone.Rd @@ -17,5 +17,10 @@ don't care about old runs when you pushed new code.} The function is called for its side effects and returns \code{NULL} (invisibly). } \description{ -Initiate {touchstone} +This function will initialize {touchstone} in your package repository, use +from root directory. +} +\details{ +For more information see the 'Using touchstone' vignette: +`vignette("touchstone", package = "touchstone") } From 5a7043922d5c138651f52ca4a5be540595ce9fc0 Mon Sep 17 00:00:00 2001 From: assignUser Date: Mon, 13 Sep 2021 19:19:29 +0200 Subject: [PATCH 02/15] add how to vignette --- .pre-commit-config.yaml | 3 +- README.Rmd | 80 ++++++---------------------- README.md | 89 ++++++++----------------------- inst/WORDLIST | 5 ++ inst/script.R | 2 +- vignettes/touchstone.Rmd | 110 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 154 insertions(+), 135 deletions(-) create mode 100644 vignettes/touchstone.Rmd diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1df73e4..5154e9f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -67,7 +67,8 @@ repos: exclude: > (?x)^( tests/testthat/test-prepare\.R| - inst/script\.R + inst/script\.R| + vignettes/touchstone\.R )$ - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.0.1 diff --git a/README.Rmd b/README.Rmd index 775e14e..a172d37 100644 --- a/README.Rmd +++ b/README.Rmd @@ -34,6 +34,21 @@ You can install the package from CRAN: install.packages("touchstone") ``` +And the development version from [GitHub](https://github.com/lorenzwalthert/touchstone){target="_blank"} with: + +``` r +# install.packages("devtools") +devtools::install_github("lorenzwalthert/touchstone") +``` + +## Getting Started +You can start using {touchstone} in your package repository with: +```{r, eval = FALSE} +touchstone::use_touchstone() +``` +For a detailed explanation on how to configure and use {touchstone} see the +["Using touchstone"](https://lorenzwalthert.github.io/touchstone/articles/touchstone.html) vignette. + ## Motivation The motivation for touchstone is to provide accurate benchmarking results for @@ -83,71 +98,6 @@ Once done with the measurements, it will * create visualizations as Github Action artifacts that show how the distribution of the timings for both branches. -## Proposed Workflow - -Initialize {touchstone} in your repo with - -```{r, eval = FALSE} -touchstone::use_touchstone() -``` - -This will: - -- create a `touchstone` directory in the repo root with: - - * `config.json` that defines how to run your benchmark. In particular, you can - define a `benchmarking_repo`, that is, a repo you need to run your bench mark - (use `""` if you don't need an additional git repo checked out for your - benchmark). - This repo will be cloned into `benchmarking_path`. For example to benchmark - {styler}, we format the {here} package with `style_pkg()` that is not part - of the {styler} repo, but with the below config, will be located at - `touchstone/sources/here` during benchmarking. The code you want to - benchmark comes from the benchmarked repo, which in our case is the root - from where you call `use_touchstone()` and hence does not need to be defined - explicitly. - - ```json - - { - "benchmarking_repo": "lorenzwalthert/here", - "benchmarking_ref": "ca9c8e69c727def88d8ba1c8b85b0e0bcea87b3f", - "benchmarking_path": "touchstone/sources/here", - "os": "ubuntu-18.04", - "r": "4.0.0", - "rspm": "https://packagemanager.rstudio.com/all/__linux__/bionic/291" - } - - ``` - - - * `script.R`, the script that runs the benchmark. - - ```{r} -touchstone::refs_install() # installs branches to benchmark - -# benchmark a function call from your package (two calls per branch) -touchstone::benchmark_run_ref( - random_test = yourpkg::fun(), - n = 2 -) - -# create artifacts used downstream in the GitHub Action -touchstone::benchmarks_analyze() - ``` - -- write the workflow files you need for touchstone into `.github/workflows/` to - invoke your touchstone script. - -Note that these files must be committed to the default branch before -{touchstone} continuous benchmarking will be triggered for new PRs. - -If you want to call the script interactively, use `run_script`()` (an -enhanced version of `base::source()`) for various technical reasons described in -the help file. Note that `benchmark_run_ref()` will check out different branches -and should therefore be the only process running in the directory and only in a -clean git working directory. - ## Status This package is experimental. You can see an example usage in diff --git a/README.md b/README.md index d080c6d..ba9a66f 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,27 @@ You can install the package from CRAN: install.packages("touchstone") ``` +And the development version from +[GitHub](https://github.com/lorenzwalthert/touchstone) with: + +``` r +# install.packages("devtools") +devtools::install_github("lorenzwalthert/touchstone") +``` + +## Getting Started + +You can start using {touchstone} in your package repository with: + +``` r +touchstone::use_touchstone() +``` + +For a detailed explanation on how to configure and use {touchstone} see +the [“Using +touchstone”](https://lorenzwalthert.github.io/touchstone/articles/touchstone.html) +vignette. + ## Motivation The motivation for touchstone is to provide accurate benchmarking @@ -78,74 +99,6 @@ Once done with the measurements, it will - create visualizations as Github Action artifacts that show how the distribution of the timings for both branches. -## Proposed Workflow - -Initialize {touchstone} in your repo with - -``` r -touchstone::use_touchstone() -``` - -This will: - - - create a `touchstone` directory in the repo root with: - - - `config.json` that defines how to run your benchmark. In - particular, you can define a `benchmarking_repo`, that is, a - repo you need to run your bench mark (use `""` if you don’t need - an additional git repo checked out for your benchmark). This - repo will be cloned into `benchmarking_path`. For example to - benchmark {styler}, we format the {here} package with - `style_pkg()` that is not part of the {styler} repo, but with - the below config, will be located at `touchstone/sources/here` - during benchmarking. The code you want to benchmark comes from - the benchmarked repo, which in our case is the root from where - you call `use_touchstone()` and hence does not need to be - defined explicitly. - - - - ``` json - - { - "benchmarking_repo": "lorenzwalthert/here", - "benchmarking_ref": "ca9c8e69c727def88d8ba1c8b85b0e0bcea87b3f", - "benchmarking_path": "touchstone/sources/here", - "os": "ubuntu-18.04", - "r": "4.0.0", - "rspm": "https://packagemanager.rstudio.com/all/__linux__/bionic/291" - } - ``` - - - `script.R`, the script that runs the benchmark. - - - - ``` r - touchstone::refs_install() # installs branches to benchmark - - # benchmark a function call from your package (two calls per branch) - touchstone::benchmark_run_ref( - random_test = yourpkg::fun(), - n = 2 - ) - - # create artifacts used downstream in the GitHub Action - touchstone::benchmarks_analyze() - ``` - - - write the workflow files you need for touchstone into - `.github/workflows/` to invoke your touchstone script. - -Note that these files must be committed to the default branch before -{touchstone} continuous benchmarking will be triggered for new PRs. - -If you want to call the script interactively, use `run_script`()`(an -enhanced version of`base::source()`) for various technical reasons -described in the help file. Note that`benchmark\_run\_ref()\` will check -out different branches and should therefore be the only process running -in the directory and only in a clean git working directory. - ## Status This package is experimental. You can see an example usage in diff --git a/inst/WORDLIST b/inst/WORDLIST index 7345821..28b6c35 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -86,6 +86,7 @@ pkgapi pkgdown prepending purrr +quasiquotation rc readFileSync repo @@ -104,6 +105,7 @@ sprintf styfle styler sublicense +subprocess sudo sysreq sysreqs @@ -114,6 +116,9 @@ th tibble tidyselect toString +touchstone +touchstone +touchstone ubuntu usethis va diff --git a/inst/script.R b/inst/script.R index bb4bbf1..a417a46 100644 --- a/inst/script.R +++ b/inst/script.R @@ -3,7 +3,7 @@ # TODO OPTIONAL Add directories you want to be available in this file or during the # benchmarks. -# touchstone::pin_head_assets("some/dir") +# touchstone::pin_assets("some/dir") # installs branches to benchmark touchstone::refs_install() diff --git a/vignettes/touchstone.Rmd b/vignettes/touchstone.Rmd new file mode 100644 index 0000000..a2c45ed --- /dev/null +++ b/vignettes/touchstone.Rmd @@ -0,0 +1,110 @@ +--- +title: "Using touchstone" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Using touchstone} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>", + eval = FALSE +) +``` + +Start by initializing {touchstone} in your package repository with: +```{r, eval = FALSE} +touchstone::use_touchstone() +``` + +This will: + +- create a `touchstone` directory in the repository root with: + + * `config.json` that defines how to run your benchmark. In particular, you can + define a `benchmarking_repo`, that is, a repository you need to run your bench mark + (use `""` if you don't need an additional git repository checked out for your + benchmark). + This repository will be cloned into `benchmarking_path`. For example to benchmark + {styler}, we format the {here} package with `style_pkg()` that is not part + of the {styler} repository, but with the below config, will be located at + `touchstone/sources/here` during benchmarking. The code you want to + benchmark comes from the benchmarked repository, which in our case is the root + from where you call `use_touchstone()` and hence does not need to be defined + explicitly. +```json + { + "benchmarking_repo": "lorenzwalthert/here", + "benchmarking_ref": "ca9c8e69c727def88d8ba1c8b85b0e0bcea87b3f", + "benchmarking_path": "touchstone/sources/here", + "os": "ubuntu-18.04", + "r": "4.0.0", + "rspm": "https://packagemanager.rstudio.com/all/__linux__/bionic/291" + } +``` + * `script.R`, the script that runs the benchmark. + * `header.R`, the script containing the default PR comment header, see `?touchstone::pr_comment`. + * `footer.R`, the script containing the default PR comment footer, see `?touchstone::pr_comment`. +- add the `touchstone` directory to `.Rbuildignore`. +- write the workflow files^[Note that these files must be committed to the default branch before +{touchstone} continuous benchmarking will be triggered for new PRs.] you need to + invoke touchstone in new pull requests into `.github/workflows/`. + +Now you just need to modify `script.R` to run the benchmarks you are interested in. + +## script.R + +The file consists of three parts, two of which you will need to modify to fit your needs. Within the github action {touchstone} will always run the `script.R` from the `HEAD` branch, so you can modify or extend the benchmarks if needed to fit your current branch. + +### Setup + +We first install the different package versions in separate libraries with `refs_install()`, this is mandatory for any `script.R`. If you want to access some directory or file which only exists on one of the branches you can use `pin_assets(..., ref = "branch")` to make them usable across branches. You can of course also run arbitrary code to prepare for the benchmarks. +```{r} +touchstone::refs_install() # installs branches to benchmark +touchstone::pin_assets("data/all.Rdata", "inst/scripts") # pin files and directories + +load(path_pinned_asset("all.Rdata")) # perform other setup you need for the benchmarks +source(path_pinned_asset("scripts/prepare.R")) +data_clean <- prepare_data(data_all) +``` + +### Benchmarks + +Run any number of benchmarks, with one named benchmark per call of `benchmark_run_ref()`. As benchmarks are run in a subprocess, setup (like setting a seed) needs to be passed with `expr_before_benchmark`. You can pass a single function call or a longer block of code wrapped in "{ }". The expressions are captured with `rlang` so you can use [quasiquotation](https://rlang.r-lib.org/reference/quasiquotation.html). +```{r} +# benchmark a function call from your package +touchstone::benchmark_run_ref( + random_test = yourpkg::fun(data_clean), + n = 2 +) + +# Optionally run setup code +touchstone::benchmark_run_ref( + expr_before_benchmark = { + library(yourpkg) + set.seed(42) + }, + test_with_seed = fun(data_clean), + n = 2 +) +``` + +### Analyze + This part is just one call to `benchmarks_analyze()`which analyses the results and prepares the PR comment. +```{r} +# create artifacts used downstream in the GitHub Action +touchstone::benchmarks_analyze() +``` + + +## Running the script +After you have committed the workflow files to your default branch the benchmarks will be run on new pull requests and on each commit while that pull request is open. + +If you want to call the script interactively, use `run_script`()` (an +enhanced version of `base::source()`) for various technical reasons described in +the help file. Note that `benchmark_run_ref()` will check out different branches +and should therefore be the only process running in the directory and only in a +clean git working directory. From 6ba2261ed0394700de59461698345c907a10b5e4 Mon Sep 17 00:00:00 2001 From: assignUser Date: Mon, 13 Sep 2021 19:23:50 +0200 Subject: [PATCH 03/15] update snapshot --- tests/testthat/_snaps/use.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/testthat/_snaps/use.md b/tests/testthat/_snaps/use.md index 39db607..95e90d5 100644 --- a/tests/testthat/_snaps/use.md +++ b/tests/testthat/_snaps/use.md @@ -10,6 +10,7 @@ v Populated file '.gitignore' in 'touchstone/'. v Populated file 'touchstone-receive.yaml' in '.github/workflows/'. v Populated file 'touchstone-comment.yaml' in '.github/workflows/'. + ! Could not find '.Rbuildignore' to add 'touchstone'. v Populated file 'cancel.yaml' in '.github/workflows/'. v Added a cancelling action for the touchstone workflow. i A new push to a branch will stop the current benchmarking run and start @@ -35,6 +36,7 @@ v Populated file .gitignore in touchstone/. v Populated file touchstone-receive.yaml in .github/workflows/. v Populated file touchstone-comment.yaml in .github/workflows/. + ! Could not find .Rbuildignore to add touchstone. v Populated file cancel.yaml in .github/workflows/. v Added a cancelling action for the touchstone workflow. i A new push to a branch will stop the current benchmarking run and start From 240b65cb2b5403dc43dd3abbb66945dce3006d38 Mon Sep 17 00:00:00 2001 From: assignUser Date: Tue, 14 Sep 2021 13:39:48 +0200 Subject: [PATCH 04/15] expand vignette, update screenshot --- .pre-commit-config.yaml | 2 +- inst/WORDLIST | 2 +- man/figures/screenshot-pr-comment.png | Bin 57446 -> 25620 bytes vignettes/touchstone.Rmd | 11 +++++++++++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5154e9f..eeaa4b7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -68,7 +68,7 @@ repos: (?x)^( tests/testthat/test-prepare\.R| inst/script\.R| - vignettes/touchstone\.R + vignettes/touchstone\.Rmd )$ - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.0.1 diff --git a/inst/WORDLIST b/inst/WORDLIST index 28b6c35..5ddd738 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -90,6 +90,7 @@ quasiquotation rc readFileSync repo +rightarrow rlang rmarkdown roclet @@ -118,7 +119,6 @@ tidyselect toString touchstone touchstone -touchstone ubuntu usethis va diff --git a/man/figures/screenshot-pr-comment.png b/man/figures/screenshot-pr-comment.png index 896f78ba76854cf3adeed367369bf88c0e29670b..5d59f1890e8b7cd5ef327c7f68f516ac7b2e4e33 100644 GIT binary patch literal 25620 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 literal 57446 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 Date: Thu, 16 Sep 2021 21:43:46 +0200 Subject: [PATCH 05/15] minor edits --- vignettes/touchstone.Rmd | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vignettes/touchstone.Rmd b/vignettes/touchstone.Rmd index 61f6fc6..734bfa7 100644 --- a/vignettes/touchstone.Rmd +++ b/vignettes/touchstone.Rmd @@ -61,7 +61,7 @@ The file consists of three parts, two of which you will need to modify to fit yo ### Setup -We first install the different package versions in separate libraries with `refs_install()`, this is mandatory for any `script.R`. If you want to access some directory or file which only exists on one of the branches you can use `pin_assets(..., ref = "branch")` to make them usable across branches. You can of course also run arbitrary code to prepare for the benchmarks. +We first install the different package versions in separate libraries with `refs_install()`, this is mandatory for any `script.R`. If you want to access some directory or file which only exists on one of the branches you can use `pin_assets(..., ref = "your-branch-name")` to make them available across branches. You can of course also run arbitrary code to prepare for the benchmarks. ```{r} touchstone::refs_install() # installs branches to benchmark touchstone::pin_assets("data/all.Rdata", "inst/scripts") # pin files and directories @@ -103,14 +103,14 @@ touchstone::benchmarks_analyze() ## Running the script After you have committed the workflow files to your default branch the benchmarks will be run on new pull requests and on each commit while that pull request is open. -If you want to call the script interactively, use `run_script`()` (an +If you want to call the script interactively, use `run_script()` (an enhanced version of `base::source()`) for various technical reasons described in the help file. Note that `benchmark_run_ref()` will check out different branches and should therefore be the only process running in the directory and only in a clean git working directory. ## The Results -When the github action successfully completes, the main result you will see is the comment posted on the pull request, it will look something like this: +When the GitHub Action successfully completes, the main result you will see is the comment posted on the pull request, it will look something like this: ![](../man/figures/screenshot-pr-comment.png) @@ -118,4 +118,4 @@ You can change the header and footer, see `?touchstone::pr_comment`. The main bo To make it easier to spot benchmarks that need closer attention, we prefix the benchmarks with emojis indicating if there was a statistically significant change (see [inference](https://lorenzwalthert.github.io/touchstone/articles/inference.html)) in the timing or not. In this example the HEAD version of `func1` is significantly faster, `func3` is slower than BASE while there is no significant change for `func2`. -The github action will also upload this text and plots of the timings as artifacts. +The GitHub Action will also upload this text and plots of the timings as artifacts. From c268c7dcc9d9864fcefe48bb3ed950da5465d6ed Mon Sep 17 00:00:00 2001 From: Lorenz Walthert Date: Thu, 16 Sep 2021 21:53:04 +0200 Subject: [PATCH 06/15] vignette similar to styler --- _pkgdown.yml | 8 ++++++++ inst/WORDLIST | 53 ++++++++++++++++++++++++++------------------------- 2 files changed, 35 insertions(+), 26 deletions(-) diff --git a/_pkgdown.yml b/_pkgdown.yml index 26fe068..76ea9b0 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -2,5 +2,13 @@ authors: Lorenz Walthert: href: https://lorenzwalthert.netlify.com +articles: +- title: Get started + navbar: ~ + contents: + - touchstone + - inference + + development: mode: auto diff --git a/inst/WORDLIST b/inst/WORDLIST index 5ddd738..380bf3f 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -1,37 +1,16 @@ -BugReports -CMD -Config -Jens -LIBS -LazyData -Lifecycle -MERCHANTABILITY -NONINFRINGEMENT -ORCID -PRs -README -RHUB -RSPM -Rds -Roxygen -RoxygenNote -Rscript -SHA -Sys -VMs -VignetteBuilder -Walthert -Wujciak api aut ba bcea benchmarked benchmarking +BugReports callr ci cli +CMD config +Config cr cran cre @@ -52,8 +31,8 @@ fromJson fs gcc gert -getRversion getenv +getRversion getwd ggplot github @@ -64,12 +43,16 @@ https icloud io jacob +Jens json knitr +LazyData lenth libcurl libgit libpaths +LIBS +Lifecycle linux listWorkflowRunArtifacts lorenz @@ -77,37 +60,52 @@ lorenzwalthert magrittr matchArtifact md +MERCHANTABILITY mkdir +navbar +netlify +NONINFRINGEMENT openssl orcid +ORCID os packagemanager pkgapi pkgdown prepending +PRs purrr quasiquotation rc +Rds readFileSync +README repo +RHUB rightarrow rlang rmarkdown roclet roclets roxygen +Roxygen +RoxygenNote +Rscript rspm +RSPM rstudio runif saveRDS seealso sep +SHA sprintf styfle styler sublicense subprocess sudo +Sys sysreq sysreqs tada @@ -118,14 +116,17 @@ tibble tidyselect toString touchstone -touchstone ubuntu usethis va vctrs +VignetteBuilder +VMs walthert +Walthert withr writeFileSync writeLines wujciak +Wujciak yourpkg From d2aa981143230aa051ee4e5bc1d66dd0dda744ec Mon Sep 17 00:00:00 2001 From: assignUser Date: Sun, 17 Oct 2021 20:40:01 +0200 Subject: [PATCH 07/15] add git root handeling --- R/utils.R | 93 ++++++++++++++++++++++++++++------ R/zzz.R | 2 + man/pin_assets.Rd | 14 ++--- tests/testthat/_snaps/utils.md | 24 ++++++++- tests/testthat/test-utils.R | 19 ++++++- 5 files changed, 126 insertions(+), 26 deletions(-) diff --git a/R/utils.R b/R/utils.R index c374822..1316f14 100644 --- a/R/utils.R +++ b/R/utils.R @@ -191,24 +191,24 @@ is_windows <- function() { #' #' Pin files or directories that need to be available on both branches when #' running the `touchstone_script`. During [benchmark_run_ref()] they will -#' available via [path_pinned_asset()]. +#' available via [path_pinned_asset()]. This is only possible for assets +#' *within* the git repository. #' @param ... Any number of directories or files, as strings, that you want to #' access in your [touchstone_script]. #' @param ref The branch the passed assets are copied from. #' @inheritParams fs::path #' @inheritParams fs::dir_copy #' @details When passing nested directories or files within nested directories -#' only the file/last directory will be copied. Directories will be copied -#' recursively. See examples. +#' the path will be copied recursively. See examples. #' @return The asset directory invisibly. #' @examples #' \dontrun{ -#' # In the touchstone script +#' # In the touchstone script within the repo "/home/user/pkg" #' -#' pin_assets(c("bench", "inst/setup.R", "some/nested/dir")) +#' pin_assets(c("/home/user/pkg/bench", "inst/setup.R", "some/nested/dir")) #' -#' source(path_pinned_asset("setup.R")) -#' load(path_pinned_asset("dir/data.RData")) +#' source(path_pinned_asset("inst/setup.R")) +#' load(path_pinned_asset("some/nested/dir/data.RData")) #' #' touchstone::benchmark_run_ref( #' expr_before_benchmark = { @@ -236,20 +236,54 @@ pin_assets <- function(..., )) } - dirs[valid_dirs] %>% purrr::walk( - ~ purrr::when( - .x, - fs::is_dir(.)[[1]] ~ fs::dir_copy(.x, - fs::path_join(c(asset_dir, fs::path_file(.x))), + create_and_copy <- function(asset) { + git_root <- get_git_root() + asset <- fs::path_real(asset) + + if (!fs::path_has_parent(asset, git_root)) { + cli::cli_abort(c( + "Can only pin assets within the git repository!", + "i" = "Current repo: {.path {git_root}}" + )) + } + + rel_asset <- fs::path_rel(asset, git_root) + new_path <- fs::path_join(c(asset_dir, rel_asset)) + + if (fs::is_dir(asset)[[1]]) { + fs::dir_copy( + asset, + new_path, overwrite = overwrite - ), - fs::is_file(.)[[1]] ~ fs::file_copy(.x, - fs::path_join(c(asset_dir, fs::path_file(.x))), + ) + } else if (fs::is_file(asset)[[1]]) { + fs::path_dir(rel_asset) %>% + fs::path(asset_dir, .) %>% + fs::dir_create() + + fs::file_copy( + asset, + new_path, overwrite = overwrite ) - ) + } + } + + dirs[valid_dirs] %>% purrr::walk( + create_and_copy + # ~ purrr::when( + # .x, + # fs::is_dir(.)[[1]] ~ fs::dir_copy(.x, + # fs::path_join(c(asset_dir, fs::path_file(.x))), + # overwrite = overwrite + # ), + # fs::is_file(.)[[1]] ~ fs::file_copy(.x, + # fs::path_join(c(asset_dir, fs::path_file(.x))), + # overwrite = overwrite + # ) ) + if (any(valid_dirs)) { cli::cli_alert_success( paste0( @@ -334,3 +368,30 @@ append_rbuildignore <- function(dir) { ) } } + +find_git_root <- function(path = ".") { + tryCatch( + gert::git_find(path), + error = function(err) { + cli::cli_alert_danger( + "Could not find git repository from current working directory!" + ) + cli::cli_alert_info( + "Please manually set the option {.val touchstone.git_root}." + ) + NULL + } + ) +} + +get_git_root <- function() { + git_root <- getOption("touchstone.git_root") + + if (is.null(git_root)) { + cli::cli_abort(c("Option {.val touchstone.git_root} not set!", + "i" = 'Set it with {.code options(touchstone.git_root = "path to repo")}' + )) + } + + git_root +} diff --git a/R/zzz.R b/R/zzz.R index 9e6dd6b..2c4299c 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -3,8 +3,10 @@ cache <- tibble::tibble( ref = character(), md5_hashes = list(), path_pkg = character() ) + op.touchstone <- list( "touchstone.skip_install" = FALSE, + "touchstone.git_root" = find_git_root(), "touchstone.dir" = "touchstone", # how many times should inner loop be ran in benchmark_run_iteration "touchstone.n_iterations" = 1, diff --git a/man/pin_assets.Rd b/man/pin_assets.Rd index a8d738d..b16df8e 100644 --- a/man/pin_assets.Rd +++ b/man/pin_assets.Rd @@ -21,21 +21,21 @@ The asset directory invisibly. \description{ Pin files or directories that need to be available on both branches when running the \code{touchstone_script}. During \code{\link[=benchmark_run_ref]{benchmark_run_ref()}} they will -available via \code{\link[=path_pinned_asset]{path_pinned_asset()}}. +available via \code{\link[=path_pinned_asset]{path_pinned_asset()}}. This is only possible for assets +\emph{within} the git repository. } \details{ When passing nested directories or files within nested directories -only the file/last directory will be copied. Directories will be copied -recursively. See examples. +the path will be copied recursively. See examples. } \examples{ \dontrun{ -# In the touchstone script +# In the touchstone script within the repo "/home/user/pkg" -pin_assets(c("bench", "inst/setup.R", "some/nested/dir")) +pin_assets(c("/home/user/pkg/bench", "inst/setup.R", "some/nested/dir")) -source(path_pinned_asset("setup.R")) -load(path_pinned_asset("dir/data.RData")) +source(path_pinned_asset("inst/setup.R")) +load(path_pinned_asset("some/nested/dir/data.RData")) touchstone::benchmark_run_ref( expr_before_benchmark = { diff --git a/tests/testthat/_snaps/utils.md b/tests/testthat/_snaps/utils.md index 7393506..980355f 100644 --- a/tests/testthat/_snaps/utils.md +++ b/tests/testthat/_snaps/utils.md @@ -1,6 +1,6 @@ # ref can be sampled - WAoAAAACAAQABQACAwAAAAMTAAAAAgAAAA0AAAAoAAAAAQAAAAEAAAACAAAAAgAAAAMAAAAD + WAoAAAACAAQBAQACAwAAAAMTAAAAAgAAAA0AAAAoAAAAAQAAAAEAAAACAAAAAgAAAAMAAAAD AAAABAAAAAQAAAAFAAAABQAAAAYAAAAGAAAABwAAAAcAAAAIAAAACAAAAAkAAAAJAAAACgAA AAoAAAALAAAACwAAAAwAAAAMAAAADQAAAA0AAAAOAAAADgAAAA8AAAAPAAAAEAAAABAAAAAR AAAAEQAAABIAAAASAAAAEwAAABMAAAAUAAAAFAAAABAAAAAoAAQACQAAAARtYWluAAQACQAA @@ -20,7 +20,7 @@ --- - WAoAAAACAAQABQACAwAAAAMTAAAAAgAAAA0AAAA0AAAAAQAAAAEAAAABAAAAAQAAAAEAAAAB + WAoAAAACAAQBAQACAwAAAAMTAAAAAgAAAA0AAAA0AAAAAQAAAAEAAAABAAAAAQAAAAEAAAAB AAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAA AAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAAC AAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAA @@ -38,3 +38,23 @@ BAIAAAABAAQACQAAAAVjbGFzcwAAABAAAAADAAQACQAAAAZ0YmxfZGYABAAJAAAAA3RibAAE AAkAAAAKZGF0YS5mcmFtZQAAAP4= +# git root is found correctly [plain] + + Code + find_git_root(no_git) + Message + x Could not find git repository from current working directory! + i Please manually set the option "touchstone.git_root". + Output + NULL + +# git root is found correctly [ansi] + + Code + find_git_root(no_git) + Message + x Could not find git repository from current working directory! + i Please manually set the option "touchstone.git_root". + Output + NULL + diff --git a/tests/testthat/test-utils.R b/tests/testthat/test-utils.R index fc67e1d..b3865ca 100644 --- a/tests/testthat/test-utils.R +++ b/tests/testthat/test-utils.R @@ -156,6 +156,7 @@ test_that("assets work on HEAD", { withr::with_options( list( touchstone.dir_assets_head = NULL, + touchstone.git_root = fs::path_temp("test_pkg", "R"), usethis.quiet = TRUE ), withr::with_envvar(list( @@ -169,6 +170,7 @@ test_that("assets work on HEAD", { withr::with_options(list( touchstone.dir_assets_head = temp_dir, + touchstone.git_root = fs::path_temp("test_pkg"), usethis.quiet = TRUE ), { withr::local_envvar(list( @@ -198,7 +200,7 @@ test_that("assets work HEAD and BASE", { )) branches <- c("rc-1.0", "feat") - local_package(branches = branches) + git_root <- local_package(branches = branches) dirs <- c("R", "bench") %>% rlang::set_names(branches) files <- c("data.Rdata", "utils.R") %>% rlang::set_names(branches) @@ -208,6 +210,7 @@ test_that("assets work HEAD and BASE", { fs::file_create(files[branch]) } + withr::local_options(list(touchstone.git_root = git_root)) withr::local_envvar(list( GITHUB_BASE_REF = branches[[1]], GITHUB_HEAD_REF = branches[[2]] @@ -243,3 +246,17 @@ test_that("asset paths are fetched correctly", { expect_error(get_asset_dir("main"), "directory not found") expect_equal(get_asset_dir("devel"), "asset/dir") }) + +cli::test_that_cli("git root is found correctly", { + no_git <- fs::path_temp("no-git") + with_git <- fs::path_temp("with-git") + deeper_git <- fs::path_temp("with-git", "deep", "deeper") + fs::dir_create(c(no_git, with_git, deeper_git)) + withr::with_dir(with_git, { + gert::git_init() + }) + + expect_snapshot(find_git_root(no_git)) + expect_equal(find_git_root(with_git), as.character(with_git)) + expect_equal(find_git_root(deeper_git), as.character(with_git)) +}) From a589c80d0fd4891f1abc10798a3855bc1370530c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 17 Oct 2021 20:29:29 +0000 Subject: [PATCH 08/15] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- inst/WORDLIST | 51 ++++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/inst/WORDLIST b/inst/WORDLIST index 45b4fa4..9e4273b 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -1,16 +1,37 @@ +BugReports +CMD +Config +Jens +LIBS +LazyData +Lifecycle +MERCHANTABILITY +NONINFRINGEMENT +ORCID +PRs +README +RHUB +RSPM +Rds +Roxygen +RoxygenNote +Rscript +SHA +Sys +VMs +VignetteBuilder +Walthert +Wujciak api aut ba bcea benchmarked benchmarking -BugReports callr ci cli -CMD config -Config cr cran cre @@ -31,8 +52,8 @@ fromJson fs gcc gert -getenv getRversion +getenv getwd ggplot github @@ -43,16 +64,12 @@ https icloud io jacob -Jens json knitr -LazyData lenth libcurl libgit libpaths -LIBS -Lifecycle linux listWorkflowRunArtifacts lorenz @@ -60,53 +77,41 @@ lorenzwalthert magrittr matchArtifact md -MERCHANTABILITY mkdir navbar netlify -NONINFRINGEMENT openssl orcid -ORCID os packagemanager pkgapi pkgdown prepending -PRs purrr quasiquotation rc -Rds readFileSync -README repo -RHUB rightarrow rlang rmarkdown roclet roclets roxygen -Roxygen -RoxygenNote -Rscript rspm -RSPM rstudio runif saveRDS seealso sep -SHA sideefects +sideeffects sprintf styfle styler sublicense subprocess sudo -Sys sysreq sysreqs tada @@ -121,13 +126,9 @@ ubuntu usethis va vctrs -VignetteBuilder -VMs walthert -Walthert withr writeFileSync writeLines wujciak -Wujciak yourpkg From ed7b738a9beefb8d4460b5a9d96f72b08d601d97 Mon Sep 17 00:00:00 2001 From: Lorenz Walthert Date: Sun, 17 Oct 2021 22:31:34 +0200 Subject: [PATCH 09/15] drop random word --- inst/WORDLIST | 1 - 1 file changed, 1 deletion(-) diff --git a/inst/WORDLIST b/inst/WORDLIST index 9e4273b..e6eb62f 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -104,7 +104,6 @@ runif saveRDS seealso sep -sideefects sideeffects sprintf styfle From 1bd2bc262a1765d3568a529917e244b484b74d9c Mon Sep 17 00:00:00 2001 From: assignUser Date: Mon, 18 Oct 2021 11:54:50 +0200 Subject: [PATCH 10/15] clean up and fix tests --- tests/testthat/test-utils.R | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/tests/testthat/test-utils.R b/tests/testthat/test-utils.R index b3865ca..01d1d17 100644 --- a/tests/testthat/test-utils.R +++ b/tests/testthat/test-utils.R @@ -117,7 +117,11 @@ test_that("Can abort with missing refs for benchmark run", { benchmark_run_ref, "force", function(...) cli::cli_abort("12321") ) - withr::local_envvar(list(GITHUB_HEAD_REF = "feature1", GITHUB_BASE_REF = "mastero")) + withr::local_envvar(list( + GITHUB_HEAD_REF = "feature1", + GITHUB_BASE_REF = "mastero" + )) + expect_error( benchmark_run_ref(x1 = "print('hi')"), "12321" @@ -152,6 +156,10 @@ test_that("assets work on HEAD", { temp_dir <- fs::path_temp() fs::dir_create(dirs) fs::file_create(files) + withr::local_envvar(list( + GITHUB_BASE_REF = "main", + GITHUB_HEAD_REF = "devel" + )) withr::with_options( list( @@ -159,13 +167,10 @@ test_that("assets work on HEAD", { touchstone.git_root = fs::path_temp("test_pkg", "R"), usethis.quiet = TRUE ), - withr::with_envvar(list( - GITHUB_BASE_REF = "main", - GITHUB_HEAD_REF = "devel" - ), { + { expect_error(pin_assets("something"), "Temporary directory not found.") expect_error(path_pinned_asset("something"), "Temporary directory ") - }) + } ) withr::with_options(list( @@ -173,10 +178,6 @@ test_that("assets work on HEAD", { touchstone.git_root = fs::path_temp("test_pkg"), usethis.quiet = TRUE ), { - withr::local_envvar(list( - GITHUB_BASE_REF = "main", - GITHUB_HEAD_REF = "devel" - )) expect_warning(pin_assets("something", dirs[[1]]), "could not be found") expect_error(suppressWarnings(pin_assets("something")), "No valid") expect_equal(pin_assets(!!!dirs), temp_dir) @@ -194,15 +195,17 @@ test_that("assets work on HEAD", { test_that("assets work HEAD and BASE", { head_asset_dir <- fs::path_temp("head") base_asset_dir <- fs::path_temp("base") - withr::local_options(list( - touchstone.dir_assets_head = head_asset_dir, - touchstone.dir_assets_base = base_asset_dir - )) + branches <- c("rc-1.0", "feat") git_root <- local_package(branches = branches) dirs <- c("R", "bench") %>% rlang::set_names(branches) files <- c("data.Rdata", "utils.R") %>% rlang::set_names(branches) + withr::local_options(list( + touchstone.dir_assets_head = head_asset_dir, + touchstone.dir_assets_base = base_asset_dir, + touchstone.git_root = git_root + )) for (branch in branches) { gert::git_branch_checkout(branch) @@ -210,7 +213,6 @@ test_that("assets work HEAD and BASE", { fs::file_create(files[branch]) } - withr::local_options(list(touchstone.git_root = git_root)) withr::local_envvar(list( GITHUB_BASE_REF = branches[[1]], GITHUB_HEAD_REF = branches[[2]] @@ -242,6 +244,7 @@ test_that("asset paths are fetched correctly", { GITHUB_BASE_REF = "main", GITHUB_HEAD_REF = "devel" )) + expect_error(get_asset_dir("not-main"), "head or base") expect_error(get_asset_dir("main"), "directory not found") expect_equal(get_asset_dir("devel"), "asset/dir") From 00c9f31c8f6ef482a9e8fa124e2eb49b590bf984 Mon Sep 17 00:00:00 2001 From: assignUser Date: Mon, 18 Oct 2021 12:20:35 +0200 Subject: [PATCH 11/15] change to fs --- R/testing.R | 4 ++-- tests/testthat/test-utils.R | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/R/testing.R b/R/testing.R index 7bab858..3832a50 100644 --- a/R/testing.R +++ b/R/testing.R @@ -29,12 +29,12 @@ path_temp_pkg <- function(name) { #' @inheritParams withr::defer #' @family testers #' @keywords internal -local_package <- function(pkg_name = fs::path_file(tempfile("pkg")), +local_package <- function(pkg_name = fs::path_file(fs::file_temp("pkg")), branches = c("main", "devel"), r_sample = NULL, setwd = TRUE, envir = parent.frame()) { - path <- fs::path(tempfile(""), pkg_name) + path <- fs::path(fs::file_temp(""), pkg_name) fs::dir_create(path) withr::local_options( usethis.quiet = TRUE, diff --git a/tests/testthat/test-utils.R b/tests/testthat/test-utils.R index 01d1d17..9752156 100644 --- a/tests/testthat/test-utils.R +++ b/tests/testthat/test-utils.R @@ -93,7 +93,7 @@ test_that("can remove touchstone libpaths", { if (is_windows()) { # cannot have touchstone library in temp, as lib path comparison becomes # unfeasible due to short/name notation - withr::local_options(dir_touchstone = fs::path_file(tempfile())) + withr::local_options(dir_touchstone = fs::path_file(fs::file_temp())) } path_pkg <- local_package(setwd = !is_windows()) new_libpaths <- refs_install(refs, path_pkg, install_dependencies = FALSE) From be845242df73d4d84c3414ed161f8d4dc99e34b9 Mon Sep 17 00:00:00 2001 From: assignUser Date: Mon, 18 Oct 2021 12:24:09 +0200 Subject: [PATCH 12/15] update doc --- man/local_package.Rd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/local_package.Rd b/man/local_package.Rd index 7ae77c6..2886d3c 100644 --- a/man/local_package.Rd +++ b/man/local_package.Rd @@ -5,7 +5,7 @@ \title{Create a test package} \usage{ local_package( - pkg_name = fs::path_file(tempfile("pkg")), + pkg_name = fs::path_file(fs::file_temp("pkg")), branches = c("main", "devel"), r_sample = NULL, setwd = TRUE, From 2c1c60a09102af85ac71119b1363e1a121b8bcb9 Mon Sep 17 00:00:00 2001 From: assignUser Date: Mon, 18 Oct 2021 12:45:52 +0200 Subject: [PATCH 13/15] remove fs::path_real --- R/utils.R | 2 +- tests/testthat/test-utils.R | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/R/utils.R b/R/utils.R index 1316f14..b2dd367 100644 --- a/R/utils.R +++ b/R/utils.R @@ -238,7 +238,7 @@ pin_assets <- function(..., create_and_copy <- function(asset) { git_root <- get_git_root() - asset <- fs::path_real(asset) + # asset <- fs::path_real(asset) if (!fs::path_has_parent(asset, git_root)) { cli::cli_abort(c( diff --git a/tests/testthat/test-utils.R b/tests/testthat/test-utils.R index 9752156..9af688b 100644 --- a/tests/testthat/test-utils.R +++ b/tests/testthat/test-utils.R @@ -164,7 +164,7 @@ test_that("assets work on HEAD", { withr::with_options( list( touchstone.dir_assets_head = NULL, - touchstone.git_root = fs::path_temp("test_pkg", "R"), + touchstone.git_root = fs::path_temp("test_pkg"), usethis.quiet = TRUE ), { From 0cdd7b991e4d16701d1276adee91b083a0adc3f8 Mon Sep 17 00:00:00 2001 From: assignUser Date: Mon, 18 Oct 2021 13:00:17 +0200 Subject: [PATCH 14/15] use fs::path_real in tests --- R/utils.R | 2 +- tests/testthat/test-utils.R | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/R/utils.R b/R/utils.R index b2dd367..1316f14 100644 --- a/R/utils.R +++ b/R/utils.R @@ -238,7 +238,7 @@ pin_assets <- function(..., create_and_copy <- function(asset) { git_root <- get_git_root() - # asset <- fs::path_real(asset) + asset <- fs::path_real(asset) if (!fs::path_has_parent(asset, git_root)) { cli::cli_abort(c( diff --git a/tests/testthat/test-utils.R b/tests/testthat/test-utils.R index 9af688b..e4361de 100644 --- a/tests/testthat/test-utils.R +++ b/tests/testthat/test-utils.R @@ -156,6 +156,8 @@ test_that("assets work on HEAD", { temp_dir <- fs::path_temp() fs::dir_create(dirs) fs::file_create(files) + dirs <- fs::path_real(dirs) + files <- fs::path_real(files) withr::local_envvar(list( GITHUB_BASE_REF = "main", GITHUB_HEAD_REF = "devel" @@ -164,7 +166,7 @@ test_that("assets work on HEAD", { withr::with_options( list( touchstone.dir_assets_head = NULL, - touchstone.git_root = fs::path_temp("test_pkg"), + touchstone.git_root = fs::path_real(fs::path_temp("test_pkg")), usethis.quiet = TRUE ), { @@ -175,7 +177,7 @@ test_that("assets work on HEAD", { withr::with_options(list( touchstone.dir_assets_head = temp_dir, - touchstone.git_root = fs::path_temp("test_pkg"), + touchstone.git_root = fs::path_real(fs::path_temp("test_pkg")), usethis.quiet = TRUE ), { expect_warning(pin_assets("something", dirs[[1]]), "could not be found") @@ -204,7 +206,7 @@ test_that("assets work HEAD and BASE", { withr::local_options(list( touchstone.dir_assets_head = head_asset_dir, touchstone.dir_assets_base = base_asset_dir, - touchstone.git_root = git_root + touchstone.git_root = fs::path_real(git_root) )) for (branch in branches) { @@ -255,6 +257,11 @@ cli::test_that_cli("git root is found correctly", { with_git <- fs::path_temp("with-git") deeper_git <- fs::path_temp("with-git", "deep", "deeper") fs::dir_create(c(no_git, with_git, deeper_git)) + + no_git <- fs::path_real(no_git) + with_git <- fs::path_real(with_git) + deeper_git <- fs::path_real(deeper_git) + withr::with_dir(with_git, { gert::git_init() }) From e91150eacb774474544d07ffa543e8117bb49c39 Mon Sep 17 00:00:00 2001 From: assignUser Date: Mon, 18 Oct 2021 13:14:11 +0200 Subject: [PATCH 15/15] set asset dirs onLoad --- R/source.R | 6 ------ R/zzz.R | 5 ++++- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/R/source.R b/R/source.R index 3a1bf71..c373069 100644 --- a/R/source.R +++ b/R/source.R @@ -54,12 +54,6 @@ run_script <- function(path = "touchstone/script.R", action = "prefix" ) - head_asset_dir <- fs::path_temp("head") - base_asset_dir <- fs::path_temp("base") - options( - touchstone.dir_assets_head = head_asset_dir, - touchstone.dir_assets_base = base_asset_dir - ) temp_file <- fs::file_temp() fs::file_copy(path, temp_file) diff --git a/R/zzz.R b/R/zzz.R index 2c4299c..b22e2af 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -10,8 +10,11 @@ "touchstone.dir" = "touchstone", # how many times should inner loop be ran in benchmark_run_iteration "touchstone.n_iterations" = 1, - "touchstone.hash_source_package" = cache + "touchstone.hash_source_package" = cache, + "touchstone.dir_assets_head" = fs::path_temp("head"), + "touchstone.dir_assets_base" = fs::path_temp("base") ) + toset <- !(names(op.touchstone) %in% names(op)) if (any(toset)) options(op.touchstone[toset]) invisible()