Skip to content

Commit

Permalink
Feature/renv run command args (#2018)
Browse files Browse the repository at this point in the history
* support command-line arguments in run

* update NEWS
  • Loading branch information
kevinushey authored Nov 13, 2024
1 parent 7ec0ad8 commit 6b94b69
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 9 deletions.
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@

# renv 1.1.0 (UNRELEASED)

* `renv::run()` gains the `args` parameter, which can be used to pass command-line
arguments to a script. (#2015)

* `renv` now infers a dependency on `rmarkdown` and `knitr` for R scripts which
include YAML front-matter. (#2023)

Expand Down
47 changes: 39 additions & 8 deletions R/run.R
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,23 @@
#'
#' @param name The name to associate with the job, for scripts run as a job.
#'
#' @param args description A character vector of command line arguments to be
#' passed to the launched job. These parameters can be accessed via
#' `commandArgs(trailingOnly = FALSE)`.
#'
#' @param project The path to the renv project. This project will be loaded
#' before the requested script is executed. When `NULL` (the default), renv
#' will automatically determine the project root for the associated script
#' if possible.
#'
#' @export
run <- function(script, ..., job = NULL, name = NULL, project = NULL) {

run <- function(script,
...,
job = NULL,
name = NULL,
args = NULL,
project = NULL)
{
renv_scope_error_handler()
renv_dots_check(...)

Expand Down Expand Up @@ -59,18 +68,37 @@ run <- function(script, ..., job = NULL, name = NULL, project = NULL) {
stopf("cannot run script as job: required versions of RStudio + rstudioapi not available")

if (jobbable)
renv_run_job(script = script, name = name, project = project)
renv_run_job(script = script, name = name, args = args, project = project)
else
renv_run_impl(script = script, name = name, project = project)

renv_run_impl(script = script, name = name, args = args, project = project)
}

renv_run_job <- function(script, name, project) {
renv_run_job <- function(script, name, args, project) {

activate <- renv_paths_activate(project = project)
exprs <- expr({

# insert a shim for commandArg
local({

# unlock binding temporarily
base <- .BaseNamespaceEnv
base$unlockBinding("commandArgs", base)
on.exit(base$lockBinding("commandArgs", base), add = TRUE)

# insert our shim
cargs <- commandArgs(trailingOnly = FALSE)
base$commandArgs <- function(trailingOnly = FALSE) {
result <- !!args
if (trailingOnly) result else union(cargs, result)
}

})

# run the script
source(!!activate)
source(!!script)

})

code <- deparse(exprs)
Expand All @@ -85,7 +113,10 @@ renv_run_job <- function(script, name, project) {

}

renv_run_impl <- function(script, name, project) {
renv_run_impl <- function(script, name, args, project) {
renv_scope_wd(project)
system2(R(), c("-s", "-f", renv_shell_path(script)))
system2(R(), c(
"-s", "-f", renv_shell_path(script),
if (length(args)) c("--args", args)
), wait = FALSE)
}
6 changes: 6 additions & 0 deletions R/utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -593,3 +593,9 @@ warnify <- function(cnd) {
not <- function(value) {
if (value) FALSE else TRUE
}

wait <- function(predicate, ...) {
while (TRUE)
if (predicate(...))
break
}
6 changes: 5 additions & 1 deletion man/run.Rd

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

26 changes: 26 additions & 0 deletions tests/testthat/test-run.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

test_that("run() can be called with arguments", {

project <- renv_tests_scope()
dir.create("renv", recursive = TRUE, showWarnings = FALSE)
writeLines("# stub", con = "renv/activate.R")

output <- tempfile("renv-output-")
script <- renv_test_code({
writeLines(commandArgs(trailingOnly = TRUE), con = output)
}, list(output = output))

args <- c("--apple", "--banana", "--cherry")

run(
script = script,
args = args,
project = getwd()
)

wait(file.exists, output)

contents <- readLines(output)
expect_equal(contents, args)

})

0 comments on commit 6b94b69

Please sign in to comment.