diff --git a/CHANGELOG.md b/CHANGELOG.md index 6583186..1e7b604 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] (date goes here) +### Added + +- Downloads now default to using tarballs compressed by `xz` over `gzip`, if `xz` support detected. (#606, #607) + ## [6.1.3] (2019-11-23) ### Added @@ -237,6 +241,8 @@ Only minor functional changes, but technically could break scripts relying on sp [#588]: https://github.com/tj/n/issues/588 [#590]: https://github.com/tj/n/issues/590 [#593]: https://github.com/tj/n/issues/593 +[#606]: https://github.com/tj/n/issues/606 +[#607]: https://github.com/tj/n/issues/607 diff --git a/README.md b/README.md index 71fbbf7..234d53f 100644 --- a/README.md +++ b/README.md @@ -194,9 +194,16 @@ To change the location to say `$HOME/.n`, add lines like the following to your s export N_PREFIX=$HOME/.n export PATH=$N_PREFIX/bin:$PATH -By default `n` downloads archives from the mirror site which have been compressed with `gzip`. You can switch to using the `xz` compressed archives by defining `N_USE_XZ`. +`n` defaults to using xz compressed node tarballs for the download if it is likely tar on the system supports xz decompression. +You can override the automatic choice by setting an environment variable to zero or non-zero: - export N_USE_XZ=true + export N_USE_XZ=0 # to disable + export N_USE_XZ=1 # to enable + +You can be explicit to get the desired behaviour whatever the environment variable: + + n install --use-xz nightly + n install --no-use-xz latest In brief: diff --git a/bin/n b/bin/n index 157e3c4..360f340 100755 --- a/bin/n +++ b/bin/n @@ -55,6 +55,18 @@ N_NODE_DOWNLOAD_MIRROR=${N_NODE_DOWNLOAD_MIRROR:-https://nodejs.org/download} N_NODE_DOWNLOAD_MIRROR=${N_NODE_DOWNLOAD_MIRROR%/} readonly N_NODE_DOWNLOAD_MIRROR +# Using xz instead of gzip is enabled by default, if xz compatibility checks pass. +# User may set N_USE_XZ to 0 to disable, or set to anything else to enable. +# May also be overridden by command line flags. + +# Normalise external values to true/false +if [[ "${N_USE_XZ}" = "0" ]]; then + N_USE_XZ="false" +elif [[ -n "${N_USE_XZ+defined}" ]]; then + N_USE_XZ="true" +fi +# Not setting to readonly. Overriden by CLI flags, and update_xz_settings_for_version. + N_MAX_REMOTE_MATCHES=${N_MAX_REMOTE_MATCHES:-20} # modified by update_mirror_settings_for_version g_mirror_url=${N_NODE_MIRROR} @@ -165,6 +177,23 @@ function update_mirror_settings_for_version() { fi } +# +# Synopsis: update_xz_settings_for_version version +# Globals modified: +# - N_USE_XZ +# + +function update_xz_settings_for_version() { + # tarballs in xz format were available in later version of iojs, but KISS and only use xz from v4. + if [[ "${N_USE_XZ}" = "true" ]]; then + local resolved_major_version + resolved_major_version="$(echo "${1#v}" | cut -d '.' -f '1')" + if [[ "${resolved_major_version}" -lt 4 ]]; then + N_USE_XZ="false" + fi + fi +} + # # Synopsis: is_lts_codename version # @@ -276,13 +305,14 @@ Commands: Options: - -V, --version Output version of n - -h, --help Display help information - -q, --quiet Disable curl output (if available) - -d, --download Download only - -a, --arch Override system architecture - --all ls-remote displays all matches instead of last 20 - --insecure Turn off certificate checking for https requests (may be needed from behind a proxy server) + -V, --version Output version of n + -h, --help Display help information + -q, --quiet Disable curl output (if available) + -d, --download Download only + -a, --arch Override system architecture + --all ls-remote displays all matches instead of last 20 + --insecure Turn off certificate checking for https requests (may be needed from behind a proxy server) + --use-xz/--no-use-xz Override automatic detection of xz support and enable/disable use of xz compressed node downloads. Aliases: @@ -589,10 +619,11 @@ install() { version="$(display_latest_resolved_version "$1")" || return 2 [[ -n "${version}" ]] || abort "no version found for '$1'" update_mirror_settings_for_version "$1" + update_xz_settings_for_version "${version}" local dir="${CACHE_DIR}/${g_mirror_folder_name}/${version}" - if test -n "$N_USE_XZ"; then + if test "$N_USE_XZ" = "true"; then local tarflag="-Jx" else local tarflag="-zx" @@ -775,6 +806,25 @@ function is_ok() { fi } +# +# Synopsis: can_use_xz +# Test system to see if xz decompression is supported by tar. +# + +function can_use_xz() { + # Be conservative and only enable if xz is likely to work. Unfortunately we can't directly query tar itself. + # For research, see https://github.com/shadowspawn/nvh/issues/8 + local uname_s="$(uname -s)" + if [[ "${uname_s}" = "Linux" ]] && command -v xz &> /dev/null ; then + # tar on linux is likely to support xv if it is available separately + return 0 + elif [[ "${uname_s}" = "Darwin" && "$(sw_vers -productVersion | cut -d '.' -f 2)" -gt "8" ]]; then + # tar on recent Darwin has xv support built-in + return 0 + fi + return 2 # not supported +} + # # Synopsis: display_tarball_platform # @@ -830,7 +880,7 @@ function display_compatible_file_field { function tarball_url() { local version="$1" local ext=gz - [ -n "$N_USE_XZ" ] && ext="xz" + [ "$N_USE_XZ" = "true" ] && ext="xz" echo "${g_mirror_url}/v${version}/node-v${version}-$(display_tarball_platform).tar.${ext}" } @@ -1191,6 +1241,8 @@ while [[ $# -ne 0 ]]; do -q|--quiet) set_quiet ;; -d|--download) ACTIVATE=false ;; --insecure) set_insecure ;; + --use-xz) N_USE_XZ="true" ;; + --no-use-xz) N_USE_XZ="false" ;; --latest) display_remote_versions latest; exit ;; --stable) display_remote_versions lts; exit ;; # [sic] old terminology --lts) display_remote_versions lts; exit ;; @@ -1202,6 +1254,11 @@ while [[ $# -ne 0 ]]; do shift done +if [[ -z "${N_USE_XZ+defined}" ]]; then + N_USE_XZ="true" # Default to using xz + can_use_xz || N_USE_XZ="false" +fi + set -- "${unprocessed_args[@]}" if test $# -eq 0; then