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

Add package-json subcommand #50

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions bin/JSON.sh
1 change: 1 addition & 0 deletions bin/nodenv-package-json
26 changes: 0 additions & 26 deletions bin/plugin_root

This file was deleted.

1 change: 1 addition & 0 deletions bin/semver.sh
17 changes: 8 additions & 9 deletions etc/nodenv.d/version-name/package-json-engine.bash
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
#!/bin/bash

# shellcheck source=libexec/nodenv-package-json-engine
source "$(plugin_root)/libexec/nodenv-package-json-engine"
if [ -n "$(nodenv-sh-shell 2>/dev/null)" ] ||
[ -n "$(nodenv-local 2>/dev/null)" ]; then
return
fi

if ! NODENV_PACKAGE_JSON_VERSION=$(get_version_respecting_precedence); then
echo "package-json-engine: version satisfying \`$(get_expression_respecting_precedence)' not installed" >&2
exit 1
elif [ -n "$NODENV_PACKAGE_JSON_VERSION" ]; then
export NODENV_VERSION="${NODENV_PACKAGE_JSON_VERSION}"
if NODENV_PACKAGE_JSON_VERSION=$(nodenv-package-json 2>/dev/null) &&
[ -n "$NODENV_PACKAGE_JSON_VERSION" ]; then
# shellcheck disable=2034
NODENV_VERSION=$NODENV_PACKAGE_JSON_VERSION
fi
36 changes: 30 additions & 6 deletions etc/nodenv.d/version-origin/package-json-engine.bash
Original file line number Diff line number Diff line change
@@ -1,9 +1,33 @@
#!/bin/bash
if [ -n "$(nodenv-sh-shell 2>/dev/null)" ] ||
[ -n "$(nodenv-local 2>/dev/null)" ]; then
return
fi

READLINK=$(type -p greadlink readlink | head -1)
[ -n "$READLINK" ] || return 1

abs_dirname() {
local cwd="$PWD"
local path="$1"

while [ -n "$path" ]; do
cd "${path%/*}" || return 1
local name="${path##*/}"
path="$($READLINK "$name" || true)"
done

pwd
cd "$cwd" || return 1
}

bin_path="$(abs_dirname "${BASH_SOURCE[0]}")/../../../libexec"

# shellcheck source=libexec/nodenv-package-json-engine
source "$(plugin_root)/libexec/nodenv-package-json-engine"
[ -d "$bin_path" ] || return 1

ENGINES_EXPRESSION=$(get_expression_respecting_precedence);
if [ -n "$ENGINES_EXPRESSION" ]; then
export NODENV_VERSION_ORIGIN="package-json-engine matching $ENGINES_EXPRESSION"
if NODENV_PACKAGE_JSON_VERSION=$(nodenv-package-json 2>/dev/null) &&
[ -n "$NODENV_PACKAGE_JSON_VERSION" ]; then
NODENV_PACKAGE_JSON_FILE=$("$bin_path/nodenv-package-json-file")
NODENV_PACKAGE_JSON_SPEC=$("$bin_path/nodenv-package-json-file-read" "$NODENV_PACKAGE_JSON_FILE")
# shellcheck disable=2034
NODENV_VERSION_ORIGIN="satisfying \`$NODENV_PACKAGE_JSON_SPEC' from $NODENV_PACKAGE_JSON_FILE#engines.node"
fi
77 changes: 77 additions & 0 deletions libexec/nodenv-package-json
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#!/usr/bin/env bash
#
# Usage: nodenv package-json
# Summary: Show the local application-specific Node version from package.json
#
# Shows the highest-installed node version satisfying package.json#engines.
#

set -e
[ -n "$NODENV_DEBUG" ] && set -x

abort() {
echo "package-json-engine: $1" >&2
exit 1
}

READLINK=$(type -p greadlink readlink | head -1)
[ -n "$READLINK" ] || abort "cannot find readlink - are you missing GNU coreutils?"

abs_dirname() {
local cwd="$PWD"
local path="$1"

while [ -n "$path" ]; do
cd "${path%/*}"
local name="${path##*/}"
path="$($READLINK "$name" || true)"
done

pwd
cd "$cwd"
}

bin_path="$(abs_dirname "$0")"

matching_version() {
local version_spec=$1
local -a installed_versions
while IFS= read -r v; do
installed_versions+=( "$v" )
done < <(nodenv versions --bare --skip-aliases | grep -e '^[[:digit:]]')

local fast_guess
fast_guess=$(semver.sh -r "$version_spec" "${installed_versions[@]:${#installed_versions[@]}-1}" | tail -n 1)

# Most #engine version specs just specify a baseline version,
# which means most likely, the highest installed version will satisfy
# This does a first pass with just that single version in hopes it satisfies.
# If so, we can avoid the cost of sh-semver sorting and validating across
# all the installed versions.
if [ -n "$fast_guess" ]; then
echo "$fast_guess"
return 0
fi

local match
match=$(semver.sh -r "$version_spec" "${installed_versions[@]}" | tail -n 1)

if [ -n "$match" ]; then
echo "$match"
else
return 1
fi
}


if ! NODENV_PACKAGE_JSON_FILE="$("$bin_path/nodenv-package-json-file")"; then
abort "no package.json found for this directory"
fi

if ! version_spec="$("$bin_path/nodenv-package-json-file-read" "$NODENV_PACKAGE_JSON_FILE")"; then
abort "no engine version configured for this package"
fi

if ! matching_version "$version_spec"; then
abort "no version found satisfying \`$version_spec'"
fi
97 changes: 0 additions & 97 deletions libexec/nodenv-package-json-engine

This file was deleted.

37 changes: 37 additions & 0 deletions libexec/nodenv-package-json-file
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/usr/bin/env bash
#
# Usage: package-file [<dir>]
# Summary: Detect the package.json that sets the current nodenv version
# Options:
# <dir> Directory from which to find package.json
# [default: ${NODENV_DIR:-PWD}]

set -e
[ -n "$NODENV_DEBUG" ] && set -x

target_dir="$1"

find_package_json() {
local package_json root="$1"
while ! [[ "$root" =~ ^//[^/]*$ ]]; do
package_json="$root/package.json"

if [ -f "$package_json" ] &&
[ -r "$package_json" ] &&
[ -s "$package_json" ]; then
echo "$package_json"
return 0
fi
[ -n "$root" ] || break
root="${root%/*}"
done
return 1
}

if [ -n "$target_dir" ]; then
find_package_json "$target_dir"
else
find_package_json "$NODENV_DIR" || {
[ "$NODENV_DIR" != "$PWD" ] && find_package_json "$PWD"
}
fi
26 changes: 26 additions & 0 deletions libexec/nodenv-package-json-file-read
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env bash
# Usage: nodenv package-json-file-read <file>
#
# Summary: Show the engines version-spec from package.json
# Options:
# <file> Package.json file to read from
#

set -e
[ -n "$NODENV_DEBUG" ] && set -x

PACKAGE_JSON_FILE=$1

[ -f "$PACKAGE_JSON_FILE" ] || exit 1

extract_expression() {
local version_regex='\["engines","node"\][[:space:]]*"([^"]*)"'
# -b -n gives minimal output - see https://github.com/dominictarr/JSON.sh#options
if [[ $(JSON.sh -b -n 2>/dev/null) =~ $version_regex ]]; then
echo "${BASH_REMATCH[1]}"
else
return 1
fi
}

extract_expression < "$PACKAGE_JSON_FILE"
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@
"bugs": {
"url": "https://github.com/nodenv/nodenv-package-json-engine/issues"
},
"bin": "libexec/nodenv-package-json",
"directories": {
"bin": "bin",
"test": "test"
@@ -25,7 +26,7 @@
"libexec"
],
"scripts": {
"lint": "git ls-files bin etc libexec test/*.bash | xargs shellcheck",
"lint": "git ls-files etc libexec test/*.bash | xargs shellcheck",
"test": "bats ${CI:+--tap} test",
"posttest": "npm run lint",
"postversion": "npm publish",
Loading