Skip to content

Commit

Permalink
Fix #1359: shinyApp options argument ignored when passed to runApp
Browse files Browse the repository at this point in the history
  • Loading branch information
bborgesr committed Dec 5, 2016
1 parent 2e1c371 commit ee01d45
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 12 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Expand Up @@ -15,6 +15,7 @@ shiny 0.14.2.9000

* Fixed bug causing `<meta>` tags associated with HTML dependencies of Shiny R Markdown files to be rendered incorrectly. ([#1463](https://github.com/rstudio/shiny/pull/1463))

* Fix [#1359](https://github.com/rstudio/shiny/issue/1359): `shinyApp()` options argument ignored when passed to `runApp()`. ([#1483](https://github.com/rstudio/shiny/pull/1483))

shiny 0.14.2
============
Expand Down
11 changes: 7 additions & 4 deletions R/app.R
Expand Up @@ -20,9 +20,11 @@
#' @param onStart A function that will be called before the app is actually run.
#' This is only needed for \code{shinyAppObj}, since in the \code{shinyAppDir}
#' case, a \code{global.R} file can be used for this purpose.
#' @param options Named options that should be passed to the `runApp` call. You
#' can also specify \code{width} and \code{height} parameters which provide a
#' hint to the embedding environment about the ideal height/width for the app.
#' @param options Named options that should be passed to the \code{runApp} call
#' (these can be any of the following: "port", "launch.browser", "host", "quiet",
#' "display.mode" and "test.mode"). You can also specify \code{width} and
#' \code{height} parameters which provide a hint to the embedding environment
#' about the ideal height/width for the app.
#' @param uiPattern A regular expression that will be applied to each \code{GET}
#' request to determine whether the \code{ui} should be used to handle the
#' request. Note that the entire request path must match the regular
Expand Down Expand Up @@ -373,7 +375,8 @@ is.shiny.appobj <- function(x) {
print.shiny.appobj <- function(x, ...) {
opts <- x$options %OR% list()
opts <- opts[names(opts) %in%
c("port", "launch.browser", "host", "quiet", "display.mode")]
c("port", "launch.browser", "host", "quiet",
"display.mode", "test.mode")]

args <- c(list(x), opts)

Expand Down
54 changes: 49 additions & 5 deletions R/server.R
Expand Up @@ -561,14 +561,60 @@ runApp <- function(appDir=getwd(),
.globals$options <- oldOptionSet
},add = TRUE)

if (is.null(host) || is.na(host))
host <- '0.0.0.0'

# Make warnings print immediately
# Set pool.scheduler to support pool package
ops <- options(warn = 1, pool.scheduler = scheduleTask)
on.exit(options(ops), add = TRUE)

appParts <- as.shiny.appobj(appDir)

# The lines below set some of the app's running options, which
# can be:
# - left unspeficied (in which case the arguments' default
# values from `runApp` kick in);
# - passed through `shinyApp`
# - passed through `runApp` (this function)
# - passed through both `shinyApp` and `runApp` (the latter
# takes precedence)
#
# Matrix of possibilities:
# | IN shinyApp | IN runApp | result | check |
# |-------------|-----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------|
# | no | no | use defaults | exhaust all possibilities: if it's missing (runApp does not specify); THEN if it's not in shinyApp appParts$options; THEN use defaults |
# | yes | no | use shinyApp | if it's missing (runApp does not specify); THEN if it's in shinyApp appParts$options; THEN use shinyApp |
# | no | yes | use runApp | if it's not missing (runApp specifies), use those |
# | yes | yes | use runApp | if it's not missing (runApp specifies), use those |
#
# I tried to make this as compact and intuitive as possible,
# given that there are four distinct possibilities to check
runOpts <- appParts$options
passedArgs <- as.list(match.call())[-1]
thisEnv <- environment()

# Figure out which value to use for an option
priorityAssign <- function(arg) {
# if it was passed directly to `runApp`, use that value
if (arg %in% names(passedArgs)) val <- passedArgs[[arg]]

# else if it was passed directly to `shinyApp`, use that value
else if (arg %in% names(runOpts)) val <- runOpts[[arg]]

# else, just use the default value specified in `runApp`
else val <- thisEnv[[arg]]

# make sure that Ts and Fs are kept as logicals
if (is.name(val) && val == "T") val <- TRUE
if (is.name(val) && val == "F") val <- FALSE

assign(arg, val, envir = thisEnv)
}

lapply(list("port", "launch.browser", "host",
"quiet", "display.mode", "test.mode"),
priorityAssign)

if (is.null(host) || is.na(host)) host <- '0.0.0.0'

workerId(workerId)

if (inShinyServer()) {
Expand Down Expand Up @@ -680,8 +726,6 @@ runApp <- function(appDir=getwd(),
}
}

appParts <- as.shiny.appobj(appDir)

# Extract appOptions (which is a list) and store them as shinyOptions, for
# this app. (This is the only place we have to store settings that are
# accessible both the UI and server portion of the app.)
Expand Down
8 changes: 5 additions & 3 deletions man/shinyApp.Rd

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

0 comments on commit ee01d45

Please sign in to comment.