Skip to content

Managing multiple local package versions with devtools::dev_mode

Martina Morris edited this page Jul 24, 2020 · 2 revisions

We often want to test packages before release, or benchmark updated packages with their predecessors. The best way to do this is to have multiple R libraries to hold the different versions, rather than repeatedly installing different versions into the default library.

This is one purpose of devtools::dev_mode. When activated, dev_mode creates a new library (default is "~/R-dev") for storing installed packages, and prepends it to your .libPaths so these versions will be attached first. This allows you to test development packages in a sandbox, without interfering with the other packages you have installed.

Here we cover:

Table of contents generated with markdown-toc

Installing packages from GitHub with devtools::dev_mode

The devtools documentation is typically terse. Here's a minimal example, to install the dev branch of ergm-private:

library(devtools)
dev_mode()
remotes::install_github("statnet/ergm-private@dev")
dev_mode()

You can install multiple packages at once: c("org/package1@branch", "org/package2@branch"). The default branch is master. You can also use the @ syntax to reference a specific commit, or a tagged release.

When you enter dev_mode, you'll notice that the line prompt changes, and your .libPaths is automatically updated by prepending ~/R-dev:

> devtools::dev_mode()
Dev mode: ON

d> .libPaths()
[1] "C:/Users/Martina Morris/Documents/R-dev"            
[2] "C:/Users/Martina Morris/Documents/R/win-library/4.0"
[3] "C:/Program Files/R/R-4.0.2/library"

d>  getOption("devtools.path")
[1] "~/R-dev"
d> devtools::dev_mode()
Dev mode: OFF
>

So dev_mode covers both installation and loading of packages from the new library.

Installing and loading a consistent set of statnet packages into a directory of your choice

The statnet development workflow results in three package versions at any time point:

  • CRAN releases
  • GitHub:
    • master branch - the next release candidate
    • dev branch - ongoing development

Given the dependencies among the statnet packages, it is important to ensure that you load a consistent set that work together.

Using dev_mode

The identification of dependencies is often automated in the package DESCRIPTION file see details below, so in most cases you won't need to specify them in the installation process. To keep the set together, the best practice is to have multiple local folders for your R libraries, each folder dedicated to a specific version. For example, I use

  • the default folder for the CRAN releases (~\Documents\R\win-library\4.0 on Windows),

  • and set up 2 additional folders for the master and dev branch versions (~\Documents\R\master-library and ~\Documents\R\dev-library).

It's simple to install and load to the folder of your choice.

# Give the target folder a short name if you like
> dev_lib <- "~/R/dev-library"

# Specify this folder to `dev.mode`
> devtools::dev_mode(path = dev_lib)
d> remotes::install_github("statnet/ergm-private@dev")

dev_lib has already been set up as the first library to pull from, so you don't need to do anything more.

Note: I recommend using dev_mode if there are package dependencies, as I've seen install_github get confused about what is, and is not, installed when dependencies need to be pulled. It also sets you up to automatically load all of those packages correctly.

Not using dev_mode

If you don't want to use dev_mode, you can specify the folder in the install command directly, and explicitly modify your .libPaths to load from this folder first.

# Give it a short name
> dev_lib <- "~/R/dev-library"

# Install to named folder
remotes::install_github("statnet/ergm-private@dev", lib = dev_lib)

# Make that folder 1st position in libPath for loading (and keep the default around just in case)
defaultPaths <- .libPaths()
.libPaths(c(dev_lib, defaultPaths))
.libPaths()

If you don't change the .libPaths, or if you want a specific combination of package versions, you will need to specify the library location for each package loaded, and load all of the dependencies in reverse order.

Finally, if you're running the package comparisons sequentially from a script/markdown file, you'll need to unload the first set of packages before you can load the next:

# detach CRAN packages
detach("package:ergm.ego", unload = TRUE)
detach("package:ergm", unload = TRUE)
detach("package:network", unload = TRUE)
detach("package:statnet.common", unload = TRUE)

Checking what versions are installed

Always check after your install with sessionInfo::package_info. Default is a long list of all packages and their dependencies, so I usually make things explicit.

sessioninfo::package_info(pkgs = c("network", "networkDynamic", "statnet.common",
                                   "ergm", "tergm", "EpiModel", "EpiModelHPC",
                                   "tergmLite", "EpiABC", "EpiModelHIV",
                                   "ARTnetData", "ARTnet"), dependencies = FALSE)

A note on package dependencies

If you're using install_github, you'll need to be careful about package dependencies. In my example above, ergm-private@dev depends on updated versions of network@master and statnet.common@master.


For those dependencies to be automatically installed, the DESCRIPTION file in the ergm-private repo needs to include a line identifying the remotes to check.


Pavel has now included that line in all of the statnet package DESCRIPTION files: here is an example.

If remote dependencies are needed, but not named in the DESCRIPTION file, you'll need to install_github them explicitly.