From 8c30f120d139189e8c2996e2476cb8518e4ddb9a Mon Sep 17 00:00:00 2001 From: John Gee Date: Mon, 24 Feb 2020 21:50:23 +1300 Subject: [PATCH] Preserve npm (#611) * First cut at --preserve (npm) * Add documentation for --preserve * Add --preserve test * Extend help section to include --no-preserve * Bump version * Prepare CHANGELOG for release --- CHANGELOG.md | 8 +++++++- README.md | 24 ++++++++++++++++++++++++ bin/n | 22 +++++++++++++++++----- package-lock.json | 2 +- package.json | 2 +- test/tests/install-options.bats | 29 +++++++++++++++++++++++++++++ 6 files changed, 79 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2781e2..b1b7118 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. -## [Unreleased] (date goes here) +## [6.3.0] (2020-02-24) + +### Added + +- `--preserve` to preserve npm and npx during install of node ([#587]) ## [6.2.0] (2020-01-29) @@ -240,6 +244,7 @@ Only minor functional changes, but technically could break scripts relying on sp [#560]: https://github.com/tj/n/issues/560 [#562]: https://github.com/tj/n/issues/562 [#574]: https://github.com/tj/n/issues/574 +[#587]: https://github.com/tj/n/issues/587 [#588]: https://github.com/tj/n/issues/588 [#590]: https://github.com/tj/n/issues/590 [#593]: https://github.com/tj/n/issues/593 @@ -249,6 +254,7 @@ Only minor functional changes, but technically could break scripts relying on sp [Unreleased]: https://github.com/tj/n/compare/master...develop +[6.3.0]: https://github.com/tj/n/compare/v6.2.0...v6.3.0 [6.2.0]: https://github.com/tj/n/compare/v6.1.3...v6.2.0 [6.1.3]: https://github.com/tj/n/compare/v6.0.2...v6.1.3 [6.1.2]: https://github.com/tj/n/compare/v6.0.1...v6.1.2 diff --git a/README.md b/README.md index 234d53f..0e41b3c 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ Node.js version management: no subshells, no profile setup, no convoluted API, j - [Specifying Node Versions](#specifying-node-versions) - [Removing Versions](#removing-versions) - [Using Downloaded Node Versions Without Reinstalling](#using-downloaded-node-versions-without-reinstalling) + - [Preserving npm](#preserving-npm) - [Miscellaneous](#miscellaneous) - [Custom Source](#custom-source) - [Custom Architecture](#custom-architecture) @@ -150,6 +151,28 @@ modules this way.) n exec 10 my-script --fast test +## Preserving npm + +A `node` install normally includes `npm` as well, but you may wish to preserve an updated `npm` and `npx` leaving them out of the install using `--preserve` (requires rsync): + + $ npm install -g npm@latest + ... + $ npm --version + 6.13.7 + $ n -p 8 + installed : v8.17.0 + $ npm --version + 6.13.7 + +You can make this the default by setting `N_PRESERVE_NPM` to a non-empty string. + + export N_PRESERVE_NPM=1 + +You can be explicit to get the desired behaviour whatever the environment variable: + + n --preserve nightly + n --no-preserve latest + ## Miscellaneous Command line help can be obtained from `n --help`. @@ -211,6 +234,7 @@ In brief: - `N_NODE_DOWNLOAD_MIRROR`: See [Custom source](#custom-source) - support for [NO_COLOR](http://no-color.org) and [CLICOLOR=0](https://bixense.com/clicolors) for controlling use of ANSI color codes - `N_MAX_REMOTE_MATCHES` to change the default `ls-remote` maximum of 20 matching versions +- `N_PRESERVE_NPM`: See [Preserving npm](#preserving-npm) ## How It Works diff --git a/bin/n b/bin/n index fb32a51..45b394a 100755 --- a/bin/n +++ b/bin/n @@ -40,7 +40,7 @@ function echo_red() { # Setup and state # -VERSION="6.2.1-0" +VERSION="6.3.0" N_PREFIX="${N_PREFIX-/usr/local}" N_PREFIX=${N_PREFIX%/} @@ -307,6 +307,7 @@ Options: -V, --version Output version of n -h, --help Display help information + -p, --preserve Preserve npm and npx during install of node (requires rsync) -q, --quiet Disable curl output (if available) -d, --download Download only -a, --arch Override system architecture @@ -567,14 +568,16 @@ activate() { local original_node="$(command -v node)" # Remove old npm to avoid potential issues with simple overwrite. - if test -d "$dir/lib/node_modules/npm"; then + if [[ -z "${N_PRESERVE_NPM}" && -d "$dir/lib/node_modules/npm" ]]; then if test -d "$N_PREFIX/lib/node_modules/npm"; then rm -rf "$N_PREFIX/lib/node_modules/npm" fi fi # Copy (lib before bin to avoid error messages on Darwin when cp over dangling link) for subdir in lib bin include share; do - if test -L "$N_PREFIX/$subdir"; then + if [[ -n "${N_PRESERVE_NPM}" ]]; then + rsync --recursive --archive --keep-dirlinks --exclude=npm --exclude=npx "${dir}/${subdir}" "${N_PREFIX}" + elif test -L "$N_PREFIX/$subdir"; then find "$dir/$subdir" -mindepth 1 -maxdepth 1 -exec cp -fR "{}" "$N_PREFIX/$subdir" \; else cp -fR "$dir/$subdir" "$N_PREFIX" @@ -592,7 +595,7 @@ activate() { local npm_version_str="" local installed_npm="${N_PREFIX}/bin/npm" local active_npm="$(command -v npm)" - if [[ -e "${active_npm}" && -e "${installed_npm}" && "${active_npm}" = "${installed_npm}" ]]; then + if [[ -z "${N_PRESERVE_NPM}" && -e "${active_npm}" && -e "${installed_npm}" && "${active_npm}" = "${installed_npm}" ]]; then npm_version_str=" (with npm $(npm --version))" fi @@ -1091,10 +1094,16 @@ function show_diagnostics() { echo_red "Neither curl nor wget found. Need one of them for downloads." fi + printf "\nrsync:\n" + if command -v rsync &> /dev/null; then + command -v rsync && rsync --version + else + printf "rsync not found. (Needed for preserving npm during install.)\n" + fi + printf "\nuname\n" uname -a - printf "\n\nSETTINGS\n" printf "\nn\n" @@ -1103,6 +1112,7 @@ function show_diagnostics() { echo "install destination: ${N_PREFIX}" [[ -n "${N_PREFIX}" ]] && echo "PATH: ${PATH}" echo "ls-remote max matches: ${N_MAX_REMOTE_MATCHES}" + [[ -n "${N_PRESERVE_NPM}" ]] && echo "installs preserve npm by default" printf "\nProxy\n" # disable "var is referenced but not assigned": https://github.com/koalaman/shellcheck/wiki/SC2154 @@ -1241,6 +1251,8 @@ while [[ $# -ne 0 ]]; do -q|--quiet) set_quiet ;; -d|--download) ACTIVATE=false ;; --insecure) set_insecure ;; + -p|--preserve) N_PRESERVE_NPM="true" ;; + --no-preserve) N_PRESERVE_NPM="" ;; --use-xz) N_USE_XZ="true" ;; --no-use-xz) N_USE_XZ="false" ;; --latest) display_remote_versions latest; exit ;; diff --git a/package-lock.json b/package-lock.json index fcd0b86..c1568a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "n", - "version": "6.2.1-0", + "version": "6.3.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index fdc46d6..3da23de 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "n", "description": "Interactively Manage All Your Node Versions", - "version": "6.2.1-0", + "version": "6.3.0", "author": "TJ Holowaychuk ", "homepage": "https://github.com/tj/n", "bugs": "https://github.com/tj/n/issues", diff --git a/test/tests/install-options.bats b/test/tests/install-options.bats index c8d0ebf..60447ea 100644 --- a/test/tests/install-options.bats +++ b/test/tests/install-options.bats @@ -33,4 +33,33 @@ function teardown() { } +# mostly --preserve, but also variations with i/install and lts/numeric +@test "--preserve variations # (4 installs)" { + local ARGON_VERSION="v4.9.1" + local ARGON_NPM_VERSION="2.15.11" + local LTS_VERSION="$(display_remote_version lts)" + + n ${ARGON_VERSION} + run "${N_PREFIX}/bin/node" --version + [ "$output" = "${ARGON_VERSION}" ] + run "${N_PREFIX}/bin/npm" --version + [ "$output" = "${ARGON_NPM_VERSION}" ] + + n --preserve "${LTS_VERSION}" + run "${N_PREFIX}/bin/node" --version + [ "$output" = "v${LTS_VERSION}" ] + run "${N_PREFIX}/bin/npm" --version + [ "$output" = "${ARGON_NPM_VERSION}" ] + + N_PRESERVE_NPM=1 n "${LTS_VERSION}" + run "${N_PREFIX}/bin/npm" --version + [ "$output" = "${ARGON_NPM_VERSION}" ] + + N_PRESERVE_NPM=1 n --no-preserve "${LTS_VERSION}" + run "${N_PREFIX}/bin/npm" --version + [ "$output" != "${ARGON_NPM_VERSION}" ] +} + + + # ToDo: --arch