WARNING: This is work under development. I strongly recommend that you do not depend on it at this time. Please do not publish a package to NPM that depends on it.
The rw tools is an Rscript-like command-line-interface (CLI) tool
for running R code in an webR WebAssembly environment via either
the Node.js or the Deno JavaScript engines, e.g.
$ rw --r-libs=~/R/webR --prologue=trusted.R untrusted.RThis can be useful when we need to evaluate arbitrary, untrusted R code in a secure manner isolated from the host system. It is also useful for making sure R code and R packages work in webR without having to go the extra mile to upload packages online and then testing it in the web browser at https://webr.sh/.
Using Node:
$ npx @henrikbengtsson/rw --expr="sum(1:100)"
[1] 5050Using Deno:
$ deno run --quiet --allow-all npm:@henrikbengtsson/rw --expr='sum(1:100)'
[1] 5050Technically, you can use --allow-env --allow-read --allow-sys instead of --allow-all.
Node:
npm install --global @henrikbengtsson/rwThe rw executable is installed to the bin/ subfolder under npm config get prefix. Prepend that to your PATH, e.g. export PATH=$(npm config get prefix)/bin:$PATH.
Deno:
deno install --global --allow-env --allow-read --allow-sys npm:@henrikbengtsson/rwThe rw executable is installed to ~/.deno/bin/. Prepend that to
your PATH, e.g. export PATH=~/.deno/bin:$PATH.
$ rw --help
rw: CLI for Sandboxed R Execution
Usage:
rw [options] <script.R> [args]
rw [options] --expr="..."
rw [options] < script.R
rw [options] --persistent install <pkg> [pkg ...]
rw [options] --persistent install --docker <dir> [dir ...]
rw [options] --persistent uninstall <pkg> [pkg ...]
rw build --docker [<dir>]
rw env list
rw env get <field>
rw config [--local] list
rw config [--local] get <field>
rw config [--local] set <field> <value>
rw config [--local] unset <field>
rw config --global list
rw config --global get <field>
rw config --global set <field> <value>
rw config --global unset <field>
Options (general):
--help Show this help
--version Show version
--verbose Show progress messages
--debug Show debug output
--no-config Ignore ./.rwconfig
--vanilla Run R with --vanilla
Options (sandboxing):
--sandbox=<sandbox> Sandbox runtime (default: 'webr')
--sandbox-opt=<key>=<value> Sandbox-specific option (repeatable)
shims=<shim>[,<shim>] — comma-separated shims
(default: sandbox-opt in ./.rwconfig,
or 'shims=install.packages')
--r-libs-user=<host-dir> Bind R user library to host directory
(only active with --persistent;
default: r-libs-user in ./.rwconfig)
--bind=<host-dir>:<rwasm-dir> Bind host directory as a webR directory
(may be specified multiple times)
--bastion=<host-dir> Bind host directory available to prologue and
epilogue code at '/host/bastion', but not
the main code (default: bastion in ./.rwconfig,
or './bastion/' if it exists)
--prologue=<R script> R script evaluated before main R code
--epilogue=<R script> R script evaluated after main R code
--prologue-expr=<R code> R code evaluated before main R code
(default: prologue-expr in ./.rwconfig)
--epilogue-expr=<R code> R code evaluated after main R code
(default: epilogue-expr in ./.rwconfig)
--persistent Persist changes to host (required for 'install')
Options (evaluation):
--expr=<R code> R code to evaluate (multiple okay)
Alternative to specifying 'script.R'
--timeout=<seconds> Maximum evaluation time in seconds
Examples:
rw --expr="sum(1:100)"
rw <<< "1 + 2"
echo "sum(1:100)" | rw
rw main.R
rw < main.R
rw --expr="message('running script ...')" main.R
## Interrupt after 3.5 seconds, if not completed
rw --timeout=3.5 --expr="slow <- function() { Sys.sleep(5); 42 }" \
--expr="tryCatch(slow(), interrupt = identity)"
## Configure R package library on host
mkdir -p ~/R/wasm32-unknown-emscripten-library/4.5
rw config set r-libs-user ~/R/wasm32-unknown-emscripten-library/4.5
rw config get r-libs-user
## Install a package persistently to package library on host
rw --persistent install praise
rw --persistent --expr="message(praise::praise())"
## An R session with the R user library on host
rw --persistent main.R
## Evaluate untrusted R code in sandbox, with data passed in
## and out via a bastion folder accessible only to prologue/epilogue
mkdir -p bastion
Rscript -e "saveRDS(list(a=1, b=2), 'bastion/in.rds')"
rw \
--prologue-expr="data_in <- readRDS('/host/bastion/in.rds')" \
--epilogue-expr="saveRDS(data_out, '/host/bastion/out.rds')" \
--expr="data_out <- lapply(data_in, sqrt)"
Rscript -e "data_out <- readRDS('bastion/out.rds')" -e "utils::str(data_out)"
## Show runtime environment (R/webR versions, resolved paths, etc.)
rw env get webr-version
rw env get r-version
rw env list
## Build a webR binary of an R package via Docker
rw build --docker .
rw build --docker path/to/mypkg
Version: 0.0.111
License: MIT
Author: Henrik Bengtsson