From b68ec4e9c108e0378787a289b78d20a531485dca Mon Sep 17 00:00:00 2001 From: Mike Peachey Date: Fri, 24 Apr 2026 16:34:18 +0100 Subject: [PATCH] Support tfenv use - to switch to previous version Similar to cd -, tfenv use - now switches back to the previously active default version. The previous version is saved to \$TFENV_CONFIG_DIR/version.prev each time tfenv use writes a new default. Running tfenv use - again toggles between the two versions. If no previous version exists, the command errors with a clear message. Also adds version.prev cleanup to the cleanup() helper in lib/helpers.sh to prevent test pollution. Fixes #378 --- lib/helpers.sh | 2 ++ libexec/tfenv-use | 24 ++++++++++++++++++++++ test/test_use_dash.sh | 47 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100755 test/test_use_dash.sh diff --git a/lib/helpers.sh b/lib/helpers.sh index 696f6b8c..ab38f4b0 100755 --- a/lib/helpers.sh +++ b/lib/helpers.sh @@ -154,6 +154,8 @@ function cleanup() { log 'debug' "Deleting ${TFENV_CONFIG_DIR}/version"; rm -rf "${TFENV_CONFIG_DIR}/version"; + log 'debug' "Deleting ${TFENV_CONFIG_DIR}/version.prev"; + rm -rf "${TFENV_CONFIG_DIR}/version.prev"; log 'debug' "Deleting ${TFENV_CONFIG_DIR}/versions"; rm -rf "${TFENV_CONFIG_DIR}/versions"; log 'debug' "Deleting ${pwd}/.terraform-version"; diff --git a/libexec/tfenv-use b/libexec/tfenv-use index 24de91fa..4a932f6c 100755 --- a/libexec/tfenv-use +++ b/libexec/tfenv-use @@ -72,6 +72,18 @@ declare version_source_suffix=""; declare requested="${requested_arg}"; declare loaded_version_file="$(tfenv-version-file)"; +# Handle 'tfenv use -' to switch to previous version +if [ "${requested_arg}" == '-' ]; then + declare prev_file="${TFENV_CONFIG_DIR}/version.prev"; + [ -f "${prev_file}" ] \ + || log 'error' 'No previous version to switch to. Use tfenv use first.'; + requested_arg="$(cat "${prev_file}" | tr -d '\r')"; + [ -n "${requested_arg}" ] \ + || log 'error' 'Previous version file is empty.'; + requested="${requested_arg}"; + log 'info' "Switching to previous version: ${requested_arg}"; +fi; + if [ -z "${requested_arg}" -a -z "${TFENV_TERRAFORM_VERSION:-""}" ]; then version_source_suffix=" (set by ${loaded_version_file})"; @@ -154,6 +166,18 @@ log 'debug' "target_path is ${TFENV_CONFIG_DIR}/versions/${installed_version}"; log 'info' "Switching default version to v${installed_version}"; version_file="${TFENV_CONFIG_DIR}/version"; + +# Save current version as previous before overwriting +if [ -f "${version_file}" ]; then + declare current_version; + current_version="$(cat "${version_file}" | tr -d '\r')" || true; + if [ -n "${current_version}" ] && [ "${current_version}" != "${installed_version}" ]; then + log 'debug' "Saving previous version '${current_version}' to ${version_file}.prev"; + echo "${current_version}" > "${version_file}.prev" \ + || log 'warn' "Failed to save previous version to ${version_file}.prev"; + fi; +fi; + log 'debug' "Writing \"${installed_version}\" to \"${version_file}\""; echo "${installed_version}" > "${version_file}" \ || log 'error' "Switch to v${installed_version} failed"; diff --git a/test/test_use_dash.sh b/test/test_use_dash.sh new file mode 100755 index 00000000..b0575614 --- /dev/null +++ b/test/test_use_dash.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash + +# Source common test setup +source "$(dirname "${0}")/test_common.sh"; + +##################### +# Begin Script Body # +##################### + +declare -a errors=(); + +log 'info' '### Test Suite: tfenv use -'; +cleanup || log 'error' 'Cleanup failed?!'; + +log 'info' '## Test: tfenv use - switches to previous version'; +( + tfenv install 0.12.1 || exit 1; + tfenv install 0.12.2 || exit 1; + + tfenv use 0.12.1 || exit 1; + check_active_version 0.12.1 || exit 1; + + tfenv use 0.12.2 || exit 1; + check_active_version 0.12.2 || exit 1; + + # Switch back to previous + tfenv use - || exit 1; + check_active_version 0.12.1 || exit 1; + + # Switch back again + tfenv use - || exit 1; + check_active_version 0.12.2 || exit 1; +) && log 'info' '## Test passed: tfenv use - switches to previous version' \ + || error_and_proceed 'tfenv use - switches to previous version'; + +log 'info' '## Test: tfenv use - fails with no previous version'; +cleanup || log 'error' 'Cleanup failed?!'; +( + tfenv install 0.12.1 || exit 1; + # No previous version set yet — use - should fail + tfenv use - 2>/dev/null && exit 1 || exit 0; +) && log 'info' '## Test passed: tfenv use - fails with no previous version' \ + || error_and_proceed 'tfenv use - fails with no previous version'; + +finish_tests 'use-dash'; +exit 0; +# vim: set ts=2 sw=2 et: