Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow custom RHINO_NPM command (support bun and pnpm) #549

Merged
merged 10 commits into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 = "opensource+kamil@appsilon.com"),
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
Loading