why would you need srcpkgs?

# suppressPackageStartupMessages(library(srcpkgs))

# setup a temp dir
root_dir <- tempfile()
dir.create(root_dir)
file.copy('srcpkgs_lotr_demo', root_dir, recursive = TRUE)
workdir <- file.path(root_dir, 'srcpkgs_lotr_demo')
knitr::opts_knit$set(root.dir = workdir) # set directory for other chunks

I will demonstrate srcpkgs using a dummy collection of source packages: https://github.com/kforner/srcpkgs_lotr_demo

overview of the srcpkgs_lotr_demo collection

It consists currently in 11 related packages, with a tree structure:

N.B: lotr depends on all other packages, except for elrond (not yet).

The dependencies are implemented by a mix of Imports, Imports with namespace imports and Depends.

using devtools

suppressPackageStartupMessages(library(devtools))
pkgs <- c('bilbo', 'frodo', 'hobbits', 'legolas', 'galadriel', 'elves', 'gimli', 'aragorn', 'gandalf', 'lotr')

loading

devtools is designed to manage a single source package. Let's use it to load our lotr source package:

load_all('lotr')

--> devtools can NOT load lotr since it can not possibly find the hobbits package, which is a dependency.

Let's help him:

load_all('hobbits')

--> same problem

Here is how we must load the packages, following the dependencies order. Note that we also need to roxygenize them (using document())

document('frodo')
load_all('frodo')
document('bilbo')
load_all('frodo')
document('hobbits')
load_all('hobbits')

document('legolas')
load_all('legolas')
document('galadriel')
load_all('galadriel')
document('elves')
load_all('elves')

document('gimli')
load_all('gimli')
document('aragorn')
load_all('aragorn')
document('gandalf')
load_all('gandalf')

and finally we can load it

document('lotr')
load_all('lotr')

# use it
str(lotr())

editing and reloading

Let's modify one of the direct dependency of lotr, e.g. the hobbits package. Currently:

names(lotr()$hobbits)
lines <- readLines('hobbits/R/main.R')
cat(lines, sep = '\n')

Edit hobbits/R/main.R and comment out bilbo, which comes from the bilbo package in Depends.

edited_lines <- grep('bilbo', lines, invert = TRUE, value = TRUE)
writeLines(edited_lines, 'hobbits/R/main.R')

Let's try to apply our changes:

load_all('lotr')
names(lotr()$hobbits)

--> load_all() can not properly reload our package, since it does not know that a dependency has been modified.

To apply the changes:

load_all('hobbits')
names(lotr()$hobbits)

--> now it works. Note that this is because load_all() is now able to force the unload of a package even though it is needed by another package:

unloadNamespace('hobbits')

But:

devtools::unload('hobbits')

Note that now lotr is broken:

lotr()

Let's fix it

load_all('hobbits')
names(lotr())

using srcpkgs

library(srcpkgs)
options(width = 200)
print(get_srcpkgs())

unloading

the srcpkgs::pkg_unload() takes into account the dependencies between the source packages.

plan <- pkg_unload('bilbo')
print(plan)

unload all our packages to start from a clean state. We will also

for (pkg in get_srcpkgs()) pkg_unload(pkg)

loading

srcpkgs::pkg_load() takes care of everything: it roxygenizes the packages if needed, and load them in the appropriate order:

plan <- pkg_load('lotr')
print(plan)
print(names(lotr()))

editing and reloading

Let's edit the frodo package, and change the weapon from sting to sword:

lotr()$hobbits$frodo

lines <- readLines('frodo/R/main.R')
cat(lines, sep = '\n')

edited_lines <- sub('sting', 'sword', lines)
writeLines(edited_lines, 'frodo/R/main.R')

Now let's ask srcpkgs to make sure the lotr package is up-to-date:

plan <- pkg_load('lotr')
print(plan)

--> It figured out that frodo was modified, and needed to be reloaded, and for that all its dependents needed to be also properly unloaded and re-loaded.

lotr()$hobbits$frodo$weapons


Try the srcpkgs package in your browser

Any scripts or data that you put into this service are public.

srcpkgs documentation built on May 29, 2024, 6:43 a.m.