From e1142e454a6f140e93c062304c0af8573be24740 Mon Sep 17 00:00:00 2001 From: vincent guyader Date: Sun, 29 Jan 2023 09:51:14 +0100 Subject: [PATCH] draft : Temp (#977) * Pass `require_suggets` to `attachment_create_renv_for_prod` * feat : force check_if_suggests_is_installed = FALSE in renv creation * feat : add test to check suggested package are not in renv.lock * fix : explictly use library(appname) before launching an app un Dockerfile issue : #978 * fix : update add_dockerfile_with_renv * fix : check_installed is more cleaver * fix : add {renv} to dev_deps (its already in {dockerfiler}'s deps, but it seems safer to do this. --------- Co-authored-by: Stephen Holsenbeck --- DESCRIPTION | 2 +- R/add_dockerfiles.R | 6 +-- R/add_dockerfiles_renv.R | 79 ++++++++++++++++++++++---------- R/bootstrap_attachment.R | 6 ++- R/install_dev_deps.R | 3 +- man/dockerfiles.Rd | 18 ++++++-- man/get_golem_options.Rd | 28 +++++------ tests/testthat/helper-config.R | 15 ++++++ tests/testthat/test-renv_stuff.R | 34 +++++++++----- 9 files changed, 131 insertions(+), 60 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 9d73703a..ef1e936a 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -66,4 +66,4 @@ Config/testthat/edition: 3 Encoding: UTF-8 Language: en-US Roxygen: list(markdown = TRUE) -RoxygenNote: 7.2.2 +RoxygenNote: 7.2.3 diff --git a/R/add_dockerfiles.R b/R/add_dockerfiles.R index 4901aef5..6565c7a1 100644 --- a/R/add_dockerfiles.R +++ b/R/add_dockerfiles.R @@ -165,7 +165,7 @@ add_dockerfile_ <- talk_once( dock$CMD( sprintf( - "R -e \"options('shiny.port'=%s,shiny.host='%s');%s::run_app()\"", + "R -e \"options('shiny.port'=%s,shiny.host='%s');library(%3$s);%3$s::run_app()\"", port, host, read.dcf(path)[1] @@ -263,7 +263,7 @@ add_dockerfile_shinyproxy_ <- talk_once( dock$EXPOSE(3838) dock$CMD(sprintf( - " [\"R\", \"-e\", \"options('shiny.port'=3838,shiny.host='0.0.0.0');%s::run_app()\"]", + " [\"R\", \"-e\", \"options('shiny.port'=3838,shiny.host='0.0.0.0');library(%1$s);%1$s::run_app()\"]", read.dcf(path)[1] )) dock$write(output) @@ -357,7 +357,7 @@ add_dockerfile_heroku_ <- talk_once( dock$CMD( sprintf( - "R -e \"options('shiny.port'=$PORT,shiny.host='0.0.0.0');%s::run_app()\"", + "R -e \"options('shiny.port'=$PORT,shiny.host='0.0.0.0');library(%1$s);%1$s::run_app()\"", read.dcf(path)[1] ) ) diff --git a/R/add_dockerfiles_renv.R b/R/add_dockerfiles_renv.R index 5a13be88..9c38a977 100644 --- a/R/add_dockerfiles_renv.R +++ b/R/add_dockerfiles_renv.R @@ -9,24 +9,21 @@ add_dockerfile_with_renv_ <- function( repos = c(CRAN = "https://cran.rstudio.com/"), expand = FALSE, extra_sysreqs = NULL, - update_tar_gz = TRUE + update_tar_gz = TRUE, + document = FALSE, + ... # build_golem_from_source = TRUE, ) { - + if (is.null(lockfile)) { rlang::check_installed( - "attachment", + c("renv","attachment"), reason = "to build a Dockerfile with automatic renv.lock creation. Use the `lockfile` parameter to pass your own `renv.lock` file." ) - + } - - - - rlang::check_installed( - "renv", - reason = "to build a Dockerfile." - ) + + # Small hack to prevent warning from rlang::lang() in tests # This should be managed in {attempt} later on x <- suppressWarnings({ @@ -41,10 +38,28 @@ add_dockerfile_with_renv_ <- function( } if (is.null(lockfile)) { - + + + if ( isTRUE(document) ){ + + cli_cat_line("You set `document = TRUE` and you did not pass your own renv.lock file,") + cli_cat_line("as a consequence {golem} will use `attachment::att_amend_desc()` to update your ") + cli_cat_line("DESCRIPTION file before creating the renv.lock file") + cli_cat_line("") + cli_cat_line("you can set `document = FALSE` to use your actual DESCRIPTION file,") + cli_cat_line("or pass you own renv.lock to use, using the `lockfile` parameter") + cli_cat_line("") + cli_cat_line("In any case be sure to have no Error or Warning at `devtools::check()`") + } + + + + lockfile <- attachment_create_renv_for_prod( path = source_folder, - output = file.path(output_dir, "renv.lock.prod") + check_if_suggests_is_installed = FALSE, document = document, + output = file.path(output_dir, "renv.lock.prod"), + ... ) } @@ -132,8 +147,10 @@ add_dockerfile_with_renv_ <- function( #' @param output_dir folder to export everything deployment related. #' @param distro One of "focal", "bionic", "xenial", "centos7", or "centos8". #' See available distributions at https://hub.docker.com/r/rstudio/r-base/. +#' @param document boolean. If TRUE (by default), DESCRIPTION file is updated using [attachment::att_amend_desc()] before creating the renv.lock file #' @param dockerfile_cmd What is the CMD to add to the Dockerfile. If NULL, the default, -#' the CMD will be `R -e "options('shiny.port'={port},shiny.host='{host}');{appname}::run_app()\` +#' the CMD will be `R -e "options('shiny.port'={port},shiny.host='{host}');library({appname});{appname}::run_app()\` +#' @param ... Other arguments to pass to [renv::snapshot()] #' @inheritParams add_dockerfile #' @rdname dockerfiles #' @export @@ -150,9 +167,11 @@ add_dockerfile_with_renv <- function( repos = c(CRAN = "https://cran.rstudio.com/"), expand = FALSE, open = TRUE, + document = TRUE, extra_sysreqs = NULL, update_tar_gz = TRUE, - dockerfile_cmd = NULL + dockerfile_cmd = NULL, + ... ) { base_dock <- add_dockerfile_with_renv_( source_folder = source_folder, @@ -165,14 +184,16 @@ add_dockerfile_with_renv <- function( repos = repos, expand = expand, extra_sysreqs = extra_sysreqs, - update_tar_gz = update_tar_gz + update_tar_gz = update_tar_gz, + document = document, + ... ) if (!is.null(port)) { base_dock$EXPOSE(port) } if (is.null(dockerfile_cmd)) { dockerfile_cmd <- sprintf( - "R -e \"options('shiny.port'=%s,shiny.host='%s');%s::run_app()\"", + "R -e \"options('shiny.port'=%s,shiny.host='%s');library(%3$s);%3$s::run_app()\"", port, host, golem::get_golem_name() @@ -205,7 +226,7 @@ docker run -p %s:%s %s ) } -#' @inheritParams add_dockerfile +#' @inheritParams add_dockerfile_with_renv #' @rdname dockerfiles #' @export #' @export @@ -221,7 +242,9 @@ add_dockerfile_with_renv_shinyproxy <- function( expand = FALSE, extra_sysreqs = NULL, open = TRUE, - update_tar_gz = TRUE + document = TRUE, + update_tar_gz = TRUE, + ... ) { add_dockerfile_with_renv( source_folder = source_folder, @@ -238,14 +261,16 @@ add_dockerfile_with_renv_shinyproxy <- function( extra_sysreqs = extra_sysreqs, update_tar_gz = update_tar_gz, open = open, + document = document, dockerfile_cmd = sprintf( - "R -e \"options('shiny.port'=3838,shiny.host='0.0.0.0');%s::run_app()\"", + "R -e \"options('shiny.port'=3838,shiny.host='0.0.0.0');library(%1$s);%1$s::run_app()\"", golem::get_golem_name() - ) + ), + ... ) } -#' @inheritParams add_dockerfile +#' @inheritParams add_dockerfile_with_renv #' @rdname dockerfiles #' @export #' @export @@ -261,7 +286,9 @@ add_dockerfile_with_renv_heroku <- function( expand = FALSE, extra_sysreqs = NULL, open = TRUE, - update_tar_gz = TRUE + document = TRUE, + update_tar_gz = TRUE, + ... ) { add_dockerfile_with_renv( source_folder = source_folder, @@ -278,10 +305,12 @@ add_dockerfile_with_renv_heroku <- function( extra_sysreqs = extra_sysreqs, update_tar_gz = update_tar_gz, open = FALSE, + document = document, dockerfile_cmd = sprintf( - "R -e \"options('shiny.port'=$PORT,shiny.host='0.0.0.0');%s::run_app()\"", + "R -e \"options('shiny.port'=$PORT,shiny.host='0.0.0.0');library(%1$s);%1$s::run_app()\"", golem::get_golem_name() - ) + ), + ... ) apps_h <- gsub( diff --git a/R/bootstrap_attachment.R b/R/bootstrap_attachment.R index 887b6939..0f0e831d 100644 --- a/R/bootstrap_attachment.R +++ b/R/bootstrap_attachment.R @@ -3,7 +3,7 @@ check_attachment_installed <- function() { rlang::check_installed( "attachment", - version = "0.2.5", + version = "0.3.1", reason = "to build a Dockerfile." ) } @@ -12,12 +12,16 @@ attachment_create_renv_for_prod <- function( path = ".", output = "renv.lock.prod", dev_pkg = "remotes", + check_if_suggests_is_installed = FALSE, + document = FALSE, ... ) { attachment::create_renv_for_prod( path = path, output = output, dev_pkg = dev_pkg, + document = document, + check_if_suggests_is_installed = check_if_suggests_is_installed, ... ) } diff --git a/R/install_dev_deps.R b/R/install_dev_deps.R index d86dc2e8..cffab779 100644 --- a/R/install_dev_deps.R +++ b/R/install_dev_deps.R @@ -82,6 +82,7 @@ dev_deps <- unique( "pkgload", "processx", "roxygen2", + "renv", "rsconnect", "rstudioapi", "testthat", @@ -97,7 +98,7 @@ check_dev_deps_are_installed <- function() { if (!all(are_installed)) { message( "We noticed that some dev dependencies are not installed.\n", - "You can install them with `install_dev_deps()`." + "You can install them with `golem::install_dev_deps()`." ) } } diff --git a/man/dockerfiles.Rd b/man/dockerfiles.Rd index 6a54e1a0..04536333 100644 --- a/man/dockerfiles.Rd +++ b/man/dockerfiles.Rd @@ -69,9 +69,11 @@ add_dockerfile_with_renv( repos = c(CRAN = "https://cran.rstudio.com/"), expand = FALSE, open = TRUE, + document = TRUE, extra_sysreqs = NULL, update_tar_gz = TRUE, - dockerfile_cmd = NULL + dockerfile_cmd = NULL, + ... ) add_dockerfile_with_renv_shinyproxy( @@ -86,7 +88,9 @@ add_dockerfile_with_renv_shinyproxy( expand = FALSE, extra_sysreqs = NULL, open = TRUE, - update_tar_gz = TRUE + document = TRUE, + update_tar_gz = TRUE, + ... ) add_dockerfile_with_renv_heroku( @@ -101,7 +105,9 @@ add_dockerfile_with_renv_heroku( expand = FALSE, extra_sysreqs = NULL, open = TRUE, - update_tar_gz = TRUE + document = TRUE, + update_tar_gz = TRUE, + ... ) } \arguments{ @@ -154,8 +160,12 @@ default is current folder '.'} \item{distro}{One of "focal", "bionic", "xenial", "centos7", or "centos8". See available distributions at https://hub.docker.com/r/rstudio/r-base/.} +\item{document}{boolean. If TRUE (by default), DESCRIPTION file is updated using \code{\link[attachment:att_amend_desc]{attachment::att_amend_desc()}} before creating the renv.lock file} + \item{dockerfile_cmd}{What is the CMD to add to the Dockerfile. If NULL, the default, -the CMD will be \verb{R -e "options('shiny.port'=\{port\},shiny.host='\{host\}');\{appname\}::run_app()\\}} +the CMD will be \verb{R -e "options('shiny.port'=\{port\},shiny.host='\{host\}');library(\{appname\});\{appname\}::run_app()\\}} + +\item{...}{Other arguments to pass to \code{\link[renv:snapshot]{renv::snapshot()}}} } \value{ The \code{{dockerfiler}} object, invisibly. diff --git a/man/get_golem_options.Rd b/man/get_golem_options.Rd index 0eadfabc..6f8a2a6c 100644 --- a/man/get_golem_options.Rd +++ b/man/get_golem_options.Rd @@ -23,10 +23,12 @@ parameters passed to \code{run_app()}. if (interactive()) { # 1. Pass parameters directly to `run_app` - run_app( title="My Golem App", - content = "something" ) + run_app( + title = "My Golem App", + content = "something" + ) - # 2. Get the values + # 2. Get the values # 2.1 from the UI side h1(get_golem_options("title")) @@ -36,17 +38,17 @@ if (interactive()) { output$param <- renderPrint({ paste("param content = ", get_golem_options("content")) }) - + output$param_full <- renderPrint({ - get_golem_options() # list of all golem options as a list. + get_golem_options() # list of all golem options as a list. }) - + # 3. If needed, to set default value, edit `run_app` like this : run_app <- function( - title = "this", - content = "that", - ... + title = "this", + content = "that", + ... ) { with_golem_options( app = shinyApp( @@ -54,14 +56,12 @@ if (interactive()) { server = app_server ), golem_opts = list( - title = title, - content = content, - ... + title = title, + content = content, + ... ) ) } - - } } diff --git a/tests/testthat/helper-config.R b/tests/testthat/helper-config.R index 5105773b..81554197 100644 --- a/tests/testthat/helper-config.R +++ b/tests/testthat/helper-config.R @@ -93,3 +93,18 @@ withr::with_dir(pkg, { ) usethis::use_mit_license("Golem") }) + + +create_deploy_folder <- function(){ +file.path( + tempdir(), + make.names( + paste0( + "deploy", + round( + runif(1, min = 0, max = 99999) + ) + ) + ) + ) +} diff --git a/tests/testthat/test-renv_stuff.R b/tests/testthat/test-renv_stuff.R index f63449e4..07853af1 100644 --- a/tests/testthat/test-renv_stuff.R +++ b/tests/testthat/test-renv_stuff.R @@ -8,17 +8,7 @@ test_that("add_dockerfiles_renv and add_dockerfile_with_renv_shinyproxy all outp add_dockerfile_with_renv_shinyproxy, add_dockerfile_with_renv_heroku )) { - deploy_folder <- file.path( - tempdir(), - make.names( - paste0( - "deploy", - round( - runif(1, min = 0, max = 99999) - ) - ) - ) - ) + deploy_folder <- create_deploy_folder() fun(output_dir = deploy_folder, open = FALSE) @@ -32,3 +22,25 @@ test_that("add_dockerfiles_renv and add_dockerfile_with_renv_shinyproxy all outp } }) }) +test_that("suggested package ore not in renv prod", { + skip_if_not_installed("renv") + skip_if_not_installed("dockerfiler", "0.2.0") + skip_if_not_installed("attachment", "0.3.1") + with_dir(pkg, { + desc_file <- file.path("DESCRIPTION") + desc_lines <- readLines(desc_file) + # desc_lines <- c(desc_lines,"Suggests: \n idontexist") + desc_lines[desc_lines == "Suggests: "] <- "Suggests: \n idontexist," + writeLines(desc_lines,desc_file) + deploy_folder <- create_deploy_folder() + + add_dockerfile_with_renv(output_dir = deploy_folder, open = FALSE) + + base <- paste(readLines(file.path(deploy_folder,"renv.lock.prod")),collapse = " ") + expect_false(grepl(pattern = "idontexist",x = base)) + expect_true(grepl(pattern = "shiny",x = base)) + + unlink(deploy_folder, force = TRUE, recursive = TRUE) + } + ) +})