Skip to content

Commit

Permalink
Merge branch 'main' into tfm/readme-includes-install-script
Browse files Browse the repository at this point in the history
  • Loading branch information
jay-aye-see-kay authored Feb 26, 2024
2 parents e134158 + 3e3aa98 commit 07fffa6
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 7 deletions.
70 changes: 70 additions & 0 deletions plugins/corepack/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Corepack plugin

This plugin sets up [Corepack](https://github.com/nodejs/corepack/), a NodeJS feature to automatically install the correct version of Yarn or PNPM.

When using corepack, running `pnpm` or `yarn` will always use the correct version as defined in the `packageManager` field of the project's `package.json` file.

## Use and activation

1. Make sure you already have a `nodejs` listed as one of your packages in `devbox.json`. You don't need to list `pnpm` or `yarn`:

```json
{
"packages": ["[email protected]"]
}
```

1. Add this plugin to the `include` section of your `devbox.json`:

```json
{
"packages": ["[email protected]"],
"include": ["github:cultureamp/devbox-extras?dir=plugins/corepack"]
}
```

2. Ensure your `package.json` sets a `packageManager` field, for example:

```json
{
"packageManager": "[email protected]"
}
```

or

```json
{
"packageManager": "[email protected]"
}
```

When you run `pnpm -v` or `yarn -v` you should see that the versions used match what you've set in the `packageManager` field.

## Motivation

There’s a subtle but messy issue that can arise using Devbox, Node.js, and Yarn/PNPM. If you install node and yarn as documented you will end up with two different versions of node:

```sh
$ devbox add [email protected] yarn
...
$ devbox run node --version
v20.8.0
$ devbox run yarn node --version
yarn node v1.22.19
v18.18.0
```

This happens because nix bundles all dependencies into every package, yarn is getting it’s own copy of Node.js, which may be more recent than the Node.js version the project is using.

Corepack is a tool included with Node.js that manages PNPM and Yarn versions for you, installing the requested versions as needed and switching seamlessly. Using Corepack would mean that we don't need Devbox / Nix to provide pnpm or Yarn binaries.

But corepack by default tries to install shim scripts for both `yarn` and `pnpm` in the same directory that `node` is found in. Unfortunately when using devbox, the `node` binary is in the Nix store, which is read only, so Corepack gives an error similar to:

> `Internal Error: EACCES: permission denied, unlink '/nix/store/0r6wvd9rr6lsrv8j9b3nv9s9lw7vfb37-profile/bin/pnpm'`
This Devbox plugin works by:

- creating a folder in `.devbox/virtenv/pnpm_plugin/bin/`
- running `corepack enable --install-directory "./devbox/virtenv/pnpm_plugin/bin/"`, which adds the `pnpm` and `yarn` shim scripts
- and then adding `./devbox/virtenv/pnpm_plugin/bin/` to the `PATH` environment variable.
14 changes: 14 additions & 0 deletions plugins/corepack/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "corepack",
"version": "0.0.1",
"readme": "README.md",
"env": {
"PATH": "{{ .Virtenv }}/bin/:$PATH"
},
"shell": {
"init_hook": [
"mkdir -p {{ .Virtenv }}/bin",
"corepack enable --install-directory \"{{ .Virtenv }}/bin/\""
]
}
}
12 changes: 6 additions & 6 deletions scripts/bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@ install_direnv() {
fi
}

direnv_shell_integration() {
shell_integrations() {
DIRENV_BIN="$(command -v direnv)"
DIRENV_BIN="${DIRENV_BIN:-$HOME/.nix-profile/bin/direnv}"
shell=$(basename "$SHELL")
case "$shell" in
*bash*)
rcfile="$HOME/.bashrc"
touch "$rcfile"
printf "\n" >>"$rcfile"
cat <<-EOF >>"$rcfile"
### Do not edit. This was autogenerated by 'bootstrap.sh' ###
export DIRENV_BIN="$DIRENV_BIN"
Expand All @@ -91,7 +91,7 @@ direnv_shell_integration() {
;;
*zsh*)
rcfile="${ZDOTDIR:-$HOME}/.zshrc"
touch "$rcfile"
printf "\n" >>"$rcfile"
cat <<-EOF >>"$rcfile"
### Do not edit. This was autogenerated by 'bootstrap.sh' ###
export DIRENV_BIN="$DIRENV_BIN"
Expand All @@ -102,12 +102,12 @@ direnv_shell_integration() {
*fish*)
rcfile="${XDG_DATA_HOME:-$HOME/.local/share}/fish/vendor_conf.d/direnv.fish"
mkdir -p "$(dirname "$rcfile")"
touch "$rcfile"
printf "\n" >>"$rcfile"
cat <<-EOF >>"$rcfile"
### Do not edit. This was autogenerated by 'bootstrap.sh' ###
set -gx DIRENV_BIN "$DIRENV_BIN"
\$DIRENV_BIN hook fish | source
set -gx NIX_SSL_CERT_FILE='$NETSKOPE_DATA_DIR/nscacert_combined.pem'
set -gx NIX_SSL_CERT_FILE '$NETSKOPE_DATA_DIR/nscacert_combined.pem'
EOF
;;
*)
Expand Down Expand Up @@ -157,7 +157,7 @@ main() {
install_nix
install_devbox
install_direnv
direnv_shell_integration
shell_integrations
install_nix_direnv
print_further_steps
}
Expand Down
2 changes: 1 addition & 1 deletion test/bootstrap-fish.bats
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ load "$DEVBOX_SHARE_DIR/bats/bats-assert/load.bash"
run cat /root/.local/share/fish/vendor_conf.d/direnv.fish
assert_output --partial "set -gx DIRENV_BIN"
assert_output --partial "\$DIRENV_BIN hook fish | source"
assert_output --partial "set -gx NIX_SSL_CERT_FILE="
assert_output --partial "set -gx NIX_SSL_CERT_FILE "
}

0 comments on commit 07fffa6

Please sign in to comment.