asdf-nodejs/shims/npm
2021-12-24 00:55:29 -03:00

153 lines
3.6 KiB
Bash
Executable File

#! /usr/bin/env bash
set -eu
set -o pipefail
# This script wraps npm so to run `asdf reshim` after global installs and uninstalls
# Any other cases are passed-through to npm
this_dir=$(dirname "${BASH_SOURCE[0]}")
plugin_name=$(basename "$(dirname "$this_dir")")
this_dir=$(cd "$this_dir" && pwd -P) # Normalizes the directory
asdf_data_dir=$(cd "${ASDF_DATA_DIR:-$HOME/.asdf}" && pwd -P)
asdf_shims_dir="$asdf_data_dir/shims"
plugin_dir="$asdf_data_dir/plugins/$plugin_name"
should_reshim() {
if [ "${ASDF_SKIP_RESHIM:-}" ]; then
return 1
fi
local is_global= cmd= cmd_needs_reshim=
local additional_bare_cmds=()
for arg; do
case "$arg" in
-g|--global)
is_global=true
;;
-*) ;; # Skip other options
*)
if ! [ "$cmd" ]; then
cmd="$arg"
else
additional_bare_cmds+=("$arg")
fi
;;
esac
done
case "$cmd" in
# npm install aliases
install|i|in|ins|inst|insta|instal|isnt|isnta|isntal|add)
cmd_needs_reshim=true
;;
# npm uninstall aliases
uninstall|un|unlink|remove|rm|r)
cmd_needs_reshim=true
;;
link|ln)
# Bare link installs a global package
if ! [ "${additional_bare_cmds[0]-}" ]; then
is_global=1
cmd_needs_reshim=true
fi
# Links to directories also install a global package
if [[ "${additional_bare_cmds[0]-}" =~ [./].* && -d "${additional_bare_cmds[0]-}" ]]; then
is_global=1
cmd_needs_reshim=true
fi
;;
esac
# Implicit return
[ "$is_global" ] && [ "$cmd_needs_reshim" ]
}
resolve_canon_npm() {
local npm_location=
# Try searching in current path (asdf core from 0.7 onwards adds all binaries candidates directories to PATH)
# if that doesn't works (when calling the shim directly for example) it tries manually searching the binary in
# the installed version provided by "asdf where"
npm_location="${ASDF_NODEJS_CANON_NPM_PATH:-$(search_npm_on_current_path || manually_search_npm_bin)}"
if ! [ "$npm_location" ]; then
printf "asdf-nodejs couldn't find a suitable npm executable\n"
printf "This is probably a problem with the plugin, please report this issue at https://github.com/asdf-vm/asdf-nodejs/issues\n"
exit 1
fi
printf "%s\n" "$npm_location"
}
remove_current_dir_from_path() {
local filtered_path= dir= normalized_dir=
while read -rd : dir; do
if [ -d "$dir" ]; then
normalized_dir=$(cd "$dir" && pwd -P)
if [ "$normalized_dir" = "$this_dir" ] || [ "$normalized_dir" = "$asdf_shims_dir" ]; then
continue
fi
fi
filtered_path+="$dir:"
done <<< "$PATH:"
printf "%s\n" "${filtered_path%:}"
}
search_npm_on_current_path() {
local filtered_path=
# Tries to prevent recursion by removing the current script and asdf-shim from PATH
filtered_path=$(remove_current_dir_from_path)
PATH="$filtered_path" command -v npm
}
manually_search_npm_bin() {
local installed_dir= bin_directories=
installed_dir=$(asdf where nodejs)
bin_directories=(bin)
if [ -x "$plugin_dir/bin/list-bin-paths" ]; then
bin_directories=($("$plugin_dir/bin/list-bin-paths"))
fi
for bin_dir in "${bin_directories[@]}"; do
if [ -x "$installed_dir/$bin_dir/npm" ]; then
printf "%s\n" "$installed_dir/$bin_dir/npm"
return 0
fi
done
return 1
}
wrap_npm_if_reshim_is_needed() {
local npm=
npm=$(resolve_canon_npm)
if should_reshim "$@"; then
"$npm" "$@"
printf "Reshimming asdf %s...\n" "$plugin_name" >&2
asdf reshim "$plugin_name"
else
exec "$npm" "$@"
fi
}
wrap_npm_if_reshim_is_needed "$@"