Skip to content

Commit beba7b0

Browse files
committed
Fix #1282
1 parent 55244e8 commit beba7b0

File tree

10 files changed

+143
-1
lines changed

10 files changed

+143
-1
lines changed

.Rbuildignore

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
^build_site.R$
33
^pkgdown$
44
^\.DS_Store
5+
^_drake\.R$
56
^\.drake$
67
^\.drake_history$
78
^\.future$

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Thumbs.db
1818
*.synctex.gz
1919
*.toc
2020
*.vrb
21+
_drake.R
2122
.drake
2223
.drake_history
2324
.DS_Store

NAMESPACE

+1
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ export(drake_plan_source)
104104
export(drake_progress)
105105
export(drake_quotes)
106106
export(drake_running)
107+
export(drake_script)
107108
export(drake_session)
108109
export(drake_slice)
109110
export(drake_strings)

NEWS.md

+4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
* Strongly depend on `tidyselect` (#1274, @dernst).
1212
* Avoid `txtq` lockfiles (#1232, #1239, #1280, @danwwilson, @pydupont, @mattwarkentin).
1313

14+
## New features
15+
16+
* Add a new `drake_script()` function to write `_drake.R` files for `r_make()` (#1282).
17+
1418
# Version 7.12.2
1519

1620
## Bug fixes

R/drake_script.R

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#' @title Write an example `_drake.R` script to the current working directory.
2+
#' @export
3+
#' @description A `_drake.R` file is required for [r_make()] and friends.
4+
#' See the [r_make()] help file for details.
5+
#' @return Nothing.
6+
#' @param code R code to put in `_drake.R` in the current working directory.
7+
#' If `NULL`, an example script is written.
8+
#' @examples
9+
#' \dontrun{
10+
#' isolate_example("contain side-effects", {
11+
#' drake_script({
12+
#' library(drake)
13+
#' plan <- drake_plan(x = 1)
14+
#' drake_config(plan, lock_cache = FALSE)
15+
#' })
16+
#' cat(readLines("_drake.R"), sep = "\n")
17+
#' r_make()
18+
#' })
19+
#' }
20+
drake_script <- function(code = NULL) {
21+
code <- substitute(code)
22+
if (length(code)) {
23+
text <- parse_drake_script_code(code)
24+
} else {
25+
text <- example_drake_script()
26+
}
27+
writeLines(text, "_drake.R")
28+
}
29+
30+
example_drake_script <- function() {
31+
path <- system.file(
32+
file.path("templates", "drake_script", "example_drake.R"),
33+
package = "drake",
34+
mustWork = TRUE
35+
)
36+
readLines(path)
37+
}
38+
39+
parse_drake_script_code <- function(code) {
40+
if (length(code) > 1L && safe_deparse(code[[1]]) == "`{`") {
41+
vcapply(code[-1], safe_deparse)
42+
} else {
43+
safe_deparse(code)
44+
}
45+
}

_pkgdown.yml

+1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ reference:
7474
- '`read_trace`'
7575
- title: Reproducible R session management
7676
contents:
77+
- '`drake_script`'
7778
- '`r_make`'
7879
- '`r_drake_build`'
7980
- '`r_outdated`'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# This file serves the r_*() functions (e.g. r_make()) documented at
2+
# https://books.ropensci.org/drake/projects.html#safer-interactivity # nolint
3+
# and
4+
# https://docs.ropensci.org/drake/reference/r_make.html
5+
6+
# Load all your packages before calling make().
7+
library(drake)
8+
library(tibble)
9+
10+
# Custom functions are an important part of a drake workflow.
11+
# This is where you write them.
12+
# Details: https://books.ropensci.org/drake/plans.html#functions
13+
14+
generate_data <- function() {
15+
tibble(x = rnorm(1e5), y = rnorm(1e5))
16+
}
17+
18+
fit_model <- function(data) {
19+
summary(lm(y ~ x, data = data))
20+
}
21+
22+
# This is where you write your drake plan.
23+
# Details: https://books.ropensci.org/drake/plans.html
24+
25+
plan <- drake_plan(
26+
data = generate_data(),
27+
model = fit_model(data)
28+
)
29+
30+
# You could have put all the above into separate script files and
31+
# source()'d them as below:
32+
33+
# source("R/packages.R") # Load your packages, e.g. library(drake). # nolint
34+
# source("R/functions.R") # Define your custom code as a bunch of functions. # nolint
35+
# source("R/plan.R") # Create your drake plan. # nolint
36+
37+
# _drake.R must end with a call to drake_config().
38+
# The arguments to drake_config() are basically the same as those to make().
39+
drake_config(plan)

man/drake_script.Rd

+32
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/make.Rd

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-zzz-callr.R

+18
Original file line numberDiff line numberDiff line change
@@ -226,3 +226,21 @@ test_with_dir("errors keep their informative messages (#969)", {
226226
class = "callr_error"
227227
)
228228
})
229+
230+
test_with_dir("drake_script() can generate an example script", {
231+
drake_script()
232+
expect_true(length(readLines("_drake.R")) > 0L)
233+
})
234+
235+
test_with_dir("drake_script() can generate a single symbol", {
236+
drake_script(x)
237+
expect_equal(readLines("_drake.R"), "x")
238+
})
239+
240+
test_with_dir("drake_script() can generate multiple lines", {
241+
drake_script({
242+
x
243+
y
244+
})
245+
expect_equal(readLines("_drake.R"), c("x", "y"))
246+
})

0 commit comments

Comments
 (0)