From ab83657ba6fed0fb8529d8b0e1f0c3d1e25d7cbe Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Thu, 3 Sep 2026 10:17:16 -0700 Subject: [PATCH] [Refactor] `nvm --help`: extract the set-colors legend into `nvm_print_color_legend` --- nvm.sh | 30 +++++++---- test/fast/Unit tests/nvm_print_color_legend | 59 +++++++++++++++++++++ 2 files changed, 78 insertions(+), 11 deletions(-) create mode 100755 test/fast/Unit tests/nvm_print_color_legend diff --git a/nvm.sh b/nvm.sh index cc18543d..d130f00a 100755 --- a/nvm.sh +++ b/nvm.sh @@ -1183,6 +1183,23 @@ nvm_wrap_with_color_code() { fi } +nvm_print_color_legend() { + # Every line is built in a command substitution, so this cannot stay + # inline: resolving color support has to happen in one scope that all of + # them share. Pure code motion for now; see the following commit. + nvm_echo ' Initial colors are:' + nvm_echo_with_colors " $(nvm_wrap_with_color_code 'b' 'b')$(nvm_wrap_with_color_code 'y' 'y')$(nvm_wrap_with_color_code 'g' 'g')$(nvm_wrap_with_color_code 'r' 'r')$(nvm_wrap_with_color_code 'e' 'e')" + nvm_echo ' Color codes:' + nvm_echo_with_colors " $(nvm_wrap_with_color_code 'r' 'r')/$(nvm_wrap_with_color_code 'R' 'R') = $(nvm_wrap_with_color_code 'r' 'red') / $(nvm_wrap_with_color_code 'R' 'bold red')" + nvm_echo_with_colors " $(nvm_wrap_with_color_code 'g' 'g')/$(nvm_wrap_with_color_code 'G' 'G') = $(nvm_wrap_with_color_code 'g' 'green') / $(nvm_wrap_with_color_code 'G' 'bold green')" + nvm_echo_with_colors " $(nvm_wrap_with_color_code 'b' 'b')/$(nvm_wrap_with_color_code 'B' 'B') = $(nvm_wrap_with_color_code 'b' 'blue') / $(nvm_wrap_with_color_code 'B' 'bold blue')" + nvm_echo_with_colors " $(nvm_wrap_with_color_code 'c' 'c')/$(nvm_wrap_with_color_code 'C' 'C') = $(nvm_wrap_with_color_code 'c' 'cyan') / $(nvm_wrap_with_color_code 'C' 'bold cyan')" + nvm_echo_with_colors " $(nvm_wrap_with_color_code 'm' 'm')/$(nvm_wrap_with_color_code 'M' 'M') = $(nvm_wrap_with_color_code 'm' 'magenta') / $(nvm_wrap_with_color_code 'M' 'bold magenta')" + nvm_echo_with_colors " $(nvm_wrap_with_color_code 'y' 'y')/$(nvm_wrap_with_color_code 'Y' 'Y') = $(nvm_wrap_with_color_code 'y' 'yellow') / $(nvm_wrap_with_color_code 'Y' 'bold yellow')" + nvm_echo_with_colors " $(nvm_wrap_with_color_code 'k' 'k')/$(nvm_wrap_with_color_code 'K' 'K') = $(nvm_wrap_with_color_code 'k' 'black') / $(nvm_wrap_with_color_code 'K' 'bold black')" + nvm_echo_with_colors " $(nvm_wrap_with_color_code 'e' 'e')/$(nvm_wrap_with_color_code 'W' 'W') = $(nvm_wrap_with_color_code 'e' 'light grey') / $(nvm_wrap_with_color_code 'W' 'white')" +} + nvm_print_color_code() { case "${1-}" in '0') return 0 ;; @@ -3500,17 +3517,7 @@ nvm() { nvm_echo ' nvm cache dir Display path to the cache directory for nvm' nvm_echo ' nvm cache clear Empty cache directory for nvm' nvm_echo ' nvm set-colors [] Set five text colors using format "yMeBg". Available when supported.' - nvm_echo ' Initial colors are:' - nvm_echo_with_colors " $(nvm_wrap_with_color_code 'b' 'b')$(nvm_wrap_with_color_code 'y' 'y')$(nvm_wrap_with_color_code 'g' 'g')$(nvm_wrap_with_color_code 'r' 'r')$(nvm_wrap_with_color_code 'e' 'e')" - nvm_echo ' Color codes:' - nvm_echo_with_colors " $(nvm_wrap_with_color_code 'r' 'r')/$(nvm_wrap_with_color_code 'R' 'R') = $(nvm_wrap_with_color_code 'r' 'red') / $(nvm_wrap_with_color_code 'R' 'bold red')" - nvm_echo_with_colors " $(nvm_wrap_with_color_code 'g' 'g')/$(nvm_wrap_with_color_code 'G' 'G') = $(nvm_wrap_with_color_code 'g' 'green') / $(nvm_wrap_with_color_code 'G' 'bold green')" - nvm_echo_with_colors " $(nvm_wrap_with_color_code 'b' 'b')/$(nvm_wrap_with_color_code 'B' 'B') = $(nvm_wrap_with_color_code 'b' 'blue') / $(nvm_wrap_with_color_code 'B' 'bold blue')" - nvm_echo_with_colors " $(nvm_wrap_with_color_code 'c' 'c')/$(nvm_wrap_with_color_code 'C' 'C') = $(nvm_wrap_with_color_code 'c' 'cyan') / $(nvm_wrap_with_color_code 'C' 'bold cyan')" - nvm_echo_with_colors " $(nvm_wrap_with_color_code 'm' 'm')/$(nvm_wrap_with_color_code 'M' 'M') = $(nvm_wrap_with_color_code 'm' 'magenta') / $(nvm_wrap_with_color_code 'M' 'bold magenta')" - nvm_echo_with_colors " $(nvm_wrap_with_color_code 'y' 'y')/$(nvm_wrap_with_color_code 'Y' 'Y') = $(nvm_wrap_with_color_code 'y' 'yellow') / $(nvm_wrap_with_color_code 'Y' 'bold yellow')" - nvm_echo_with_colors " $(nvm_wrap_with_color_code 'k' 'k')/$(nvm_wrap_with_color_code 'K' 'K') = $(nvm_wrap_with_color_code 'k' 'black') / $(nvm_wrap_with_color_code 'K' 'bold black')" - nvm_echo_with_colors " $(nvm_wrap_with_color_code 'e' 'e')/$(nvm_wrap_with_color_code 'W' 'W') = $(nvm_wrap_with_color_code 'e' 'light grey') / $(nvm_wrap_with_color_code 'W' 'white')" + nvm_print_color_legend nvm_echo 'Example:' nvm_echo ' nvm install 8.0.0 Install a specific version number' nvm_echo ' nvm use 8.0 Use the latest available 8.0.x release' @@ -4950,6 +4957,7 @@ nvm() { nvm_curl_libz_support nvm_command_info nvm_is_zsh nvm_stdout_is_terminal \ nvm_npmrc_bad_news_bears nvm_sanitize_auth_header \ nvm_get_colors nvm_set_colors nvm_print_color_code nvm_wrap_with_color_code nvm_format_help_message_colors \ + nvm_print_color_legend \ nvm_echo_with_colors nvm_err_with_colors \ nvm_get_artifact_compression nvm_install_binary_extract nvm_extract_tarball \ nvm_process_nvmrc nvm_process_nvmrc_content nvm_nvmrc_invalid_msg \ diff --git a/test/fast/Unit tests/nvm_print_color_legend b/test/fast/Unit tests/nvm_print_color_legend new file mode 100755 index 00000000..e37bab93 --- /dev/null +++ b/test/fast/Unit tests/nvm_print_color_legend @@ -0,0 +1,59 @@ +#!/bin/sh + +die () { echo "$@" ; exit 1; } + +\. ../../../nvm.sh + +set -e + +ESC="$(printf '\033')" +# The legend's letters are wrapped in color codes when the terminal supports +# them, so every text assertion below compares against the output with any +# escapes removed. That keeps these checks about structure and alignment only. +strip_colors() { command sed "s/${ESC}\[[0-9;]*m//g"; } + +command -v nvm_print_color_legend >/dev/null 2>&1 \ + || die 'nvm_print_color_legend is not defined' + +OUTPUT="$(nvm_print_color_legend)" + +LINES="$(nvm_echo "${OUTPUT}" | command wc -l | command tr -d ' ')" +[ "${LINES}" = 11 ] || die "expected 11 legend lines, got ${LINES}: ${OUTPUT}" + +PLAIN="$(nvm_echo "${OUTPUT}" | strip_colors)" + +# the two labels are literal, and their indentation lines the legend up under +# the `nvm set-colors` entry in the help output +nvm_echo "${PLAIN}" | nvm_grep -qx ' Initial colors are:' \ + || die "the 'Initial colors are:' label is missing or misaligned: ${PLAIN}" +nvm_echo "${PLAIN}" | nvm_grep -qx ' Color codes:' \ + || die "the 'Color codes:' label is missing or misaligned: ${PLAIN}" + +# the default-palette sample, indented one level deeper than its label +nvm_echo "${PLAIN}" | nvm_grep -qx ' bygre' \ + || die "the initial-colors sample is missing or misaligned: ${PLAIN}" + +# all eight rows of the code table, in order, each with both letter forms +for ROW in \ + 'r/R = red / bold red' \ + 'g/G = green / bold green' \ + 'b/B = blue / bold blue' \ + 'c/C = cyan / bold cyan' \ + 'm/M = magenta / bold magenta' \ + 'y/Y = yellow / bold yellow' \ + 'k/K = black / bold black' \ + 'e/W = light grey / white' \ +; do + nvm_echo "${PLAIN}" | nvm_grep -qx " ${ROW}" \ + || die "color code row '${ROW}' is missing or misaligned: ${PLAIN}" +done + +# the extracted function has to stay wired into the help output +nvm --help | strip_colors | nvm_grep -qx ' Color codes:' \ + || die 'nvm --help no longer includes the color legend' + +# and `nvm unload` has to clean it up, the way it does its sibling helpers +UNLOADED="$( (nvm unload >/dev/null 2>&1; command -v nvm_print_color_legend >/dev/null 2>&1 && echo present || echo gone) )" +[ "${UNLOADED}" = 'gone' ] || die 'nvm unload left nvm_print_color_legend defined' + +echo "nvm_print_color_legend: passed"