From 6d642bc6e8b6805e57579086723d7d95b76bb328 Mon Sep 17 00:00:00 2001 From: DeeDeeG Date: Wed, 29 Jan 2020 03:42:31 -0500 Subject: [PATCH] Auto xz (#607) * bin/n: Port auto-xz feature from nvh Includes platform/feature detection to guess if the user has the ability to decompress xz tarballs using `tar`. Doesn't attempt to fetch/decompress xz tarballs for Node versions less than 4. (KISS). The feature is set up to use xz instead of gz by default, but the default behavior is easily configurable. Co-authored-by: John Gee * documentation: Add documentation for auto-xz * CHANGELOG.md: Copy xz entry from the nvh changelog Copied and pasted from here: https://github.com/shadowspawn/nvh/blob/master/CHANGELOG.md * README.md: Copy xz info from docs at nvh repo Copied and pasted from here: https://github.com/shadowspawn/nvh/blob/master/docs/environment-variables.md ("NVH" changed to "N" as appropriate.) Co-authored-by: John Gee Co-authored-by: John Gee --- CHANGELOG.md | 6 +++++ README.md | 11 ++++++-- bin/n | 75 +++++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 81 insertions(+), 11 deletions(-) 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