Skip to content

Commit

Permalink
Fix #1282
Browse files Browse the repository at this point in the history
  • Loading branch information
wlandau-lilly committed Jun 23, 2020
1 parent 55244e8 commit beba7b0
Show file tree
Hide file tree
Showing 10 changed files with 143 additions and 1 deletion.
1 change: 1 addition & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
^build_site.R$
^pkgdown$
^\.DS_Store
^_drake\.R$
^\.drake$
^\.drake_history$
^\.future$
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Thumbs.db
*.synctex.gz
*.toc
*.vrb
_drake.R
.drake
.drake_history
.DS_Store
Expand Down
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ export(drake_plan_source)
export(drake_progress)
export(drake_quotes)
export(drake_running)
export(drake_script)
export(drake_session)
export(drake_slice)
export(drake_strings)
Expand Down
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
* Strongly depend on `tidyselect` (#1274, @dernst).
* Avoid `txtq` lockfiles (#1232, #1239, #1280, @danwwilson, @pydupont, @mattwarkentin).

## New features

* Add a new `drake_script()` function to write `_drake.R` files for `r_make()` (#1282).

# Version 7.12.2

## Bug fixes
Expand Down
45 changes: 45 additions & 0 deletions R/drake_script.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#' @title Write an example `_drake.R` script to the current working directory.
#' @export
#' @description A `_drake.R` file is required for [r_make()] and friends.
#' See the [r_make()] help file for details.
#' @return Nothing.
#' @param code R code to put in `_drake.R` in the current working directory.
#' If `NULL`, an example script is written.
#' @examples
#' \dontrun{
#' isolate_example("contain side-effects", {
#' drake_script({
#' library(drake)
#' plan <- drake_plan(x = 1)
#' drake_config(plan, lock_cache = FALSE)
#' })
#' cat(readLines("_drake.R"), sep = "\n")
#' r_make()
#' })
#' }
drake_script <- function(code = NULL) {
code <- substitute(code)
if (length(code)) {
text <- parse_drake_script_code(code)
} else {
text <- example_drake_script()
}
writeLines(text, "_drake.R")
}

example_drake_script <- function() {
path <- system.file(
file.path("templates", "drake_script", "example_drake.R"),
package = "drake",
mustWork = TRUE
)
readLines(path)
}

parse_drake_script_code <- function(code) {
if (length(code) > 1L && safe_deparse(code[[1]]) == "`{`") {
vcapply(code[-1], safe_deparse)
} else {
safe_deparse(code)
}
}
1 change: 1 addition & 0 deletions _pkgdown.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ reference:
- '`read_trace`'
- title: Reproducible R session management
contents:
- '`drake_script`'
- '`r_make`'
- '`r_drake_build`'
- '`r_outdated`'
Expand Down
39 changes: 39 additions & 0 deletions inst/templates/drake_script/example_drake.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# This file serves the r_*() functions (e.g. r_make()) documented at
# https://books.ropensci.org/drake/projects.html#safer-interactivity # nolint
# and
# https://docs.ropensci.org/drake/reference/r_make.html

# Load all your packages before calling make().
library(drake)
library(tibble)

# Custom functions are an important part of a drake workflow.
# This is where you write them.
# Details: https://books.ropensci.org/drake/plans.html#functions

generate_data <- function() {
tibble(x = rnorm(1e5), y = rnorm(1e5))
}

fit_model <- function(data) {
summary(lm(y ~ x, data = data))
}

# This is where you write your drake plan.
# Details: https://books.ropensci.org/drake/plans.html

plan <- drake_plan(
data = generate_data(),
model = fit_model(data)
)

# You could have put all the above into separate script files and
# source()'d them as below:

# source("R/packages.R") # Load your packages, e.g. library(drake). # nolint
# source("R/functions.R") # Define your custom code as a bunch of functions. # nolint
# source("R/plan.R") # Create your drake plan. # nolint

# _drake.R must end with a call to drake_config().
# The arguments to drake_config() are basically the same as those to make().
drake_config(plan)
32 changes: 32 additions & 0 deletions man/drake_script.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/make.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions tests/testthat/test-zzz-callr.R
Original file line number Diff line number Diff line change
Expand Up @@ -226,3 +226,21 @@ test_with_dir("errors keep their informative messages (#969)", {
class = "callr_error"
)
})

test_with_dir("drake_script() can generate an example script", {
drake_script()
expect_true(length(readLines("_drake.R")) > 0L)
})

test_with_dir("drake_script() can generate a single symbol", {
drake_script(x)
expect_equal(readLines("_drake.R"), "x")
})

test_with_dir("drake_script() can generate multiple lines", {
drake_script({
x
y
})
expect_equal(readLines("_drake.R"), c("x", "y"))
})

0 comments on commit beba7b0

Please sign in to comment.