├── .editorconfig ├── .github ├── dependabot.yml └── workflows │ ├── release.yml │ ├── sync-default-branch.yml │ └── test.yml ├── .gitignore ├── LICENSE ├── README.md ├── bin ├── nodenv-doctor └── nodenv-installer ├── package-lock.json ├── package.json └── test ├── doctor.bats └── test_helper.bash /.editorconfig: -------------------------------------------------------------------------------- 1 | # https://EditorConfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | insert_final_newline = true 8 | indent_size = 2 9 | indent_style = space 10 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 2 | 3 | version: 2 4 | updates: 5 | - package-ecosystem: github-actions 6 | directory: "/" 7 | schedule: { interval: weekly } 8 | - package-ecosystem: npm 9 | directory: "/" 10 | schedule: { interval: weekly } 11 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | push: { tags: "v[0-9]+.[0-9]+.[0-9]+*" } 4 | workflow_dispatch: 5 | permissions: {contents: read} 6 | 7 | jobs: 8 | release: 9 | permissions: {contents: write} 10 | uses: nodenv/.github/.github/workflows/release.yml@v4 11 | with: 12 | homebrew: false 13 | -------------------------------------------------------------------------------- /.github/workflows/sync-default-branch.yml: -------------------------------------------------------------------------------- 1 | # This workflow keeps the master branch in sync with main, 2 | # after main has been selected as the default branch for the repository. 3 | # This way users that cloned prior to the switch-over can continue to pull; 4 | # but any new clones will have main as the default branch. 5 | # 6 | # The following commands should be run by users that have an old clone, 7 | # and want to switch over to main as the default branch: 8 | # 9 | # ```console 10 | # git branch -m master main 11 | # git fetch origin 12 | # git branch -u origin/main main 13 | # git remote set-head origin -a 14 | # ``` 15 | 16 | name: Sync Default Branch 17 | on: 18 | push: { branches: main } 19 | workflow_dispatch: 20 | permissions: read-all 21 | 22 | jobs: 23 | sync: 24 | uses: nodenv/.github/.github/workflows/sync-default-branch.yml@v5 25 | permissions: { contents: write } 26 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | on: 3 | pull_request: 4 | push: {branches: main} 5 | schedule: [{cron: '0 0 10 * *'}] # monthly https://crontab.guru/#0_0_10_*_* 6 | workflow_dispatch: 7 | permissions: {contents: read} 8 | 9 | jobs: 10 | test: 11 | uses: nodenv/.github/.github/workflows/test.yml@v4 12 | permissions: 13 | contents: read 14 | packages: read 15 | id-token: write 16 | security-events: write 17 | statuses: write 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /nodenv-nodenv-installer-*.tgz 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nodenv installer & doctor scripts 2 | 3 | 4 | 5 | - [nodenv-installer](#nodenv-installer) 6 | - [nodenv-doctor](#nodenv-doctor) 7 | - [Credits](#credits) 8 | 9 | 10 | 11 | ## nodenv-installer 12 | 13 | The `nodenv-installer` script idempotently installs or updates nodenv on your 14 | system. If Homebrew is detected, installation will proceed using `brew 15 | install/upgrade`. Otherwise, nodenv is installed under `~/.nodenv`. 16 | 17 | Additionally, [node-build](https://github.com/nodenv/node-build#readme) is also 18 | installed if `nodenv install` is not already available. 19 | 20 | with curl: 21 | 22 | ```sh 23 | curl -fsSL https://github.com/nodenv/nodenv-installer/raw/HEAD/bin/nodenv-installer | bash 24 | ``` 25 | 26 | with wget: 27 | 28 | ```sh 29 | wget -q https://github.com/nodenv/nodenv-installer/raw/HEAD/bin/nodenv-installer -O- | bash 30 | ``` 31 | 32 | with npx/npm: 33 | 34 | ```sh 35 | npx @nodenv/nodenv-installer 36 | ``` 37 | 38 | The installer script is meant for casual use on your own development machine. 39 | For automating installation across machines it's better to _avoid_ using this 40 | script in favor of fine-tuning nodenv & node-build installation manually. Some 41 | environments—such as container images meant for either Node development or 42 | production—should not be switching between multiple Node versions at all, so if 43 | you are installing nodenv there, you are likely doing something wrong. 44 | 45 | ## nodenv-doctor 46 | 47 | You can verify the state of your nodenv installation with: 48 | 49 | with curl: 50 | 51 | ```sh 52 | curl -fsSL https://github.com/nodenv/nodenv-installer/raw/HEAD/bin/nodenv-doctor | bash 53 | ``` 54 | 55 | with wget: 56 | 57 | ```sh 58 | wget -q https://github.com/nodenv/nodenv-installer/raw/HEAD/bin/nodenv-doctor -O- | bash 59 | ``` 60 | 61 | with npx/npm: 62 | 63 | ```sh 64 | npx -p @nodenv/nodenv-installer nodenv-doctor 65 | ``` 66 | 67 | ## Credits 68 | 69 | Forked from [Mislav Marohnić][mislav]'s [rbenv-installer][] and modified for node. 70 | 71 | [mislav]: https://github.com/mislav 72 | [rbenv-installer]: https://github.com/rbenv/rbenv-installer 73 | -------------------------------------------------------------------------------- /bin/nodenv-doctor: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Usage: nodenv doctor 3 | # Summary: Detects common problems in nodenv installation 4 | 5 | set -e 6 | [ -n "$NODENV_DEBUG" ] && { export PS4='+ [${BASH_SOURCE##*/}:${LINENO}] '; set -x; } 7 | 8 | count-lines() { 9 | printf "%d" "$(wc -l)" 10 | } 11 | 12 | command-list() { 13 | # shellcheck disable=SC2230 14 | which -a "$1" 15 | } 16 | 17 | indent() { 18 | sed 's/^/ /' 19 | } 20 | 21 | # for ubuntu /bin is a symlink to /usr/bin 22 | # which -a doesn't know the binaries are the same 23 | fix-usr-bin() { 24 | sed 's:^/usr/bin/:/bin/:' 25 | } 26 | 27 | printc() { 28 | local color_name="color_$1" 29 | local msg="$2" 30 | printf "%s%s%s" "${!color_name}" "$msg" "$color_reset" 31 | } 32 | 33 | if [ -t 1 ]; then 34 | # shellcheck disable=SC2034 35 | color_red=$'\e[31m' 36 | # shellcheck disable=SC2034 37 | color_green=$'\e[32m' 38 | # shellcheck disable=SC2034 39 | color_yellow=$'\e[1;33m' 40 | # shellcheck disable=SC2034 41 | color_bright=$'\e[1;37m' 42 | color_reset=$'\e[0m' 43 | else 44 | # shellcheck disable=SC2034 45 | color_red="" 46 | # shellcheck disable=SC2034 47 | color_green="" 48 | # shellcheck disable=SC2034 49 | color_yellow="" 50 | # shellcheck disable=SC2034 51 | color_bright="" 52 | # shellcheck disable=SC2034 53 | color_reset="" 54 | fi 55 | 56 | warnings=0 57 | 58 | echo -n "Checking for \`nodenv' in PATH: " 59 | num_locations="$(command-list nodenv | fix-usr-bin | uniq | count-lines)" 60 | if [ "$num_locations" -eq 0 ]; then 61 | printc red "not found" 62 | echo 63 | { if [ -x "$HOME/.nodenv/bin/nodenv" ] || [ -x "${NODENV_ROOT:-}/bin/nodenv" ]; then 64 | [ -x "$HOME/.nodenv/bin/nodenv" ] && 65 | echo "You seem to have nodenv installed in \`$HOME/.nodenv/bin'," 66 | [ -x "${NODENV_ROOT:-}/bin/nodenv" ] && 67 | echo "You seem to have nodenv installed in \`$NODENV_ROOT/bin'," 68 | echo "but that directory is not present in PATH." 69 | echo "Please add it to PATH by configuring your shell initialization files." 70 | else 71 | echo "Please refer to https://github.com/nodenv/nodenv#installation" 72 | fi 73 | } | indent 74 | 75 | if [ -n "$(find "${NODENV_ROOT:-~/.nodenv}/bin/nodenv" -mmin 1 2>/dev/null)" ]; then 76 | printc bright "Recent installation detected.\n" 77 | { echo "Complete the installation by configuring your PATH as above," 78 | echo "and re-run nodenv-doctor in a fresh shell." 79 | } | indent 80 | exit 0 81 | fi 82 | 83 | exit 1 84 | elif [ "$num_locations" -eq 1 ]; then 85 | printc green "$(command -v nodenv)" 86 | echo 87 | else 88 | printc yellow "multiple" 89 | echo 90 | { echo "You seem to have multiple nodenv installs in the following locations." 91 | echo "Please pick just one installation and remove the others." 92 | echo 93 | command-list nodenv 94 | } | indent 95 | echo 96 | : $((warnings++)) 97 | fi 98 | 99 | NODENV_ROOT="${NODENV_ROOT:-$(nodenv root)}" 100 | 101 | echo -n "Checking for nodenv shims in PATH: " 102 | shims_dir="${NODENV_ROOT}/shims" 103 | found="" 104 | precedence_problem="" 105 | IFS=: read -r -a path <<<"$PATH" || true 106 | for dir in "${path[@]}"; do 107 | if [ "$dir" = "$shims_dir" ]; then 108 | found=true 109 | elif [ -x "$dir"/node ] && [ -z "$found" ]; then 110 | precedence_problem="$dir" 111 | fi 112 | done 113 | if [ -n "$found" ]; then 114 | if [ -n "$precedence_problem" ]; then 115 | printc yellow "found at wrong position" 116 | echo 117 | { echo "The directory \`$shims_dir' is present in PATH, but is listed too late." 118 | echo "The Node version found in \`$precedence_problem' will have precedence. Please reorder your PATH." 119 | } | indent 120 | echo 121 | : $((warnings++)) 122 | else 123 | printc green "OK" 124 | echo 125 | fi 126 | else 127 | printc red "not found" 128 | echo 129 | { echo "The directory \`$shims_dir' must be present in PATH for nodenv to work." 130 | echo "Please run \`nodenv init' and follow the instructions." 131 | } | indent 132 | echo 133 | : $((warnings++)) 134 | fi 135 | 136 | echo -n "Checking \`nodenv install' support: " 137 | nodenv_installs="$({ ls "$NODENV_ROOT"/plugins/*/bin/nodenv-install 2>/dev/null || true 138 | command-list nodenv-install 2>/dev/null || true 139 | } | uniq)" 140 | num_installs="$(count-lines <<<"$nodenv_installs")" 141 | if [ -z "$nodenv_installs" ]; then 142 | printc red "not found" 143 | echo 144 | { echo "Unless you plan to add Node versions manually, you should install node-build." 145 | echo "Please refer to https://github.com/nodenv/node-build#installation" 146 | } 147 | echo 148 | : $((warnings++)) 149 | elif [ "$num_installs" -eq 1 ]; then 150 | printc green "$nodenv_installs" 151 | if [[ $nodenv_installs == "$NODENV_ROOT"/plugins/* ]]; then 152 | nodenv_install_cmd="${nodenv_installs##*/}" 153 | nodenv_install_version="$(nodenv "${nodenv_install_cmd#nodenv-}" --version || true)" 154 | else 155 | nodenv_install_version="$("$nodenv_installs" --version || true)" 156 | fi 157 | printf " (%s)\n" "$nodenv_install_version" 158 | else 159 | printc yellow "multiple" 160 | echo 161 | { echo "You seem to have multiple \`nodenv-install' in the following locations." 162 | echo "Please pick just one installation and remove the others." 163 | echo 164 | echo "$nodenv_installs" 165 | } | indent 166 | echo 167 | : $((warnings++)) 168 | fi 169 | 170 | echo -n "Counting installed Node versions: " 171 | num_nodes="$(nodenv versions --bare | count-lines)" 172 | if [ "$num_nodes" -eq 0 ]; then 173 | printc yellow "none" 174 | echo 175 | echo "There aren't any Node versions installed under \`$NODENV_ROOT/versions'." | indent 176 | [ "$num_installs" -eq 0 ] || { 177 | latest_version="$(nodenv install -l 2>/dev/null | grep -vFe - | tail -1)" 178 | [ -n "$latest_version" ] || latest_version="" 179 | echo -n "You can install Node versions like so: " 180 | printc bright "nodenv install $latest_version" 181 | echo 182 | } | indent 183 | else 184 | printc green "$num_nodes versions" 185 | echo 186 | fi 187 | 188 | echo -n "Auditing installed plugins: " 189 | hooks_list="$(nodenv hooks exec || true)" 190 | IFS=$'\n' read -r -d '' -a hooks <<<"$hooks_list" || true 191 | plugin_broken=0 192 | for hook in "${hooks[@]}"; do 193 | plugin_name= 194 | message= 195 | 196 | if [ -n "$plugin_name" ]; then 197 | if [ "$((plugin_broken++))" -eq 0 ]; then 198 | printc yellow "warning" 199 | echo 200 | fi 201 | { printc bright "$plugin_name" 202 | echo " $message" 203 | echo " (found in \`${hook}')" 204 | } | indent 205 | : $((warnings++)) 206 | fi 207 | done 208 | if [ "$plugin_broken" -eq 0 ]; then 209 | printc green "OK" 210 | echo 211 | fi 212 | 213 | if [ "$warnings" -gt 0 ]; then 214 | exit 1 215 | fi 216 | -------------------------------------------------------------------------------- /bin/nodenv-installer: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | [ -n "$NODENV_DEBUG" ] && { export PS4='+ [${BASH_SOURCE##*/}:${LINENO}] '; set -x; } 5 | 6 | homebrew= 7 | type -p brew >/dev/null && homebrew=1 8 | 9 | if ! type -p git >/dev/null; then 10 | git() { 11 | echo "Error: git is required to proceed. Please install git and try again." >&2 12 | exit 1 13 | } 14 | fi 15 | 16 | nodenv="$(command -v nodenv ~/.nodenv/bin/nodenv | head -1)" 17 | 18 | if [ -n "$nodenv" ]; then 19 | echo "nodenv already seems installed in \`$nodenv'." 20 | cd "${nodenv%/*}" 21 | 22 | if [ -x ./brew ]; then 23 | echo "Trying to update with Homebrew..." 24 | brew update >/dev/null 25 | if brew list nodenv | grep -q nodenv/HEAD; then 26 | brew reinstall nodenv 27 | else 28 | brew upgrade nodenv 29 | fi 30 | elif git remote -v 2>/dev/null | grep -q nodenv; then 31 | echo "Trying to update with git..." 32 | git pull --tags origin master 33 | cd .. 34 | fi 35 | else 36 | if [ -n "$homebrew" ]; then 37 | echo "Installing nodenv with Homebrew..." 38 | brew update 39 | brew install nodenv 40 | nodenv="$(brew --prefix)/bin/nodenv" 41 | else 42 | echo "Installing nodenv with git..." 43 | mkdir -p ~/.nodenv 44 | cd ~/.nodenv 45 | git init 46 | git remote add -f -t master origin https://github.com/nodenv/nodenv.git 47 | git checkout -b master origin/master 48 | nodenv=~/.nodenv/bin/nodenv 49 | 50 | if [ ! -e versions ] && [ -w /opt/rubies ]; then 51 | ln -s /opt/rubies versions 52 | fi 53 | fi 54 | fi 55 | 56 | nodenv_root="$("$nodenv" root)" 57 | node_build="$(command -v "$nodenv_root"/plugins/*/bin/nodenv-install nodenv-install | head -1)" 58 | 59 | echo 60 | if [ -n "$node_build" ]; then 61 | echo "\`nodenv install' command already available in \`$node_build'." 62 | cd "${node_build%/*}" 63 | 64 | if [ -x ./brew ]; then 65 | echo "Trying to update with Homebrew..." 66 | brew update >/dev/null 67 | brew upgrade node-build 68 | elif git remote -v 2>/dev/null | grep -q node-build; then 69 | echo "Trying to update with git..." 70 | git pull origin master 71 | fi 72 | else 73 | if [ -n "$homebrew" ]; then 74 | echo "Installing node-build with Homebrew..." 75 | brew update 76 | brew install node-build 77 | else 78 | echo "Installing node-build with git..." 79 | mkdir -p "${nodenv_root}/plugins" 80 | git clone https://github.com/nodenv/node-build.git "${nodenv_root}/plugins/node-build" 81 | fi 82 | fi 83 | 84 | # Enable caching of nodenv-install downloads 85 | mkdir -p "${nodenv_root}/cache" 86 | 87 | echo 88 | echo "All done!" 89 | echo "Note that this installer does NOT edit your shell configuration files:" 90 | i=0 91 | nodenv_command="nodenv" 92 | if [ -x ~/.nodenv/bin ]; then 93 | # shellcheck disable=SC2088 94 | nodenv_command='~/.nodenv/bin/nodenv' 95 | fi 96 | echo "$((++i)). Run \`$nodenv_command init' to view instructions on how to configure nodenv for your shell." 97 | echo "$((++i)). Launch a new terminal window after editing shell configuration files." 98 | 99 | url="https://github.com/nodenv/nodenv-installer/raw/HEAD/bin/nodenv-doctor" 100 | if false && type -p curl >/dev/null; then 101 | echo "$((++i)). (Optional) Run the doctor command to verify the installation:" 102 | printf ' curl -fsSL "%s" | bash\n' "$url" 103 | elif type -p wget >/dev/null; then 104 | echo "$((++i)). (Optional) Run the doctor command to verify the installation:" 105 | printf ' wget -q "%s" -O- | bash\n' "$url" 106 | fi 107 | echo 108 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nodenv/nodenv-installer", 3 | "version": "2.0.1", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "@nodenv/nodenv-installer", 9 | "version": "2.0.1", 10 | "devDependencies": { 11 | "@nodenv/nodenv": "^1", 12 | "bats": "^1", 13 | "bats-assert": "github:bats-core/bats-assert", 14 | "bats-support": "github:bats-core/bats-support", 15 | "shellcheck": "^2" 16 | } 17 | }, 18 | "node_modules/@nodenv/nodenv": { 19 | "version": "1.5.0", 20 | "resolved": "https://registry.npmjs.org/@nodenv/nodenv/-/nodenv-1.5.0.tgz", 21 | "integrity": "sha512-/gxxII3r0SR+FjpWVqxmWsYTTRUldQPcvU5AHgKt/v/xjpg+q88Lk1zyuGTA5PrEOWTW/d01JDfHyHMnPtSjdQ==", 22 | "dev": true, 23 | "hasInstallScript": true, 24 | "bin": { 25 | "nodenv": "libexec/nodenv" 26 | } 27 | }, 28 | "node_modules/base64-js": { 29 | "version": "1.5.1", 30 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 31 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", 32 | "dev": true, 33 | "funding": [ 34 | { 35 | "type": "github", 36 | "url": "https://github.com/sponsors/feross" 37 | }, 38 | { 39 | "type": "patreon", 40 | "url": "https://www.patreon.com/feross" 41 | }, 42 | { 43 | "type": "consulting", 44 | "url": "https://feross.org/support" 45 | } 46 | ] 47 | }, 48 | "node_modules/bats": { 49 | "version": "1.11.0", 50 | "resolved": "https://registry.npmjs.org/bats/-/bats-1.11.0.tgz", 51 | "integrity": "sha512-qiKdnS4ID3bJ1MaEOKuZe12R4w+t+psJF0ICj+UdkiHBBoObPMHv8xmD3w6F4a5qwUyZUHS+413lxENBNy8xcQ==", 52 | "dev": true, 53 | "bin": { 54 | "bats": "bin/bats" 55 | } 56 | }, 57 | "node_modules/bats-assert": { 58 | "version": "2.1.0", 59 | "resolved": "git+ssh://git@github.com/bats-core/bats-assert.git#e2d855bc78619ee15b0c702b5c30fb074101159f", 60 | "integrity": "sha512-essBJNGadRCxpjrypamUSyJ2wzBnCAgvcO7/WS7VU1ZDrAxnWFSjx8hTNXZIcoGGcbps5eg3nS32prghhJO5aA==", 61 | "dev": true, 62 | "license": "CC0-1.0", 63 | "peerDependencies": { 64 | "bats": "0.4 || ^1", 65 | "bats-support": "^0.3" 66 | } 67 | }, 68 | "node_modules/bats-support": { 69 | "version": "0.3.0", 70 | "resolved": "git+ssh://git@github.com/bats-core/bats-support.git#9bf10e876dd6b624fe44423f0b35e064225f7556", 71 | "integrity": "sha512-lZueJbfb9JqaFTNZcaoj7uhAPxSRKRCe+PBA2Y1OvQEtSQjdVn4v/+QtZlKGq88krlHOA2cpOMHz7VLfwphO8A==", 72 | "dev": true, 73 | "license": "CC0-1.0", 74 | "peerDependencies": { 75 | "bats": "0.4 || ^1" 76 | } 77 | }, 78 | "node_modules/bl": { 79 | "version": "1.2.3", 80 | "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", 81 | "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", 82 | "dev": true, 83 | "dependencies": { 84 | "readable-stream": "^2.3.5", 85 | "safe-buffer": "^5.1.1" 86 | } 87 | }, 88 | "node_modules/boolean": { 89 | "version": "3.2.0", 90 | "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", 91 | "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", 92 | "dev": true 93 | }, 94 | "node_modules/buffer": { 95 | "version": "5.7.1", 96 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", 97 | "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", 98 | "dev": true, 99 | "funding": [ 100 | { 101 | "type": "github", 102 | "url": "https://github.com/sponsors/feross" 103 | }, 104 | { 105 | "type": "patreon", 106 | "url": "https://www.patreon.com/feross" 107 | }, 108 | { 109 | "type": "consulting", 110 | "url": "https://feross.org/support" 111 | } 112 | ], 113 | "dependencies": { 114 | "base64-js": "^1.3.1", 115 | "ieee754": "^1.1.13" 116 | } 117 | }, 118 | "node_modules/buffer-alloc": { 119 | "version": "1.2.0", 120 | "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", 121 | "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", 122 | "dev": true, 123 | "dependencies": { 124 | "buffer-alloc-unsafe": "^1.1.0", 125 | "buffer-fill": "^1.0.0" 126 | } 127 | }, 128 | "node_modules/buffer-alloc-unsafe": { 129 | "version": "1.1.0", 130 | "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", 131 | "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", 132 | "dev": true 133 | }, 134 | "node_modules/buffer-crc32": { 135 | "version": "0.2.13", 136 | "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", 137 | "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", 138 | "dev": true, 139 | "engines": { 140 | "node": "*" 141 | } 142 | }, 143 | "node_modules/buffer-fill": { 144 | "version": "1.0.0", 145 | "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", 146 | "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==", 147 | "dev": true 148 | }, 149 | "node_modules/commander": { 150 | "version": "2.20.3", 151 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 152 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", 153 | "dev": true 154 | }, 155 | "node_modules/core-util-is": { 156 | "version": "1.0.3", 157 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", 158 | "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", 159 | "dev": true 160 | }, 161 | "node_modules/decompress": { 162 | "version": "4.2.1", 163 | "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", 164 | "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==", 165 | "dev": true, 166 | "dependencies": { 167 | "decompress-tar": "^4.0.0", 168 | "decompress-tarbz2": "^4.0.0", 169 | "decompress-targz": "^4.0.0", 170 | "decompress-unzip": "^4.0.1", 171 | "graceful-fs": "^4.1.10", 172 | "make-dir": "^1.0.0", 173 | "pify": "^2.3.0", 174 | "strip-dirs": "^2.0.0" 175 | }, 176 | "engines": { 177 | "node": ">=4" 178 | } 179 | }, 180 | "node_modules/decompress-tar": { 181 | "version": "4.1.1", 182 | "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", 183 | "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", 184 | "dev": true, 185 | "dependencies": { 186 | "file-type": "^5.2.0", 187 | "is-stream": "^1.1.0", 188 | "tar-stream": "^1.5.2" 189 | }, 190 | "engines": { 191 | "node": ">=4" 192 | } 193 | }, 194 | "node_modules/decompress-tarbz2": { 195 | "version": "4.1.1", 196 | "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", 197 | "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", 198 | "dev": true, 199 | "dependencies": { 200 | "decompress-tar": "^4.1.0", 201 | "file-type": "^6.1.0", 202 | "is-stream": "^1.1.0", 203 | "seek-bzip": "^1.0.5", 204 | "unbzip2-stream": "^1.0.9" 205 | }, 206 | "engines": { 207 | "node": ">=4" 208 | } 209 | }, 210 | "node_modules/decompress-tarbz2/node_modules/file-type": { 211 | "version": "6.2.0", 212 | "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", 213 | "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==", 214 | "dev": true, 215 | "engines": { 216 | "node": ">=4" 217 | } 218 | }, 219 | "node_modules/decompress-targz": { 220 | "version": "4.1.1", 221 | "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", 222 | "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", 223 | "dev": true, 224 | "dependencies": { 225 | "decompress-tar": "^4.1.1", 226 | "file-type": "^5.2.0", 227 | "is-stream": "^1.1.0" 228 | }, 229 | "engines": { 230 | "node": ">=4" 231 | } 232 | }, 233 | "node_modules/decompress-unzip": { 234 | "version": "4.0.1", 235 | "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", 236 | "integrity": "sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw==", 237 | "dev": true, 238 | "dependencies": { 239 | "file-type": "^3.8.0", 240 | "get-stream": "^2.2.0", 241 | "pify": "^2.3.0", 242 | "yauzl": "^2.4.2" 243 | }, 244 | "engines": { 245 | "node": ">=4" 246 | } 247 | }, 248 | "node_modules/decompress-unzip/node_modules/file-type": { 249 | "version": "3.9.0", 250 | "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", 251 | "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==", 252 | "dev": true, 253 | "engines": { 254 | "node": ">=0.10.0" 255 | } 256 | }, 257 | "node_modules/define-properties": { 258 | "version": "1.2.0", 259 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", 260 | "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", 261 | "dev": true, 262 | "dependencies": { 263 | "has-property-descriptors": "^1.0.0", 264 | "object-keys": "^1.1.1" 265 | }, 266 | "engines": { 267 | "node": ">= 0.4" 268 | }, 269 | "funding": { 270 | "url": "https://github.com/sponsors/ljharb" 271 | } 272 | }, 273 | "node_modules/detect-node": { 274 | "version": "2.1.0", 275 | "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", 276 | "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", 277 | "dev": true 278 | }, 279 | "node_modules/end-of-stream": { 280 | "version": "1.4.4", 281 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", 282 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", 283 | "dev": true, 284 | "dependencies": { 285 | "once": "^1.4.0" 286 | } 287 | }, 288 | "node_modules/es6-error": { 289 | "version": "4.1.1", 290 | "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", 291 | "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", 292 | "dev": true 293 | }, 294 | "node_modules/escape-string-regexp": { 295 | "version": "4.0.0", 296 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 297 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 298 | "dev": true, 299 | "engines": { 300 | "node": ">=10" 301 | }, 302 | "funding": { 303 | "url": "https://github.com/sponsors/sindresorhus" 304 | } 305 | }, 306 | "node_modules/fd-slicer": { 307 | "version": "1.1.0", 308 | "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", 309 | "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", 310 | "dev": true, 311 | "dependencies": { 312 | "pend": "~1.2.0" 313 | } 314 | }, 315 | "node_modules/file-type": { 316 | "version": "5.2.0", 317 | "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", 318 | "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", 319 | "dev": true, 320 | "engines": { 321 | "node": ">=4" 322 | } 323 | }, 324 | "node_modules/fs-constants": { 325 | "version": "1.0.0", 326 | "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", 327 | "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", 328 | "dev": true 329 | }, 330 | "node_modules/function-bind": { 331 | "version": "1.1.1", 332 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 333 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 334 | "dev": true 335 | }, 336 | "node_modules/get-intrinsic": { 337 | "version": "1.2.0", 338 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", 339 | "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", 340 | "dev": true, 341 | "dependencies": { 342 | "function-bind": "^1.1.1", 343 | "has": "^1.0.3", 344 | "has-symbols": "^1.0.3" 345 | }, 346 | "funding": { 347 | "url": "https://github.com/sponsors/ljharb" 348 | } 349 | }, 350 | "node_modules/get-stream": { 351 | "version": "2.3.1", 352 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", 353 | "integrity": "sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==", 354 | "dev": true, 355 | "dependencies": { 356 | "object-assign": "^4.0.1", 357 | "pinkie-promise": "^2.0.0" 358 | }, 359 | "engines": { 360 | "node": ">=0.10.0" 361 | } 362 | }, 363 | "node_modules/global-agent": { 364 | "version": "3.0.0", 365 | "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", 366 | "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", 367 | "dev": true, 368 | "dependencies": { 369 | "boolean": "^3.0.1", 370 | "es6-error": "^4.1.1", 371 | "matcher": "^3.0.0", 372 | "roarr": "^2.15.3", 373 | "semver": "^7.3.2", 374 | "serialize-error": "^7.0.1" 375 | }, 376 | "engines": { 377 | "node": ">=10.0" 378 | } 379 | }, 380 | "node_modules/globalthis": { 381 | "version": "1.0.3", 382 | "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", 383 | "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", 384 | "dev": true, 385 | "dependencies": { 386 | "define-properties": "^1.1.3" 387 | }, 388 | "engines": { 389 | "node": ">= 0.4" 390 | }, 391 | "funding": { 392 | "url": "https://github.com/sponsors/ljharb" 393 | } 394 | }, 395 | "node_modules/graceful-fs": { 396 | "version": "4.2.10", 397 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", 398 | "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", 399 | "dev": true 400 | }, 401 | "node_modules/has": { 402 | "version": "1.0.3", 403 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 404 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 405 | "dev": true, 406 | "dependencies": { 407 | "function-bind": "^1.1.1" 408 | }, 409 | "engines": { 410 | "node": ">= 0.4.0" 411 | } 412 | }, 413 | "node_modules/has-property-descriptors": { 414 | "version": "1.0.0", 415 | "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", 416 | "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", 417 | "dev": true, 418 | "dependencies": { 419 | "get-intrinsic": "^1.1.1" 420 | }, 421 | "funding": { 422 | "url": "https://github.com/sponsors/ljharb" 423 | } 424 | }, 425 | "node_modules/has-symbols": { 426 | "version": "1.0.3", 427 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 428 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", 429 | "dev": true, 430 | "engines": { 431 | "node": ">= 0.4" 432 | }, 433 | "funding": { 434 | "url": "https://github.com/sponsors/ljharb" 435 | } 436 | }, 437 | "node_modules/ieee754": { 438 | "version": "1.2.1", 439 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", 440 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", 441 | "dev": true, 442 | "funding": [ 443 | { 444 | "type": "github", 445 | "url": "https://github.com/sponsors/feross" 446 | }, 447 | { 448 | "type": "patreon", 449 | "url": "https://www.patreon.com/feross" 450 | }, 451 | { 452 | "type": "consulting", 453 | "url": "https://feross.org/support" 454 | } 455 | ] 456 | }, 457 | "node_modules/inherits": { 458 | "version": "2.0.4", 459 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 460 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 461 | "dev": true 462 | }, 463 | "node_modules/is-natural-number": { 464 | "version": "4.0.1", 465 | "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", 466 | "integrity": "sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ==", 467 | "dev": true 468 | }, 469 | "node_modules/is-stream": { 470 | "version": "1.1.0", 471 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", 472 | "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", 473 | "dev": true, 474 | "engines": { 475 | "node": ">=0.10.0" 476 | } 477 | }, 478 | "node_modules/isarray": { 479 | "version": "1.0.0", 480 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 481 | "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", 482 | "dev": true 483 | }, 484 | "node_modules/json-stringify-safe": { 485 | "version": "5.0.1", 486 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 487 | "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", 488 | "dev": true 489 | }, 490 | "node_modules/lru-cache": { 491 | "version": "6.0.0", 492 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 493 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 494 | "dev": true, 495 | "dependencies": { 496 | "yallist": "^4.0.0" 497 | }, 498 | "engines": { 499 | "node": ">=10" 500 | } 501 | }, 502 | "node_modules/make-dir": { 503 | "version": "1.3.0", 504 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", 505 | "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", 506 | "dev": true, 507 | "dependencies": { 508 | "pify": "^3.0.0" 509 | }, 510 | "engines": { 511 | "node": ">=4" 512 | } 513 | }, 514 | "node_modules/make-dir/node_modules/pify": { 515 | "version": "3.0.0", 516 | "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", 517 | "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", 518 | "dev": true, 519 | "engines": { 520 | "node": ">=4" 521 | } 522 | }, 523 | "node_modules/matcher": { 524 | "version": "3.0.0", 525 | "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", 526 | "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", 527 | "dev": true, 528 | "dependencies": { 529 | "escape-string-regexp": "^4.0.0" 530 | }, 531 | "engines": { 532 | "node": ">=10" 533 | } 534 | }, 535 | "node_modules/object-assign": { 536 | "version": "4.1.1", 537 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 538 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", 539 | "dev": true, 540 | "engines": { 541 | "node": ">=0.10.0" 542 | } 543 | }, 544 | "node_modules/object-keys": { 545 | "version": "1.1.1", 546 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", 547 | "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", 548 | "dev": true, 549 | "engines": { 550 | "node": ">= 0.4" 551 | } 552 | }, 553 | "node_modules/once": { 554 | "version": "1.4.0", 555 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 556 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 557 | "dev": true, 558 | "dependencies": { 559 | "wrappy": "1" 560 | } 561 | }, 562 | "node_modules/pend": { 563 | "version": "1.2.0", 564 | "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", 565 | "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", 566 | "dev": true 567 | }, 568 | "node_modules/pify": { 569 | "version": "2.3.0", 570 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", 571 | "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", 572 | "dev": true, 573 | "engines": { 574 | "node": ">=0.10.0" 575 | } 576 | }, 577 | "node_modules/pinkie": { 578 | "version": "2.0.4", 579 | "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", 580 | "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", 581 | "dev": true, 582 | "engines": { 583 | "node": ">=0.10.0" 584 | } 585 | }, 586 | "node_modules/pinkie-promise": { 587 | "version": "2.0.1", 588 | "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", 589 | "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", 590 | "dev": true, 591 | "dependencies": { 592 | "pinkie": "^2.0.0" 593 | }, 594 | "engines": { 595 | "node": ">=0.10.0" 596 | } 597 | }, 598 | "node_modules/process-nextick-args": { 599 | "version": "2.0.1", 600 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 601 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", 602 | "dev": true 603 | }, 604 | "node_modules/readable-stream": { 605 | "version": "2.3.7", 606 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 607 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 608 | "dev": true, 609 | "dependencies": { 610 | "core-util-is": "~1.0.0", 611 | "inherits": "~2.0.3", 612 | "isarray": "~1.0.0", 613 | "process-nextick-args": "~2.0.0", 614 | "safe-buffer": "~5.1.1", 615 | "string_decoder": "~1.1.1", 616 | "util-deprecate": "~1.0.1" 617 | } 618 | }, 619 | "node_modules/readable-stream/node_modules/safe-buffer": { 620 | "version": "5.1.2", 621 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 622 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 623 | "dev": true 624 | }, 625 | "node_modules/roarr": { 626 | "version": "2.15.4", 627 | "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", 628 | "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", 629 | "dev": true, 630 | "dependencies": { 631 | "boolean": "^3.0.1", 632 | "detect-node": "^2.0.4", 633 | "globalthis": "^1.0.1", 634 | "json-stringify-safe": "^5.0.1", 635 | "semver-compare": "^1.0.0", 636 | "sprintf-js": "^1.1.2" 637 | }, 638 | "engines": { 639 | "node": ">=8.0" 640 | } 641 | }, 642 | "node_modules/safe-buffer": { 643 | "version": "5.2.1", 644 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 645 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 646 | "dev": true, 647 | "funding": [ 648 | { 649 | "type": "github", 650 | "url": "https://github.com/sponsors/feross" 651 | }, 652 | { 653 | "type": "patreon", 654 | "url": "https://www.patreon.com/feross" 655 | }, 656 | { 657 | "type": "consulting", 658 | "url": "https://feross.org/support" 659 | } 660 | ] 661 | }, 662 | "node_modules/seek-bzip": { 663 | "version": "1.0.6", 664 | "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz", 665 | "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==", 666 | "dev": true, 667 | "dependencies": { 668 | "commander": "^2.8.1" 669 | }, 670 | "bin": { 671 | "seek-bunzip": "bin/seek-bunzip", 672 | "seek-table": "bin/seek-bzip-table" 673 | } 674 | }, 675 | "node_modules/semver": { 676 | "version": "7.3.8", 677 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", 678 | "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", 679 | "dev": true, 680 | "dependencies": { 681 | "lru-cache": "^6.0.0" 682 | }, 683 | "bin": { 684 | "semver": "bin/semver.js" 685 | }, 686 | "engines": { 687 | "node": ">=10" 688 | } 689 | }, 690 | "node_modules/semver-compare": { 691 | "version": "1.0.0", 692 | "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", 693 | "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", 694 | "dev": true 695 | }, 696 | "node_modules/serialize-error": { 697 | "version": "7.0.1", 698 | "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", 699 | "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", 700 | "dev": true, 701 | "dependencies": { 702 | "type-fest": "^0.13.1" 703 | }, 704 | "engines": { 705 | "node": ">=10" 706 | }, 707 | "funding": { 708 | "url": "https://github.com/sponsors/sindresorhus" 709 | } 710 | }, 711 | "node_modules/shellcheck": { 712 | "version": "2.2.0", 713 | "resolved": "https://registry.npmjs.org/shellcheck/-/shellcheck-2.2.0.tgz", 714 | "integrity": "sha512-rMt0WhmeqRrKMUqyTlkL6pd0zY27FRQMQWjQhpHMQETwG2ykc8gz+QGGtxHym4R2np646QgQAcq04sAEo3SWhA==", 715 | "dev": true, 716 | "dependencies": { 717 | "decompress": "^4.2.1", 718 | "global-agent": "^3.0.0" 719 | }, 720 | "bin": { 721 | "shellcheck": "bin/shellcheck.js" 722 | }, 723 | "engines": { 724 | "node": ">=18.4.0 || >=16.17.0" 725 | } 726 | }, 727 | "node_modules/sprintf-js": { 728 | "version": "1.1.2", 729 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", 730 | "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", 731 | "dev": true 732 | }, 733 | "node_modules/string_decoder": { 734 | "version": "1.1.1", 735 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 736 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 737 | "dev": true, 738 | "dependencies": { 739 | "safe-buffer": "~5.1.0" 740 | } 741 | }, 742 | "node_modules/string_decoder/node_modules/safe-buffer": { 743 | "version": "5.1.2", 744 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 745 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 746 | "dev": true 747 | }, 748 | "node_modules/strip-dirs": { 749 | "version": "2.1.0", 750 | "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", 751 | "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", 752 | "dev": true, 753 | "dependencies": { 754 | "is-natural-number": "^4.0.1" 755 | } 756 | }, 757 | "node_modules/tar-stream": { 758 | "version": "1.6.2", 759 | "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", 760 | "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", 761 | "dev": true, 762 | "dependencies": { 763 | "bl": "^1.0.0", 764 | "buffer-alloc": "^1.2.0", 765 | "end-of-stream": "^1.0.0", 766 | "fs-constants": "^1.0.0", 767 | "readable-stream": "^2.3.0", 768 | "to-buffer": "^1.1.1", 769 | "xtend": "^4.0.0" 770 | }, 771 | "engines": { 772 | "node": ">= 0.8.0" 773 | } 774 | }, 775 | "node_modules/through": { 776 | "version": "2.3.8", 777 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 778 | "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", 779 | "dev": true 780 | }, 781 | "node_modules/to-buffer": { 782 | "version": "1.1.1", 783 | "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", 784 | "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", 785 | "dev": true 786 | }, 787 | "node_modules/type-fest": { 788 | "version": "0.13.1", 789 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", 790 | "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", 791 | "dev": true, 792 | "engines": { 793 | "node": ">=10" 794 | }, 795 | "funding": { 796 | "url": "https://github.com/sponsors/sindresorhus" 797 | } 798 | }, 799 | "node_modules/unbzip2-stream": { 800 | "version": "1.4.3", 801 | "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", 802 | "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", 803 | "dev": true, 804 | "dependencies": { 805 | "buffer": "^5.2.1", 806 | "through": "^2.3.8" 807 | } 808 | }, 809 | "node_modules/util-deprecate": { 810 | "version": "1.0.2", 811 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 812 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", 813 | "dev": true 814 | }, 815 | "node_modules/wrappy": { 816 | "version": "1.0.2", 817 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 818 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 819 | "dev": true 820 | }, 821 | "node_modules/xtend": { 822 | "version": "4.0.2", 823 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", 824 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", 825 | "dev": true, 826 | "engines": { 827 | "node": ">=0.4" 828 | } 829 | }, 830 | "node_modules/yallist": { 831 | "version": "4.0.0", 832 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 833 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", 834 | "dev": true 835 | }, 836 | "node_modules/yauzl": { 837 | "version": "2.10.0", 838 | "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", 839 | "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", 840 | "dev": true, 841 | "dependencies": { 842 | "buffer-crc32": "~0.2.3", 843 | "fd-slicer": "~1.1.0" 844 | } 845 | } 846 | } 847 | } 848 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nodenv/nodenv-installer", 3 | "version": "2.0.1", 4 | "description": "Installer and doctor scripts for nodenv", 5 | "homepage": "https://github.com/nodenv/nodenv-installer#readme", 6 | "contributors": [ 7 | "Jason Karns (http://jasonkarns.com)", 8 | "Mislav Marohnić (https://github.com/mislav)" 9 | ], 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/nodenv/nodenv-installer.git" 13 | }, 14 | "bugs": { 15 | "url": "https://github.com/nodenv/nodenv-installer/issues" 16 | }, 17 | "directories": { 18 | "bin": "bin", 19 | "test": "test" 20 | }, 21 | "files": [ 22 | "bin" 23 | ], 24 | "scripts": { 25 | "test": "bats ${CI:+--tap} test", 26 | "posttest": "npm run lint", 27 | "lint": "git ls-files bin test | xargs shellcheck", 28 | "postversion": "git push --follow-tags" 29 | }, 30 | "devDependencies": { 31 | "@nodenv/nodenv": "^1", 32 | "bats": "^1", 33 | "bats-assert": "github:bats-core/bats-assert", 34 | "bats-support": "github:bats-core/bats-support", 35 | "shellcheck": "^2" 36 | }, 37 | "keywords": [ 38 | "nodenv", 39 | "install", 40 | "installer", 41 | "doctor", 42 | "debug", 43 | "help" 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /test/doctor.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | load test_helper 4 | 5 | @test "reports bin in PATH - missing" { 6 | run nodenv-doctor 7 | 8 | assert_failure 9 | assert_line "Checking for \`nodenv' in PATH: not found" 10 | assert_line " Please refer to https://github.com/nodenv/nodenv#installation" 11 | } 12 | 13 | @test "reports bin in PATH - missing, despite ~/.nodenv" { 14 | with_nodenv_in_home 15 | 16 | run nodenv-doctor 17 | 18 | assert_failure 19 | assert_line "Checking for \`nodenv' in PATH: not found" 20 | assert_line " You seem to have nodenv installed in \`$HOME/.nodenv/bin'," 21 | } 22 | 23 | @test "reports bin in PATH - OK" { 24 | with_nodenv 25 | 26 | run nodenv-doctor 27 | 28 | assert_line "Checking for \`nodenv' in PATH: $PWD/node_modules/.bin/nodenv" 29 | } 30 | 31 | @test "reports bin in PATH - multiple" { 32 | with_nodenv 33 | with_nodenv_in_home 34 | PATH="$HOME/.nodenv/bin:$PATH" 35 | 36 | run nodenv-doctor 37 | 38 | assert_failure 39 | assert_line "Checking for \`nodenv' in PATH: multiple" 40 | } 41 | 42 | @test "reports shims in PATH - missing" { 43 | with_nodenv 44 | 45 | run nodenv-doctor 46 | 47 | assert_failure 48 | assert_line "Checking for nodenv shims in PATH: not found" 49 | } 50 | 51 | @test "reports shims in PATH - OK" { 52 | with_nodenv 53 | with_nodenv_shims 54 | 55 | run nodenv-doctor 56 | 57 | assert_line "Checking for nodenv shims in PATH: OK" 58 | } 59 | 60 | @test "reports nodenv-install - missing" { 61 | with_nodenv 62 | 63 | run nodenv-doctor 64 | 65 | assert_failure 66 | assert_line "Checking \`nodenv install' support: not found" 67 | } 68 | 69 | @test "reports nodenv-install - OK" { 70 | with_nodenv 71 | with_nodenv_plugin nodenv-install 72 | 73 | run nodenv-doctor 74 | 75 | assert_line -p "Checking \`nodenv install' support: $NODENV_ROOT/plugins/nodenv-install/bin/nodenv-install" 76 | } 77 | 78 | @test "reports nodenv-install - multiple" { 79 | with_nodenv 80 | with_nodenv_plugin nodenv-install 81 | with_nodenv_plugin other-plugin nodenv-install 82 | 83 | run nodenv-doctor 84 | 85 | assert_failure 86 | assert_line "Checking \`nodenv install' support: multiple" 87 | } 88 | 89 | @test "reports nodes - zero" { 90 | with_nodenv 91 | 92 | run nodenv-doctor 93 | 94 | assert_line "Counting installed Node versions: none" 95 | } 96 | 97 | @test "reports nodes - some" { 98 | with_nodenv 99 | with_nodes 10.2.3 12.5.6 100 | 101 | run nodenv-doctor 102 | 103 | assert_line "Counting installed Node versions: 2 versions" 104 | } 105 | 106 | @test "reports plugins - OK" { 107 | with_nodenv 108 | 109 | run nodenv-doctor 110 | 111 | assert_line "Auditing installed plugins: OK" 112 | } 113 | 114 | @test "reports clean setup" { 115 | with_nodenv 116 | with_nodenv_shims 117 | with_nodenv_plugin nodenv-install 118 | with_nodes 10.2.3 119 | 120 | run nodenv-doctor 121 | 122 | assert_success 123 | assert_output - -e <<-OUT 124 | Checking for \`nodenv' in PATH: $PWD/node_modules/.bin/nodenv 125 | Checking for nodenv shims in PATH: OK 126 | Checking \`nodenv install' support: $NODENV_ROOT/plugins/nodenv-install/bin/nodenv-install \(.*\) 127 | Counting installed Node versions: 1 versions 128 | Auditing installed plugins: OK 129 | OUT 130 | } 131 | -------------------------------------------------------------------------------- /test/test_helper.bash: -------------------------------------------------------------------------------- 1 | load ../node_modules/bats-support/load 2 | load ../node_modules/bats-assert/load 3 | 4 | # guard against executing this block twice due to bats internals 5 | if [ -z "$TEST_DIR" ]; then 6 | TEST_DIR="${BATS_TMPDIR}/nodenv" 7 | TEST_DIR="$(mktemp -d "${TEST_DIR}.XXX" 2>/dev/null || echo "$TEST_DIR")" 8 | export TEST_DIR 9 | 10 | for nodenv_var in $(env 2>/dev/null | grep '^NODENV_' | cut -d= -f1); do 11 | unset "$nodenv_var" 12 | done 13 | unset nodenv_var 14 | 15 | export HOME="${TEST_DIR}/home" 16 | export NODENV_ROOT="${TEST_DIR}/root" 17 | PATH=/usr/bin:/bin:/usr/sbin:/sbin 18 | PATH="${BATS_TEST_DIRNAME}/../bin:$PATH" 19 | export PATH 20 | fi 21 | 22 | teardown() { 23 | rm -rf "${TEST_DIR:?}" 24 | } 25 | 26 | with_nodenv_in_home() { 27 | local nodenv="$PWD/node_modules/.bin/nodenv" 28 | 29 | mkdir -p "$HOME/.nodenv/bin" 30 | cd "$HOME/.nodenv/bin" || return 31 | ln -sf "$nodenv" nodenv 32 | } 33 | 34 | with_nodenv() { 35 | PATH="$PWD/node_modules/.bin:$PATH" 36 | } 37 | 38 | with_nodenv_shims() { 39 | local shims_path="$NODENV_ROOT/shims" 40 | mkdir -p "$shims_path" 41 | PATH="$shims_path:$PATH" 42 | } 43 | 44 | with_nodenv_plugin() { 45 | local name=$1 46 | local bin=${2:-$1} 47 | local path="$NODENV_ROOT/plugins/$name/bin" 48 | mkdir -p "$path" 49 | ln -sf "$(command -v grep)" "$path/$bin" # using grep b/c it supports '--version' 50 | } 51 | 52 | with_nodes() { 53 | local path="$NODENV_ROOT/versions" 54 | for node in "$@"; do 55 | mkdir -p "$path/$node/bin" 56 | done 57 | } 58 | --------------------------------------------------------------------------------