Skip to content

Commit

Permalink
Implement envManagement args for ::writeManifest()
Browse files Browse the repository at this point in the history
  • Loading branch information
dbkegley committed Aug 24, 2023
1 parent 2eda945 commit 1ec3d3a
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 7 deletions.
9 changes: 9 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@

* Ignore `.env`, `.venv`, and `venv` files only when they reference Python
virtual environments. (#972)

* Add `envManagement`, `envManagementR` and `envManagementPy` args when writing
the `manifest.json`. These args whether Connect should install packages in the
package cache. If `envManagement` is `FALSE` then Connect will not perform any
package installation and it is the administrators responsibility to ensure the
required R/Python packages are available in the runtime environment.
This is especially useful if off-host execution is enabled, when the execution
environment (specified by `--image`) already contains the required packages.
Requires Posit Connect `>=2023.07.0`. (#977)

# rsconnect 1.0.2

Expand Down
36 changes: 33 additions & 3 deletions R/bundle.R
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ createAppManifest <- function(appDir,
pythonConfig = NULL,
retainPackratDirectory = TRUE,
image = NULL,
envManagement = NULL,
envManagementR = NULL,
envManagementPy = NULL,
verbose = FALSE,
quiet = FALSE) {

Expand Down Expand Up @@ -191,9 +194,36 @@ createAppManifest <- function(appDir,
# add metadata
manifest$metadata <- metadata

# if there is a target image, attach it to the environment
if (!is.null(image)) {
manifest$environment <- list(image = image)
# handle shorthand arg to enable/disable both R and Python
if (!is.null(envManagement)) {
envManagementR <- envManagement
envManagementPy <- envManagement
}

# if envManagement is explicitly enabled/disabled,
# create an environment_management obj
envManagementInfo <- list()
if (!is.null(envManagementR)) {
envManagementInfo$r <- envManagementR
}
if (!is.null(envManagementPy)) {
envManagementInfo$python <- envManagementPy
}

# emit the environment field
if (!is.null(image) || length(envManagementInfo) > 0) {
manifest$environment <- list()

# if there is a target image, attach it to the environment
if (!is.null(image)) {
manifest$environment$image <- image
}

# if either environment_management.r or environment_management.python
# is provided, write the environment_management field
if (length(envManagementInfo) > 0) {
manifest$environment$environment_management <- envManagementInfo
}
}

# indicate whether this is a quarto app/doc
Expand Down
36 changes: 33 additions & 3 deletions R/deployApp.R
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,24 @@
#' @param image Optional. The name of the image to use when building and
#' executing this content. If none is provided, Posit Connect will
#' attempt to choose an image based on the content requirements.
#' @param envManagement Optional. Should Connect install R and Python packages
#' for this content? (`TRUE`, `FALSE`, or `NULL`). The default, `NULL`, will
#' not write any values to the bundle manifest, and Connect will fall back to
#' the application default environment management strategy, or the server
#' default if no application default is defined.
#'
#' (This option is a shorthand flag which overwrites the values of both
#' `envManagementR` and `envManagementPy`.)
#' @param envManagementR Optional. Should Connect install R packages
#' for this content? (`TRUE`, `FALSE`, or `NULL`). The default, `NULL`, will
#' not write any values to the bundle manifest, and Connect will fall back to
#' the application default R environment management strategy, or the server
#' default if no application default is defined.
#' @param envManagementPy Optional. Should Connect install Python packages
#' for this content? (`TRUE`, `FALSE`, or `NULL`). The default, `NULL`, will
#' not write any values to the bundle manifest, and Connect will fall back to
#' the application default Python environment management strategy, or the server
#' default if no application default is defined.
#' @examples
#' \dontrun{
#'
Expand Down Expand Up @@ -197,7 +215,10 @@ deployApp <- function(appDir = getwd(),
forceGeneratePythonEnvironment = FALSE,
quarto = NA,
appVisibility = NULL,
image = NULL
image = NULL,
envManagement = NULL,
envManagementR = NULL,
envManagementPy = NULL
) {

check_string(appDir)
Expand Down Expand Up @@ -424,7 +445,10 @@ deployApp <- function(appDir = getwd(),
quiet = quiet,
verbose = verbose,
pythonConfig = pythonConfig,
image = image
image = image,
envManagement = envManagement,
envManagementR = envManagementR,
envManagementPy = envManagementPy
)
size <- format(file_size(bundlePath), big.mark = ",")
taskComplete(quiet, "Created {size}b bundle")
Expand Down Expand Up @@ -589,7 +613,10 @@ bundleApp <- function(appName,
verbose = FALSE,
quiet = FALSE,
pythonConfig = NULL,
image = NULL) {
image = NULL,
envManagement = NULL,
envManagementR = NULL,
envManagementPy = NULL) {
logger <- verboseLogger(verbose)

# get application users (for non-document deployments)
Expand All @@ -615,6 +642,9 @@ bundleApp <- function(appName,
pythonConfig = pythonConfig,
retainPackratDirectory = TRUE,
image = image,
envManagement = envManagement,
envManagementR = envManagementR,
envManagementPy = envManagementPy,
verbose = verbose,
quiet = quiet
)
Expand Down
6 changes: 6 additions & 0 deletions R/writeManifest.R
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ writeManifest <- function(appDir = getwd(),
forceGeneratePythonEnvironment = FALSE,
quarto = NA,
image = NULL,
envManagement = NULL,
envManagementR = NULL,
envManagementPy = NULL,
verbose = FALSE,
quiet = FALSE) {
appFiles <- listDeploymentFiles(
Expand Down Expand Up @@ -61,6 +64,9 @@ writeManifest <- function(appDir = getwd(),
pythonConfig = pythonConfig,
retainPackratDirectory = FALSE,
image = image,
envManagement = envManagement,
envManagementR = envManagementR,
envManagementPy = envManagementPy,
verbose = verbose,
quiet = quiet
)
Expand Down
26 changes: 25 additions & 1 deletion man/deployApp.Rd

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

24 changes: 24 additions & 0 deletions man/writeManifest.Rd

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

23 changes: 23 additions & 0 deletions tests/testthat/test-writeManifest.R
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,29 @@ test_that("Sets environment.image in the manifest if one is provided", {
expect_null(manifest$environment)
})

test_that("Sets environment.environment_management in the manifest if envManagement is defined", {
withr::local_options(renv.verbose = TRUE)

appDir <- test_path("shinyapp-simple")

# test shorthand arg
manifest <- makeManifest(appDir, envManagement = FALSE, envManagementR = TRUE, envManagementPy = TRUE)
expect_equal(manifest$environment$environment_management$r, FALSE)
expect_equal(manifest$environment$environment_management$python, FALSE)

# test R and Python args
manifest <- makeManifest(appDir, envManagementR = TRUE)
expect_equal(manifest$environment$environment_management$r, TRUE)
expect_null(manifest$environment$environment_management$python)
manifest <- makeManifest(appDir, envManagementPy = TRUE)
expect_equal(manifest$environment$environment_management$python, TRUE)
expect_null(manifest$environment$environment_management$r)

# environment_management is not defined when envManagementR and envManagementPy are NULL
manifest <- makeManifest(appDir, image = "rstudio/content-base:latest")
expect_null(manifest$environment$environment_management)
})

# appMode Inference tests

test_that("content type (appMode) is inferred and can be overridden", {
Expand Down

0 comments on commit 1ec3d3a

Please sign in to comment.