An Installation Framework for Shiny Apps

Installs shiny apps using Inno Setup, an open source software that builds installers for Windows programs < http://www.jrsoftware.org/ishelp/>.


AppVeyor Build Status codecov CRAN_Status_Badge Downloads Downloads Project Status: Active - The project has reached a stable, usable state and is being actively developed.

RInno makes it easy to install local shiny apps by providing an interface between R and Inno Setup, an installer for Windows programs (sorry Mac and Linux users). It is designed to be simple to use (two lines of code at a minimum), yet comprehensive.

If a user does not have R installed, the RInno installer can be configured to ask them to install R along with a shiny app, include_R = TRUE. And similar to Dr. Lee Pang's DesktopDeployR project, RInno provides a framework for managing software dependencies and error logging features. However, RInno also supports GitHub package dependencies, continuous installation (auto-update on start up), and it is easier to manage with create_app, the main RInno function. DesktopDeployR requires many manual adjustments and a deep understanding of the entire framework to use, but RInno can be learned incrementally and changes automatically flow down stream. You don't need to remember the 100+ places impacted by changing app_dir. RInno only requires a high-level understanding of what you'd like to accomplish.

Getting Started

install.packages("devtools"); require(devtools)

# Use install_github to get RInno
devtools::install_github("ficonsulting/RInno",  build_vignettes = TRUE)

# Require Package
require(RInno)

# Use RInno to get Inno Setup
RInno::install_inno()

Minimal example

Once you have developed a shiny app, you can build an installer with create_app followed by compile_iss.

# Example app included with RInno package
example_app(wd = getwd())

# Build an installer
create_app(app_name = "Your appname", app_dir = "app")
compile_iss()

create_app creates an installation framework in your app's directory, app_dir. You can perform minor customizations before you call compile_iss. For example, you can replace the default/setup icon at Flaticon.com, or you can customize the pre-/post- install messages, infobefore.txt and infoafter.txt. Just remember, the default values (i.e. create_app(info_after = "infobefore.txt")) for those files have not changed. The Inno Setup Script (ISS), app_name.iss, will look for default.ico and try to use it until you update the script or call create_app with the new icon's file name (i.e. create_app(app_icon = "new.ico")).

Chrome is the default browser used by RInno because of its app mode feature and development-minded focus. IE/Edge often prevents icons and third party JavaScript libraries from loading because of various IT policies, which can result in strange bugs in your app. The default user_browser setting will open Chrome in app mode, which looks more like a stand-alone app than when it opens in another tab of your default browser. Regardless of which browser you specify, RInno's startup sequence will fall back on the user's default browser if it is not installed.

ui.R Requirements

In order to replace Chrome's logo with your app's icon, add something like this to your ui.R file:

fluidPage(
  tags$head(
    tags$link(
      rel = "icon", 
      type = "image/x-icon", 
      href = "http://localhost:1984/default.ico")
  )
)

server.R Requirements

In order to close the app when your user's session completes:

  1. Add session to your server function

  2. Call stopApp() when the session ends

    function(input, output, session) {

    session$onSessionEnded(function() { stopApp() q("no") }) }

If you forget to do this, users will complain that their icons are broken and rightly blame you for it (an R session will be running in the background hosting the app, but they will need to press ctrl + alt + delete and use their task manager to close it). Not cool.

Package Dependency Management

Provide a named character vector of packages to create_app, and RInno will install them with your shiny app. If the vector does not have a version #, the default is utils::packageVersion. Whereas if a specific package version is specified, i.e. pkgs = c(shiny = "==1.0.5", "jsonlite", "httr"), RInno will respect that specification and use utils::packageVersion for the rest.

create_app(
  app_name = "myapp", 
  app_dir = "app",
  pkgs = c("shiny", "jsonlite", "httr")
)

RInno will default to shiny = paste0(">=", utils::packageVersion("shiny")), etc. because versions are not included. This provides a similar management strategy as developers use in the DESCRIPTION file's Imports: section of an R package. For more information, please see R Packages - Package Metadata by Hadley Wickham.

Custom Installations

If you would like to create a custom installer from within R, you can slowly build up to it with create_app, like this:

create_app(
  app_name    = "My AppName", 
  app_dir     = "My/app/path",
  dir_out     = "wizard",
  pkgs        = c("jsonlite", "shiny", "magrittr", "xkcd"),  # CRAN-like repo packages
  remotes     = c("talgalili/installr", "daattali/shinyjs"), # GitHub packages
  include_R   = TRUE,     # Download R and install it with your app, if necessary
  R_version   = "2.2.1",  # Old versions of R
  privilege   = "high",   # Admin only installation
  default_dir = "pf")     # Install app in to Program Files

create_app passes its arguments to most of the other support functions in RInno, so you can specify most things there and they will get passed on, or you can provide detailed instructions directly to those functions like this:

# Copy installation scripts (JavaScript, icons, infobefore.txt, package_manager.R, app.R)
copy_installation(app_dir = "my/app/path")

# If your users need R installed:
get_R(app_dir = "my/app/path", R_version = "2.2.1")

# Create batch file
create_bat(app_name = "My AppName", app_dir = "my/app/path")

# Create app config file
create_config(app_name = "My AppName", R_version = "2.2.1", app_dir = "my/app/path",
  pkgs = c("jsonlite", "shiny", "magrittr", "dplyr", "caret", "xkcd"))

# Build the iss script
start_iss(app_name = "My AppName") %>%

  # C-like directives
  directives_section(R_version   = "2.2.1", 
             include_R   = TRUE,
             app_version = "0.1.2",
             publisher   = "Your Company", 
             main_url    = "yourcompany.com") %>%

  # Setup Section
  setup_section(output_dir  = "wizard", 
        app_version = "0.1.2",
        default_dir = "pf", 
        privilege   = "high",
        inst_readme = "pre-install instructions.txt", 
        setup_icon  = "myicon.ico",
        pub_url     = "mycompany.com", 
        sup_url     = "mycompany.github.com/issues",
        upd_url     = "mycompany.github.com") %>%

  # Languages Section
  languages_section() %>%

  # Tasks Section
  tasks_section(desktop_icon = FALSE) %>%

  # Files Section
  files_section(app_dir = "my/app/path", file_list = "path/to/extra/files") %>%

  # Icons Section
  icons_section(app_desc       = "This is my local shiny app",
        app_icon       = "notdefault.ico",
        prog_menu_icon = FALSE,
        desktop_icon   = FALSE) %>%

  # Execution & Pascal code to check registry during installation
  # If the user has R, don't give them an extra copy
  # If the user needs R, give it to them
  run_section() %>%
  code_section() %>%

  # Write the Inno Setup script
  writeLines(file.path("my/app/path", "My AppName.iss"))

  # Check your files, then
  compile_iss()

Feel free to read the Inno Setup documentation and RInno's documentation to get a sense for what is possible. Also, please suggest useful features or build them yourself! We have a very positive culture at FI Consulting, and we would love to get your feedback.

Please note that this project has a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.

License

The RInno package is licensed under the GPLv3. See LICENSE for details.

News

0.2.0

  • @zhengle-advantaseeds and @trybik continue to move the project forward with great ideas and bug fixes.
  • @willbradley created a pull request which adds support for package version control and local package installations #34. Conditional statements like shiny = ">= 1.0.5" and/or local .tar.gz of R packages are now supported. These can reduce software dependency bugs caused by updates to CRAN.
  • Added support for more flexible R-version checks - #24.
  • For users who use support functions (i.e. setup, files, code etc.), this version includes breaking changes. All of those functions have been appended with _section in order to avoid namespace conflicts with devtools::setup and shiny::code among others.

0.1.2

  • Swapped out many sprintf calls with RStudio's new glue function for interpolating strings. This should make RInno more flexible and easier to maintain and debug moving forward.
  • Added support for app mode when user_browser = "chrome". RInno also automatically places app_icon in a "www/" directory and utilizes port 1984. This makes it easy to display the app's icon instead of Chrome's (see README for details). Big shout out to @trybik for this great suggestion.
  • Created an option to include an installation of Chrome with the app's installer w/ include_Chrome = TRUE.
  • Improved handling of internet connection status. If the app has never started before, it will stop and tell users to check their internet connection and try again. Otherwise, the app will start normally, but the app's log will have information about the fact that it pinged www.google.com and did not get a response. Thank you @zhengle-advantaseeds for reporting this issue! #22
  • Exposed R installation flags w/ the R_flags argument. For more information, read ?run. Thanks @renejuan for requesting this feature!

0.1.1

  • Patched the way that RInno handles icons and text files. The defaults no longer cause Inno Setup compilation errors when custom icons or messaging is provided. Thanks @sollano for uncovering this bug!
  • Fixed the private repo process for continuous installations from Github. Added a new argument auth_token, which uses a Github token to authenticate with private repos. @sollano again provided amazingly detailed information that helped us resolve this issue. #19

0.1.0

  • Major improvements to registry checks and app start up sequence
    • RInno installers now query the registry during installation so that local Shiny apps can use registry information during their startup sequence. The registry is queried for R, Pandoc, Chrome, Firefox, and Internet Explorer. If you would like any other software added to the regpaths.json output, give us a holler!
    • This should make Shiny apps installed with RInno reliable for large numbers of users because strange installation bugs are often caused by unique desktop setups. 0.1.0 should reduce the maintenance cost of local installations and make them scalable for medium-sized organizations and teams.
  • Hanjo Odendall (@HanjoStudy) added support for flexdashboards. Thanks Hanjo!
    • Similar to the way that RInno installers can include copies of R, they can now include a copy of Pandoc to support the installation of flexdashboards. Because the registry query (detailed above) is performed post-install, these installation paths are captured by the registry query and can be used in the app startup sequence.
  • Our next release in September - October should include support for OAuth2 for RInno apps using continuous installation.

0.0.3

  • Fixed icon bug
  • Added version information for package dependencies
  • Added the option to select default browser with user_browser
    • Eventually, the user should be able to choose their favorite browser

0.0.2

  • Added support for GitHub package dependencies
    • Thanks Dean Attali (@daattali) for this feature request
  • Fixed error_log so that its name can be customized properly
  • Cleaned up installation paths
  • Added Firefox to the browser search path in app.R:
    1. Chrome
    2. Firefox
    3. Internet Explorer
    4. User prompt
  • Removed packages.txt from installation files. Now using a json array in utils/config.cfg

0.0.1

  • Submitted to CRAN
  • Updated LICENSE to conform with GPL-3 standards
  • Added DesktopDeployR's Aphache 2.0 copyright notice
  • Added Travis-ci, Appveyor, and Codecov to repo
  • Added Code of Conduct for contributors

0.0.0.9001

  • Added a NEWS.md file to track changes to the package.
  • Built function to install Inno Setup.
  • Added support for Bitbucket and GitHub APIs, so that locally deployed shiny apps automatically update during start up sequence.
  • Added support for Inno Setup Script sections (start_iss, directives, setup, files, icons, tasks, run, code, and languages), so you can build custom installation wizards in R.
  • Added application config file, icons, and installation readme.txt.
  • Added package management file which manages a local R library for your shiny app's package dependencies.
  • Added error logging
  • Modified .onAttach to include information about package version and maintenance

Reference manual

It appears you don't have a PDF plugin for this browser. You can click here to download the reference manual.

install.packages("RInno")

0.2.1 by Jon Hill, 14 days ago


www.ficonsulting.com


Report a bug at https://github.com/ficonsulting/RInno/issues


Browse source code at https://github.com/cran/RInno


Authors: Jon Hill [aut, cre, cph], W. Lee Pang [aut, cph] (DesktopDeployR project at https://github.com/wleepang/DesktopDeployR), Hanjo Odendaal [ctb], William Bradley [ctb], Brent (Tom) Bailey [ctb], Mikołaj Rybiński [ctb], Chase Clark [ctb]


Documentation:   PDF Manual  


GPL-3 | file LICENSE license


Imports curl, glue, httr, installr, jsonlite, magrittr, rmarkdown, shiny, stringr

Suggests knitr, stringi, covr, testthat


See at CRAN