mirror of
https://github.com/asdf-vm/asdf-nodejs.git
synced 2024-10-06 07:42:08 +08:00
Merge pull request #272 from augustobmoura/feature/nodenv-build-system
Use node-build as main installation/building drive
This commit is contained in:
commit
6430bd8e82
2
.gitignore
vendored
2
.gitignore
vendored
@ -72,3 +72,5 @@ $RECYCLE.BIN/
|
||||
*.lnk
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/linux,macos,windows
|
||||
|
||||
.node-build
|
||||
|
117
README.md
117
README.md
@ -4,23 +4,6 @@
|
||||
|
||||
Node.js plugin for [asdf](https://github.com/asdf-vm/asdf) version manager
|
||||
|
||||
*The plugin properly validates OpenPGP signatures to check the authenticity of the package. Requires `gpg` to be available during package installs*
|
||||
|
||||
## Requirements
|
||||
|
||||
|
||||
### macOS
|
||||
* [GnuPG](http://www.gnupg.org) - `brew install gpg`
|
||||
* awk - any posix compliant implementation (tested on gawk `brew install gawk`)
|
||||
|
||||
### Linux (Debian)
|
||||
|
||||
* [dirmngr](https://packages.debian.org/sid/dirmngr) - `apt-get install
|
||||
dirmngr`
|
||||
* [GnuPG](http://www.gnupg.org) - `apt-get install gpg`
|
||||
* [curl](https://curl.haxx.se) - `apt-get install curl`
|
||||
* awk - any posix compliant implementation (tested on gawk `apt-get install gawk`)
|
||||
|
||||
## Install
|
||||
|
||||
After installing [asdf](https://github.com/asdf-vm/asdf), install the plugin by running:
|
||||
@ -31,26 +14,67 @@ asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs.git
|
||||
|
||||
## Use
|
||||
|
||||
Check [asdf](https://github.com/asdf-vm/asdf) readme for instructions on how to install & manage versions of Node.js.
|
||||
Check [asdf](https://github.com/asdf-vm/asdf) readme for instructions on how to install & manage versions of Node.js at a system and project level.
|
||||
|
||||
When installing Node.js using `asdf install`, you can pass custom configure options with the following env vars:
|
||||
Behind the scenes, `asdf-nodejs` utilizes [`node-build`](https://github.com/nodenv/node-build) to install pre-compiled binaries and compile from source if necessary. You can check its [README](https://github.com/nodenv/node-build/blob/master/README.md) for additional settings and some troubleshooting.
|
||||
|
||||
* `NODEJS_CONFIGURE_OPTIONS` - use only your configure options
|
||||
* `NODEJS_EXTRA_CONFIGURE_OPTIONS` - append these configure options along with ones that this plugin already uses
|
||||
* `NODEJS_CHECK_SIGNATURES` - `strict` is default. Other values are `no` and `yes`. Checks downloads against OpenPGP signatures from the Node.js release team.
|
||||
* `NODEJS_ORG_MIRROR` - official mirror `https://nodejs.org/dist/` is default. If you are in China, you can set it to `https://npm.taobao.org/mirrors/node/`.
|
||||
When compiling a version from source, you are going to need to install [all requirements for compiling Node.js](https://github.com/nodejs/node/blob/master/BUILDING.md#building-nodejs-on-supported-platforms) (be advised that different versions might require different configurations). That being said, `node-build` does a great job at handling edge cases and compilations rarely need a deep investigation.
|
||||
|
||||
### `.nvmrc` and `.node-version` files
|
||||
### Configuration
|
||||
|
||||
asdf uses the `.tool-versions` for auto-switching between software versions. To ease migration, you can have it read an existing `.nvmrc` or `.node-version` file to find out what version of Node.js should be used. To do this, add the following to `$HOME/.asdfrc`:
|
||||
`node-build` already has a [handful of settings](https://github.com/nodenv/node-build#custom-build-configuration), in additional to that `asdf-nodejs` has a few extra configuration variables:
|
||||
|
||||
- `ASDF_NODEJS_NODEBUILD_HOME`: Home for the node-build installation, defaults to `$ASDF_DIR/plugins/nodejs/.node-build`, you can install it in another place or share it with your system
|
||||
- `ASDF_NODEJS_NODEBUILD`: Path to the node-build executable, defaults to `$NODE_BUILD_MIRROR_URL/bin/node-build`
|
||||
- `ASDF_NODEJS_CONCURRENCY`: How many jobs should be used in compilation. Defaults to half the computer cores
|
||||
- `ASDF_NODEJS_VERBOSE_INSTALL`: Enables verbose output for downloading and building. Any value different from empty is treated as enabled.
|
||||
- `NODEJS_ORG_MIRROR`: (Legacy) overrides the default mirror used for downloading the distibutions, alternative to the `NODE_BUILD_MIRROR_URL` node-build env var
|
||||
|
||||
### Integrity/signature check
|
||||
|
||||
In the past `asdf-nodejs` checked for signatures and integrity by querying live keyservers. `node-build`, on the other hand, checks integrity by precomputing checksums ahead of time and versioning them together with the instructions for building them, making the process a lot more streamlined.
|
||||
|
||||
### `.nvmrc` and `.node-version` support
|
||||
|
||||
asdf uses a `.tool-versions` file for auto-switching between software versions. To ease migration, you can have it read an existing `.nvmrc` or `.node-version` file to find out what version of Node.js should be used. To do this, add the following to `$HOME/.asdfrc`:
|
||||
|
||||
```
|
||||
legacy_version_file = yes
|
||||
```
|
||||
|
||||
### Running the wrapped node-build command
|
||||
|
||||
We provide a command for running the installed `node-build` command:
|
||||
|
||||
```bash
|
||||
asdf nodejs nodebuild --version
|
||||
```
|
||||
|
||||
### node-build advanced variations
|
||||
|
||||
`node-build` has some additional variations aside from the versions listed in `asdf list-all nodejs` (chakracore/graalvm branches and some others). As of now, we weakly support these variations. In the sense that they are available for install and can be used in a `.tool-versions` file, but we don't list them as installation candidates nor give them full attention.
|
||||
|
||||
Some of them will work out of the box, and some will need a bit of investigation to get them built. We are planning in providing better support for these variations in the future.
|
||||
|
||||
To list all the available variations run:
|
||||
|
||||
```bash
|
||||
asdf nodejs nodebuild --definitions
|
||||
```
|
||||
|
||||
_Note that this command only lists the current `node-build` definitions. You might want to [update the local `node-build` repository](#updating-node-build-definitions) before listing them._
|
||||
|
||||
### Manually updating node-build definitions
|
||||
|
||||
Every new node version needs to have a definition file in the `node-build` repository. `asdf-nodejs` already tries to update `node-build` on every new version installation, but if you want to update `node-build` manually for some reason we provide a command just for that:
|
||||
|
||||
```bash
|
||||
asdf nodejs update-nodebuild
|
||||
```
|
||||
|
||||
## Default npm Packages
|
||||
|
||||
asdf-nodejs can automatically install a set of default set of npm package right after installing a Node.js version. To enable this feature, provide a `$HOME/.default-npm-packages` file that lists one package per line, for example:
|
||||
`asdf-nodejs` can automatically install a set of default set of npm package right after installing a Node.js version. To enable this feature, provide a `$HOME/.default-npm-packages` file that lists one package per line, for example:
|
||||
|
||||
```
|
||||
lodash
|
||||
@ -59,44 +83,3 @@ express
|
||||
```
|
||||
|
||||
You can specify a non-default location of this file by setting a `ASDF_NPM_DEFAULT_PACKAGES_FILE` variable.
|
||||
|
||||
## Problems with OpenPGP signatures in older versions
|
||||
|
||||
The plugin automatically imports the NodeJS release team's OpenPGP keys. If you are trying to install a previous release and facing any issue about verification, import the Node.js previous release team's OpenPGP keys to main keyring:
|
||||
|
||||
```bash
|
||||
bash -c '${ASDF_DATA_DIR:=$HOME/.asdf}/plugins/nodejs/bin/import-previous-release-team-keyring'
|
||||
```
|
||||
|
||||
## Using a dedicated OpenPGP keyring
|
||||
|
||||
The `bash` script mentioned in [the installation instructions](#install) (`import-release-team-keyring`) imports the OpenPGP public keys in your main OpenPGP keyring. However, you can also use a dedicated keyring in order to mitigate [this issue](https://github.com/nodejs/node/issues/9859).
|
||||
|
||||
To use a dedicated keyring, prepare the dedicated keyring and set it as the default keyring in the current shell:
|
||||
|
||||
```bash
|
||||
export GNUPGHOME="${ASDF_DIR:-$HOME/.asdf}/keyrings/nodejs" && mkdir -p "$GNUPGHOME" && chmod 0700 "$GNUPGHOME"
|
||||
|
||||
# Imports Node.js release team's OpenPGP keys to the keyring
|
||||
bash ~/.asdf/plugins/nodejs/bin/import-release-team-keyring
|
||||
```
|
||||
|
||||
Again, if you used `brew` to manage the `asdf` installation use the following bash commands:
|
||||
|
||||
```bash
|
||||
export GNUPGHOME="bash /usr/local/opt/asdf/keyrings/nodejs" && mkdir -p "$GNUPGHOME" && chmod 0700 "$GNUPGHOME"
|
||||
|
||||
# Imports Node.js release team's OpenPGP keys to the keyring
|
||||
bash /usr/local/opt/asdf/plugins/nodejs/bin/import-release-team-keyring
|
||||
```
|
||||
|
||||
#### Related notes
|
||||
|
||||
* [Verifying Node.js Binaries](https://github.com/nodejs/node#verifying-binaries).
|
||||
* Only versions `>=0.10.0` are checked. Before that version, signatures for SHA2-256 hashes might not be provided (and can not be installed with the `strict` setting for that reason).
|
||||
|
||||
This behavior can be influenced by the `NODEJS_CHECK_SIGNATURES` env var which supports the following options:
|
||||
|
||||
* `strict` - (default): Check signatures/checksums and don’t operate on package versions which did not provide signatures/checksums properly (< 0.10.0).
|
||||
* `no` - Do not check signatures/checksums
|
||||
* `yes`- Check signatures/checksums if they should be present (enforced for >= 0.10.0)
|
||||
|
@ -1,38 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -o nounset -o pipefail -o errexit
|
||||
|
||||
## Previous Keys from https://github.com/nodejs/node/#release-keys
|
||||
KEYS="9554F04D7259F04124DE6B476D5A82AC7E37093B \
|
||||
B9AE9905FFD7803F25714661B63B535A4C206CA9 \
|
||||
77984A986EBC2AA786BC0F66B01FBB92821C587A \
|
||||
93C7E9E91B49E432C2F75674B0A78B0A6C481CF6 \
|
||||
56730D5401028683275BD23C23EFEFE93C4CFFFE \
|
||||
FD3A5288F042B6850C66B31F09FE44734EB7990E \
|
||||
114F43EE0176B71C7BC219DD50A3051F888C628D \
|
||||
7937DFD2AB06298B2293C3187D33FF9D0246406D \
|
||||
1C050899334244A8AF75E53792EF661D867B9DFA"
|
||||
|
||||
SERVERS="keyserver.ubuntu.com
|
||||
keyserver.ubuntu.com:80 \
|
||||
pgp.mit.edu
|
||||
pgp.mit.edu:80"
|
||||
|
||||
OPTIONS=""
|
||||
if [ -v http_proxy ];
|
||||
then OPTIONS="--keyserver-options http-proxy=$http_proxy";
|
||||
fi
|
||||
|
||||
gnugp_verify_command_name="$(command -v gpg gpg2 | head -n 1 || :)"
|
||||
|
||||
if [ -z "${gnugp_verify_command_name}" ]; then
|
||||
echo 'gpg or gpg2 command not found!' >&2
|
||||
echo "You must install GnuPG to import release team keys: https://www.gnupg.org/" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for key in $KEYS; do
|
||||
for server in $SERVERS; do
|
||||
$gnugp_verify_command_name --no-tty --keyserver "hkp://$server" $OPTIONS --display-charset utf-8 --recv-keys "$key" && break
|
||||
done
|
||||
done
|
@ -1,43 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -o nounset -o pipefail -o errexit
|
||||
|
||||
source "$(dirname "$0")/../lib/utils.sh"
|
||||
|
||||
## Keys from https://github.com/nodejs/node/#release-keys
|
||||
KEYS="4ED778F539E3634C779C87C6D7062848A1AB005C \
|
||||
94AE36675C464D64BAFA68DD7434390BDBE9B9C5 \
|
||||
74F12602B6F1C4E913FAA37AD3A89613643B6201 \
|
||||
71DCFD284A79C3B38668286BC97EC7A07EDE3FC1 \
|
||||
8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600 \
|
||||
C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 \
|
||||
C82FA3AE1CBEDC6BE46B9360C43CEC45C17AB93C \
|
||||
DD8F2338BAE7501E3DD5AC78C273792F7D83545D \
|
||||
A48C2BEE680E841632CD4E44F07496B3EB3C1762 \
|
||||
108F52B48DB57BB0CC439B2997B01419BD92F80A \
|
||||
B9E2F5981AA6E0CD28160D9FF13993A75599653C"
|
||||
|
||||
SERVERS="keyserver.ubuntu.com
|
||||
keyserver.ubuntu.com:80 \
|
||||
pgp.mit.edu
|
||||
pgp.mit.edu:80"
|
||||
|
||||
OPTIONS=""
|
||||
if [ -n "${http_proxy:-}" ];
|
||||
then OPTIONS="--keyserver-options http-proxy=$http_proxy";
|
||||
fi
|
||||
|
||||
gnugp_verify_command_name="$(command -v gpg gpg2 | head -n 1 || :)"
|
||||
|
||||
if [ -z "${gnugp_verify_command_name}" ]; then
|
||||
echo 'gpg or gpg2 command not found!' >&2
|
||||
echo "You must install GnuPG to import release team keys: https://www.gnupg.org/" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for key in $KEYS; do
|
||||
for server in $SERVERS; do
|
||||
$gnugp_verify_command_name --with-colons --no-default-keyring --keyring ${ASDF_NODEJS_KEYRING} -k $key > /dev/null 2>&1 || \
|
||||
$gnugp_verify_command_name --no-default-keyring --keyring ${ASDF_NODEJS_KEYRING} --no-tty --keyserver "hkp://$server" $OPTIONS --display-charset utf-8 --recv-keys "$key" && break
|
||||
done
|
||||
done
|
322
bin/install
322
bin/install
@ -1,85 +1,59 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -o nounset -o pipefail -o errexit
|
||||
set -eu -o pipefail
|
||||
|
||||
# shellcheck source=../lib/utils.sh
|
||||
source "$(dirname "$0")/../lib/utils.sh"
|
||||
|
||||
NODEJS_CHECK_SIGNATURES="${NODEJS_CHECK_SIGNATURES:-strict}"
|
||||
|
||||
|
||||
install_nodejs() {
|
||||
local install_type="$1"
|
||||
local version_query="$2"
|
||||
local install_path="$3"
|
||||
local tmp_download_dir="$4"
|
||||
local install_type="$1" version_query="$2" install_path="$3"
|
||||
local version=
|
||||
|
||||
local version="$(resolve_version_query "$version_query")"
|
||||
version="$(resolve_version_query "$version_query")"
|
||||
|
||||
if [ "$version" != "$version_query" ]; then
|
||||
install_aliased_version "$version" "$version_query" "$install_path"
|
||||
else
|
||||
install_canon_version "$1" "$version" "$3" "$4"
|
||||
install_canon_version "$install_type" "$version" "$install_path"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
try_to_update_nodebuild() {
|
||||
local exit_code=0
|
||||
|
||||
"$ASDF_NODEJS_PLUGIN_DIR/lib/commands/command-update-nodebuild.bash" 2> /dev/null || exit_code=$?
|
||||
|
||||
if [ "$exit_code" != 0 ]; then
|
||||
printf "
|
||||
$(colored $YELLOW WARNING): Updating node-build failed with exit code %s. The installation will
|
||||
try to continue with already installed local defintions. To debug what went
|
||||
wrong try to manually updating node-build by running: \`asdf %s update nodebuild\`
|
||||
\n" "$exit_code" "$ASDF_NODEJS_PLUGIN_NAME"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
nodebuild_wrapped() {
|
||||
"$ASDF_NODEJS_PLUGIN_DIR/lib/commands/command-nodebuild.bash" "$@"
|
||||
}
|
||||
|
||||
|
||||
install_canon_version() {
|
||||
local install_type="$1"
|
||||
local version="$2"
|
||||
local install_path="$3"
|
||||
local tmp_download_dir="$4"
|
||||
local make_flags="-j${ASDF_CONCURRENCY-1}"
|
||||
local install_type="$1" version="$2" install_path="$3"
|
||||
local args=()
|
||||
|
||||
## Do this first as it is fast but could fail.
|
||||
download_and_verify_checksums "$install_type" "$version" "$tmp_download_dir"
|
||||
|
||||
local archive_path
|
||||
archive_path="${tmp_download_dir}/$(get_archive_file_name "$install_type" "$version")"
|
||||
|
||||
local download_result=0
|
||||
download_file "$(get_download_url "$install_type" "$version")" "${archive_path}" \
|
||||
|| download_result=$?
|
||||
|
||||
if [ $download_result != 0 ]; then
|
||||
if [ "$install_type" = "ref" ]; then
|
||||
die "Source code not found for version $version"
|
||||
if [ "$install_type" = ref ]; then
|
||||
args+=(-c)
|
||||
fi
|
||||
|
||||
echo "Binary not found for version $version. Falling back to source code"
|
||||
install_type="ref"
|
||||
try_to_update_nodebuild
|
||||
|
||||
download_file "$(get_download_url "$install_type" "$version")" "${archive_path}" \
|
||||
|| die "Source code not found for version $version"
|
||||
else
|
||||
verify_archive "$tmp_download_dir"
|
||||
fi
|
||||
|
||||
# running this in a subshell
|
||||
# we don't want to disturb current working dir
|
||||
(
|
||||
if [ "$install_type" != "version" ]; then
|
||||
tar zxf "$archive_path" -C "$install_path" --strip-components=1 || exit 1
|
||||
cd "$install_path" || exit 1
|
||||
|
||||
local configure_options
|
||||
configure_options="$(construct_configure_options "$install_path")"
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
./configure $configure_options || exit 1
|
||||
make $make_flags || exit 1
|
||||
make $make_flags install || exit 1
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
rm -rf "$install_path"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
tar zxf "$archive_path" -C "$install_path" --strip-components=1 || exit 1
|
||||
fi
|
||||
)
|
||||
NODE_BUILD_BUILD_PATH="$ASDF_DOWNLOAD_PATH" NODE_BUILD_CACHE_PATH="$ASDF_DOWNLOAD_PATH" \
|
||||
nodebuild_wrapped ${args+"${args[@]}"} "$version" "$install_path"
|
||||
}
|
||||
|
||||
|
||||
install_aliased_version() {
|
||||
local version=$1
|
||||
local version_query=$2
|
||||
@ -118,237 +92,27 @@ resolve_version_query() {
|
||||
}
|
||||
|
||||
|
||||
construct_configure_options() {
|
||||
local install_path="$1"
|
||||
|
||||
if [ -z "${NODEJS_CONFIGURE_OPTIONS:-}" ]; then
|
||||
local configure_options
|
||||
configure_options="--dest-cpu=$(get_nodejs_machine_hardware_name)"
|
||||
|
||||
if [ "${NODEJS_EXTRA_CONFIGURE_OPTIONS:-}" != "" ]; then
|
||||
configure_options="$configure_options ${NODEJS_EXTRA_CONFIGURE_OPTIONS:-}"
|
||||
fi
|
||||
else
|
||||
local configure_options="${NODEJS_CONFIGURE_OPTIONS:-}"
|
||||
fi
|
||||
|
||||
configure_options="$configure_options --prefix=$install_path"
|
||||
|
||||
echo "$configure_options"
|
||||
}
|
||||
|
||||
|
||||
get_nodejs_machine_hardware_name() {
|
||||
local machine_hardware_name
|
||||
machine_hardware_name="$(uname -m)"
|
||||
|
||||
case "$machine_hardware_name" in
|
||||
'x86_64') local cpu_type="x64";;
|
||||
# For FreeBSD
|
||||
'amd64') local cpu_type="x64";;
|
||||
'i686') local cpu_type="x86";;
|
||||
'aarch64') local cpu_type="arm64";;
|
||||
*) local cpu_type="$machine_hardware_name";;
|
||||
esac
|
||||
|
||||
echo "$cpu_type"
|
||||
}
|
||||
|
||||
|
||||
download_file() {
|
||||
local download_url="$1"
|
||||
local download_path="$2"
|
||||
|
||||
STATUSCODE=$(curl --write-out "%{http_code}" -Lo "$download_path" "$download_url")
|
||||
|
||||
if test $STATUSCODE -eq 404; then
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
get_archive_file_name() {
|
||||
local install_type="$1"
|
||||
local version="$2"
|
||||
|
||||
local pkg_name
|
||||
|
||||
if [ "$install_type" = "version" ]; then
|
||||
pkg_name="node-v${version}-$(uname -s | tr '[:upper:]' '[:lower:]')-$(get_nodejs_machine_hardware_name)"
|
||||
else
|
||||
pkg_name="v${version}"
|
||||
fi
|
||||
|
||||
echo "${pkg_name}.tar.gz"
|
||||
}
|
||||
|
||||
|
||||
get_download_url() {
|
||||
local install_type="$1"
|
||||
local version="$2"
|
||||
|
||||
if [ "$install_type" = "version" ]; then
|
||||
local download_url_base="${NODEJS_ORG_MIRROR}v${version}"
|
||||
else
|
||||
local download_url_base="https://github.com/nodejs/node/archive"
|
||||
fi
|
||||
|
||||
echo "${download_url_base}/$(get_archive_file_name "$install_type" "$version")"
|
||||
}
|
||||
|
||||
|
||||
get_signed_checksum_download_url() {
|
||||
local install_type=$1
|
||||
local version=$2
|
||||
|
||||
if [ "$install_type" = "version" ]; then
|
||||
echo "${NODEJS_ORG_MIRROR}v${version}/SHASUMS256.txt.asc"
|
||||
else
|
||||
# Not implemented.
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
download_and_verify_checksums() {
|
||||
local install_type="$1"
|
||||
local version="$2"
|
||||
local tmp_download_dir="$3"
|
||||
|
||||
if [ "${NODEJS_CHECK_SIGNATURES}" == "no" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
## Seems nodejs.org started with around 0.10.0 to release properly signed SHA2-256 checksum files.
|
||||
if verlte "0.10.0" "$version"
|
||||
then
|
||||
local signed_checksum_file="$tmp_download_dir/SHASUMS256.txt.asc"
|
||||
local signed_checksum_download_url
|
||||
signed_checksum_download_url="$(get_signed_checksum_download_url "$install_type" "$version")"
|
||||
if [ -z "${signed_checksum_download_url}" ]; then
|
||||
if [ "${NODEJS_CHECK_SIGNATURES}" == "strict" ]; then
|
||||
echo "$version did not provide signed checksums or support for them has not been implemented and NODEJS_CHECK_SIGNATURES=strict is set. Exiting." >&2
|
||||
exit 1
|
||||
else
|
||||
echo "$version did not provide signed checksums or support for them has not been implemented. Continue without signature checking." >&2
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
download_file "${signed_checksum_download_url}" "$signed_checksum_file" \
|
||||
|| die "Checksum not found for version $version"
|
||||
|
||||
local gnugp_verify_command_name
|
||||
gnugp_verify_command_name="$(command -v gpg gpg2 | head -n 1 || :)"
|
||||
if [ -z "${gnugp_verify_command_name}" ]; then
|
||||
echo "You must install GnuPG to verify the authenticity of the downloaded archives before continuing with the install: https://www.gnupg.org/" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
(
|
||||
if [ -z "${GNUPGHOME:-}" ] && [ -d "${ASDF_DIR:-$HOME/.asdf}/keyrings/nodejs" ]; then
|
||||
export GNUPGHOME="${ASDF_DIR:-$HOME/.asdf}/keyrings/nodejs"
|
||||
fi
|
||||
|
||||
# Automatically add needed PGP keys
|
||||
"$(dirname "$0")/import-release-team-keyring"
|
||||
|
||||
if ! $gnugp_verify_command_name --no-default-keyring --keyring "${ASDF_NODEJS_KEYRING}" --display-charset utf-8 --verify "$signed_checksum_file" 2>/dev/null; then
|
||||
# Try default keyring
|
||||
if ! $gnugp_verify_command_name --display-charset utf-8 --verify "$signed_checksum_file" 2>/dev/null; then
|
||||
echo "Authenticity of checksum file can not be assured! Please be sure to check the README of asdf-nodejs in case you did not yet import the needed PGP keys. Also, make sure the plugin is up-to-date by running \`asdf plugin update $(plugin_name)\`. If you already did that then that is the point to become SUSPICIOUS! There must be a reason why this is failing. If you are installing an older NodeJS version you might need to import OpenPGP keys of previous release managers. Exiting." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
## Mitigates: https://github.com/nodejs/node/issues/6821
|
||||
local authentic_checksum_file="$tmp_download_dir/authentic_SHASUMS256.txt"
|
||||
$gnugp_verify_command_name --no-default-keyring --keyring "${ASDF_NODEJS_KEYRING}" --yes --output "${authentic_checksum_file}" --decrypt "$signed_checksum_file" 2>/dev/null ||
|
||||
$gnugp_verify_command_name --yes --output "${authentic_checksum_file}" --decrypt "$signed_checksum_file" 2>/dev/null
|
||||
)
|
||||
elif [ "${NODEJS_CHECK_SIGNATURES}" == "strict" ]; then
|
||||
echo "$version did not provide signed checksums or support for them has not been implemented and NODEJS_CHECK_SIGNATURES=strict is set. Exiting." >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
checkShasum ()
|
||||
{
|
||||
local archive_file_name="${1}"
|
||||
local authentic_checksum_file="${2}"
|
||||
|
||||
if $(command -v sha256sum >/dev/null 2>&1); then
|
||||
sha256sum \
|
||||
-c <(grep "\s${archive_file_name}$" "${authentic_checksum_file}")
|
||||
elif $(command -v shasum >/dev/null 2>&1); then
|
||||
shasum \
|
||||
-a 256 \
|
||||
-c <(grep "\s${archive_file_name}$" "${authentic_checksum_file}")
|
||||
else
|
||||
echo "sha256sum or shasum is not available for use" >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
verify_archive() {
|
||||
local tmp_download_dir="$1"
|
||||
|
||||
local authentic_checksum_file="$tmp_download_dir/authentic_SHASUMS256.txt"
|
||||
|
||||
if [ "${NODEJS_CHECK_SIGNATURES}" == "no" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ "${NODEJS_CHECK_SIGNATURES}" == "yes" ] && [ ! -e "${authentic_checksum_file}" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if verlte "0.10.0" "$version"
|
||||
then
|
||||
local archive_file_name
|
||||
archive_file_name="$(basename "$(get_download_url "$install_type" "$version")")"
|
||||
|
||||
(
|
||||
cd "${tmp_download_dir}"
|
||||
if ! checkShasum "$archive_file_name" "$authentic_checksum_file"; then
|
||||
echo "Authenticity of package archive can not be assured. Exiting." >&2
|
||||
exit 1
|
||||
fi
|
||||
)
|
||||
fi
|
||||
}
|
||||
|
||||
# stolen from https://github.com/rbenv/ruby-build/pull/631/files#diff-fdcfb8a18714b33b07529b7d02b54f1dR942
|
||||
function sort_versions() {
|
||||
sed 'h; s/[+-]/./g; s/.p\([[:digit:]]\)/.z\1/; s/$/.z/; G; s/\n/ /' | \
|
||||
LC_ALL=C sort -t. -k 1,1 -k 2,2n -k 3,3n -k 4,4n -k 5,5n | awk '{print $2}'
|
||||
}
|
||||
|
||||
verlte() {
|
||||
## https://stackoverflow.com/questions/4023830/how-compare-two-strings-in-dot-separated-version-format-in-bash/4024263#4024263
|
||||
[ "$1" = "$(echo -e "$1\n$2" | sort_versions | head -n1)" ]
|
||||
}
|
||||
|
||||
install_default_npm_packages() {
|
||||
local default_npm_packages="${ASDF_NPM_DEFAULT_PACKAGES_FILE:=$HOME/.default-npm-packages}"
|
||||
local name
|
||||
|
||||
if [ ! -f "$default_npm_packages" ]; then return; fi
|
||||
|
||||
cat "$default_npm_packages" | while read -r name; do
|
||||
echo -ne "\nInstalling \033[33m${name}\033[39m npm package... "
|
||||
while read -r name; do
|
||||
(
|
||||
printf "Installing $(colored $YELLOW %s) npm package...\n" "$name"
|
||||
source "$(dirname "$0")/exec-env"
|
||||
PATH="$ASDF_INSTALL_PATH/bin:$PATH" npm install -g "$name" > /dev/null 2>&1 && rc=$? || rc=$?
|
||||
if [[ $rc -eq 0 ]]; then
|
||||
echo -e "\033[32mSUCCESS\033[39m"
|
||||
printf "$(colored $GREEN SUCCESS)\n"
|
||||
else
|
||||
echo -e "\033[31mFAIL\033[39m"
|
||||
printf "$(colored $RED FAIL)\n"
|
||||
fi
|
||||
done
|
||||
)
|
||||
done < "$default_npm_packages"
|
||||
}
|
||||
|
||||
tmp_download_dir="$(mktemp -d -t 'asdf_nodejs_XXXXXX')"
|
||||
trap 'rm -rf "${tmp_download_dir}"' EXIT
|
||||
|
||||
install_nodejs "$ASDF_INSTALL_TYPE" "$ASDF_INSTALL_VERSION" "$ASDF_INSTALL_PATH" "$tmp_download_dir"
|
||||
ASDF_SKIP_RESHIM=1 install_default_npm_packages
|
||||
install_nodejs "$ASDF_INSTALL_TYPE" "$ASDF_INSTALL_VERSION" "$ASDF_INSTALL_PATH"
|
||||
install_default_npm_packages
|
||||
|
||||
asdf reshim "$(plugin_name)" "$ASDF_INSTALL_VERSION"
|
||||
|
41
lib/commands/command-nodebuild.bash
Executable file
41
lib/commands/command-nodebuild.bash
Executable file
@ -0,0 +1,41 @@
|
||||
#! /usr/bin/env bash
|
||||
|
||||
set -eu -o pipefail
|
||||
|
||||
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/../utils.sh"
|
||||
|
||||
DEFAULT_CONCURRENCY=$(bc <<< "scale=0; (${ASDF_CONCURRENCY-1} + 1) / 2")
|
||||
|
||||
: "${ASDF_NODEJS_NODEBUILD_HOME=$ASDF_NODEJS_PLUGIN_DIR/.node-build}"
|
||||
: "${ASDF_NODEJS_CONCURRENCY=$DEFAULT_CONCURRENCY}"
|
||||
|
||||
# node-build environment variables being overriden by asdf-nodejs
|
||||
export NODE_BUILD_CACHE_PATH="${NODE_BUILD_CACHE_PATH:-$ASDF_NODEJS_CACHE_DIR/node-build}"
|
||||
|
||||
if [ "$NODEJS_ORG_MIRROR" ]; then
|
||||
export NODE_BUILD_MIRROR_URL="$NODEJS_ORG_MIRROR"
|
||||
fi
|
||||
|
||||
if [[ "${ASDF_NODEJS_CONCURRENCY-}" =~ ^[0-9]+$ ]]; then
|
||||
export MAKE_OPTS="${MAKE_OPTS:-} -j$ASDF_NODEJS_CONCURRENCY"
|
||||
export NODE_MAKE_OPTS="${NODE_MAKE_OPTS:-} -j$ASDF_NODEJS_CONCURRENCY"
|
||||
fi
|
||||
|
||||
nodebuild="${ASDF_NODEJS_NODEBUILD:-$ASDF_NODEJS_NODEBUILD_HOME/bin/node-build}"
|
||||
args=()
|
||||
|
||||
if ! [ -x "$nodebuild" ]; then
|
||||
printf "Binary for node-build not found\n"
|
||||
|
||||
if ! [ "${ASDF_NODEJS_NODEBUILD-}" ]; then
|
||||
printf "Are you sure it was installed? Try running \`asdf %s update-nodebuild\` to do a local update or install\n" "$(plugin_name)"
|
||||
fi
|
||||
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${ASDF_NODEJS_VERBOSE_INSTALL-}" ]; then
|
||||
args+=(-v)
|
||||
fi
|
||||
|
||||
exec "$nodebuild" ${args+"${args[@]}"} "$@"
|
31
lib/commands/command-update-nodebuild.bash
Executable file
31
lib/commands/command-update-nodebuild.bash
Executable file
@ -0,0 +1,31 @@
|
||||
#! /usr/bin/env bash
|
||||
|
||||
set -eu -o pipefail
|
||||
|
||||
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/../utils.sh"
|
||||
|
||||
: "${ASDF_NODEJS_NODEBUILD_HOME=$ASDF_NODEJS_PLUGIN_DIR/.node-build}"
|
||||
: "${ASDF_NODEJS_NODEBUILD_REPOSITORY=https://github.com/nodenv/node-build.git}"
|
||||
|
||||
ensure_updated_project() {
|
||||
local pull_exit_code=0 output=
|
||||
|
||||
if ! [ -d "$ASDF_NODEJS_NODEBUILD_HOME" ]; then
|
||||
printf "Cloning node-build...\n"
|
||||
git clone "$ASDF_NODEJS_NODEBUILD_REPOSITORY" "$ASDF_NODEJS_NODEBUILD_HOME"
|
||||
else
|
||||
printf "Trying to update node-build..."
|
||||
output=$(git -C "$ASDF_NODEJS_NODEBUILD_HOME" pull origin master 2>&1) || pull_exit_code=$?
|
||||
|
||||
if [ "$pull_exit_code" != 0 ]; then
|
||||
printf "\n%s\n\n" "$output" >&2
|
||||
printf "$(colored $RED ERROR): Pulling the node-build repository exited with code %s\n" "$pull_exit_code" >&2
|
||||
printf "Please check if the git repository at %s doesn't have any changes or anything\nthat might not allow a git pull\n" "$ASDF_NODEJS_NODEBUILD_HOME" >&2
|
||||
exit $pull_exit_code
|
||||
fi
|
||||
|
||||
printf " ok\n"
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_updated_project
|
18
lib/utils.sh
18
lib/utils.sh
@ -8,17 +8,25 @@ then
|
||||
NODEJS_ORG_MIRROR=$NODEJS_ORG_MIRROR/
|
||||
fi
|
||||
|
||||
ASDF_NODEJS_KEYRING=asdf-nodejs.gpg
|
||||
export ASDF_NODEJS_PLUGIN_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
||||
|
||||
ASDF_NODEJS_PLUGIN_NAME="$(basename "$(dirname "$(dirname "$0")")")"
|
||||
# TODO: Replace with an asdf variable once asdf starts providing the plugin name
|
||||
# as a variable
|
||||
export ASDF_NODEJS_PLUGIN_NAME=$(basename "$ASDF_NODEJS_PLUGIN_DIR")
|
||||
plugin_name() {
|
||||
printf "%s\n" "$ASDF_NODEJS_PLUGIN_NAME"
|
||||
}
|
||||
|
||||
ASDF_DIR="${ASDF_DIR:-$HOME/.asdf}"
|
||||
export ASDF_NODEJS_PLUGIN_NAME ASDF_DIR
|
||||
export ASDF_NODEJS_CACHE_DIR="${ASDF_DATA_DIR:-${ASDF_DIR:-$HOME/.asdf}}/tmp/$ASDF_NODEJS_PLUGIN_NAME/cache"
|
||||
export ASDF_DIR="${ASDF_DIR:-$HOME/.asdf}"
|
||||
|
||||
# Colors
|
||||
colored() {
|
||||
local color="$1" text="$2"
|
||||
printf "\033[%sm%s\033[39;49m\n" "$color" "$text"
|
||||
}
|
||||
|
||||
export RED=31 GREEN=32 YELLOW=33 BLUE=34 MAGENTA=35 CYAN=36
|
||||
|
||||
die() {
|
||||
>&2 echo "$@"
|
||||
@ -61,7 +69,7 @@ filter_version_candidates() {
|
||||
done
|
||||
}
|
||||
|
||||
versions_cache_dir="${ASDF_DATA_DIR:-${ASDF_HOME:-$HOME/.asdf}}/tmp/$(plugin_name)/cache"
|
||||
versions_cache_dir="$ASDF_NODEJS_CACHE_DIR/versions-tab"
|
||||
mkdir -p "$versions_cache_dir"
|
||||
|
||||
etag_file="$versions_cache_dir/etag"
|
||||
|
Loading…
Reference in New Issue
Block a user