Skip to content

Commit

Permalink
Merge pull request #549 from Appsilon/bun-support
Browse files Browse the repository at this point in the history
Allow custom `RHINO_NPM` command (support `bun` and `pnpm`)
  • Loading branch information
kamilzyla authored Jan 18, 2024
2 parents 9631c74 + 6b0684d commit 49cff23
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 27 deletions.
7 changes: 7 additions & 0 deletions .github/workflows/e2e-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@ jobs:
cd RhinoApp
Rscript ../test-dependencies.R
- name: Node.js commands should respect RHINO_NPM
# Skip this test on Windows because it requires a Unix shell.
if: runner.os != 'Windows'
run: |
cd RhinoApp
Rscript ../test-custom-npm.R
- name: lint_r() should detect lint errors in R scripts
if: always()
run: |
Expand Down
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: rhino
Title: A Framework for Enterprise Shiny Applications
Version: 1.5.0.9003
Version: 1.5.0.9004
Authors@R:
c(
person("Kamil", "Żyła", role = c("aut", "cre"), email = "[email protected]"),
Expand Down
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
* `lint_sass()` now uses `stylelint` 14.16 (the last major version supporting stylistic rules)
* Upgrade all remaining Node.js dependencies to latest versions and fix vulnerabilities.
* The minimum supported Node.js version is now 16.
4. Introduce `RHINO_NPM` environment variable
to allow using `npm` alternatives like `bun` and `pnpm`.

# [rhino 1.5.0](https://github.com/Appsilon/rhino/releases/tag/v1.5.0)

Expand Down
47 changes: 25 additions & 22 deletions R/node.R
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,36 @@ node_path <- function(...) {
fs::path(".rhino", ...)
}

add_node <- function(clean = FALSE) {
if (clean && fs::dir_exists(node_path())) {
fs::dir_delete(node_path())
# Run `npm` or an alternative command specified by `RHINO_NPM`.
# If needed, copy over Node.js template and install dependencies.
npm <- function(...) {
npm_command <- Sys.getenv("RHINO_NPM", "npm")
check_system_dependency(
cmd = npm_command,
dependency_name = ifelse(npm_command == "npm", "Node.js", npm_command),
documentation_url = "https://go.appsilon.com/rhino-system-dependencies"
)
node_init(npm_command)
node_run(npm_command, ...)
}

node_init <- function(npm_command) {
if (!fs::dir_exists(node_path())) {
cli::cli_alert_info("Initializing Node.js directory...")
copy_template("node", node_path())
}
if (!fs::dir_exists(node_path("node_modules"))) {
cli::cli_alert_info("Installing Node.js packages with {npm_command}...")
node_run(npm_command, "install", "--no-audit", "--no-fund")
}
copy_template("node", node_path())
}

# Run `npm` command (assume node directory already exists in the project).
npm_raw <- function(..., status_ok = 0) {
# Run the specified command in Node.js directory (assume it already exists).
node_run <- function(command, ..., status_ok = 0) {
withr::with_dir(node_path(), {
status <- system2(command = "npm", args = c(...))
status <- system2(command = command, args = c(...))
})
if (status != status_ok) {
cli::cli_abort("System command 'npm' exited with status {status}.")
}
}

# Run `npm` command (create node directory in the project if needed).
npm <- function(...) {
check_system_dependency(
cmd = "node",
dependency_name = "Node.js",
documentation_url = "https://go.appsilon.com/rhino-system-dependencies"
)
if (!fs::dir_exists(node_path())) {
add_node()
npm_raw("install", "--no-audit", "--no-fund")
cli::cli_abort("System command '{command}' exited with status {status}.")
}
npm_raw(...)
}
7 changes: 5 additions & 2 deletions inst/WORDLIST
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
Addin
Addins
Appsilon
Boxifying
ESLint
Expand All @@ -13,9 +15,11 @@ Renv
Renviron
Rhinoverse
Rprofile
Rstudio
SDK
Stylelint
UI
Webpack
blogpost
conf
config
Expand All @@ -41,6 +45,7 @@ nodejs
npm
nvm
overridable
pnpm
preconfigured
renv
roxygen
Expand All @@ -54,5 +59,3 @@ unintuitive
usethis
webpack
yml
Addin
Addins
22 changes: 22 additions & 0 deletions tests/e2e/test-custom-npm.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
local({
tmp <- withr::local_tempdir()
wrapper_path <- fs::path(tmp, "wrapper")
touch_path <- fs::path(tmp, "it_works")

# Prepare a wrapper script which creates an "it_works" file and runs npm.
fs::file_create(wrapper_path, mode = "u=rwx")
writeLines(
c(
"#!/bin/sh",
paste("touch", touch_path),
'exec npm "$@"'
),
wrapper_path
)

# Use the wrapper script instead of npm.
withr::local_envvar(RHINO_NPM = wrapper_path)
rhino:::npm("--version")

testthat::expect_true(fs::file_exists(touch_path))
})
10 changes: 8 additions & 2 deletions vignettes/explanation/node-js-javascript-and-sass-tools.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@ vignette: >
can execute JavaScript code outside a web browser. It is used widely for
web development. Its package manager,
[npm](https://docs.npmjs.com/about-npm), makes it easy to install
virtually any JavaScript library.
virtually any JavaScript library. You can use other package managers such as
[bun](https://bun.sh) and [pnpm](https://pnpm.io/) that are compatible with
`npm`.

To switch from the default npm usage, set a global environment variable named
`RHINO_NPM`. For instance, if you want to use `bun` instead of `npm`,
add `export RHINO_NPM=bun` to your shell startup file (e.g. `.bashrc`).

Rhino uses Node.js to provide state of the art tools for working with
JavaScript and Sass. The following functions require Node.js to work:
Expand All @@ -26,7 +32,7 @@ JavaScript and Sass. The following functions require Node.js to work:

### Node directory

Under the hood Rhino will create a `.rhino/node` directory in your
Under the hood Rhino will create a `.rhino` directory in your
project to store the specific libraries needed by these tools. This
directory is git-ignored by default and safe to remove.

Expand Down

0 comments on commit 49cff23

Please sign in to comment.