diff --git a/lib/helpers.sh b/lib/helpers.sh index 535232d..822469f 100755 --- a/lib/helpers.sh +++ b/lib/helpers.sh @@ -126,6 +126,8 @@ function cleanup() { rm -rf ./.terraform-version; log 'debug' "Deleting ${pwd}/latest_allowed.tf"; rm -rf ./latest_allowed.tf; + log 'debug' "Deleting ${pwd}/latest_allowed_stable.tf"; + rm -rf ./latest_allowed_stable.tf; log 'debug' "Deleting ${pwd}/min_required.tf"; rm -rf ./min_required.tf; log 'debug' "Deleting ${pwd}/chdir-dir"; @@ -149,6 +151,25 @@ function check_dependencies() { alias grep=ggrep; fi; }; + +function generate_regex_for_latest_allowed_stable() { + local constraint="$1" + + # Extract major, minor, patch, and optional pre-release tag + local major minor patch pre_release + IFS='.-' read -r major minor patch pre_release <<< "$constraint" + + # Start building the regex pattern + local regex="^${major}\." + regex+="(" + regex+="${minor}\.${patch}-${pre_release}" + regex+="|$(seq 0 $(($minor - 1)) | sed 's/[0-9]*/&\.[0-9]+|/g' | tr -d '\n')" + regex="${regex%|}" + regex+=")$" + + echo "$regex" +} + export -f check_dependencies; source "$TFENV_ROOT/lib/tfenv-exec.sh"; diff --git a/libexec/tfenv-resolve-version b/libexec/tfenv-resolve-version index 69468e5..4d0e325 100755 --- a/libexec/tfenv-resolve-version +++ b/libexec/tfenv-resolve-version @@ -127,7 +127,7 @@ if [[ "${version_requested}" =~ ^min-required$ ]]; then version_requested="${min_required}"; fi; -if [[ "${version_requested}" =~ ^latest-allowed$ ]]; then +if [[ "${version_requested}" =~ ^latest-allowed(-stable)?$ ]]; then log 'debug' 'Detecting latest allowable version...'; version_spec="$(grep -h required_version "${TFENV_DIR:-$(pwd)}"/{*.tf,*.tf.json} 2>/dev/null | { IFS='"' read -r _ ver _; echo "${ver%%,*}"; })"; version_num="$(echo "${version_spec}" | sed -E 's/[^0-9.]+//')"; @@ -138,11 +138,39 @@ if [[ "${version_requested}" =~ ^latest-allowed$ ]]; then version_requested=latest; ;; '<='*) - version_requested="${version_num}"; + IFS='.-' read -r major minor patch pre_release <<< "${version_num}" + if [[ "${version_requested}" =~ latest-allowed-stable$ && -n "${pre_release}" ]]; then + constraint_regex="^" + if [[ "$major" != 0 ]]; then + constraint_regex="^$(seq 0 $((major - 1)) | sed "s/[0-9]*/&\\\.[0-9]\\\+\\\.[0-9]\\\+\\\|/g" | tr -d '\n')" + fi + + if [[ "$minor" != 0 ]]; then + constraint_regex+="$(seq 0 $((minor - 1)) | sed "s/[0-9]*/${major}\\\.&\\\.[0-9]\\\+\\\|/g" | tr -d '\n')" + fi + + constraint_regex="${constraint_regex%\\|}" # Remove trailing '|' + constraint_regex+="$" + version_requested="latest:${constraint_regex}" + else + version_requested="${version_num}"; + fi ;; '~>'*) version_without_rightmost="${version_num%.*}"; - version_requested="latest:^${version_without_rightmost}"; + if [[ "${version_without_rightmost}" == "${version_num}" ]]; then + version_requested=latest + elif [[ "${version_requested}" =~ ^latest-allowed-stable$ ]]; then + IFS='.' read -ra version_without_rightmost_parts <<< "${version_without_rightmost}" + version_without_rightmost_count=${#version_without_rightmost_parts[@]} + version_requested="latest:^${version_without_rightmost}" + for (( i = version_without_rightmost_count; i < 3; i++ )); do + version_requested+="\.[0-9]\+" + done + version_requested+="$" + else + version_requested="latest:^${version_without_rightmost}" + fi ;; *) log 'error' "Unsupported version spec: '${version_spec}', only >, >=, <=, and ~> are supported."; diff --git a/test/test_use_latestallowed.sh b/test/test_use_latestallowedstable.sh similarity index 67% rename from test/test_use_latestallowed.sh rename to test/test_use_latestallowedstable.sh index 10af0d5..13ad876 100755 --- a/test/test_use_latestallowed.sh +++ b/test/test_use_latestallowedstable.sh @@ -53,62 +53,74 @@ declare -a errors=(); cleanup || log 'error' 'Cleanup failed?!'; -log 'info' '### Install latest-allowed normal version (#.#.#)'; +log 'info' '### Install latest-allowed-stable normal version (#.#.#)'; echo "terraform { required_version = \"~> 1.1.0\" -}" > latest_allowed.tf; +}" > latest_allowed_stable.tf; ( - tfenv install latest-allowed; - tfenv use latest-allowed; + tfenv install latest-allowed-stable; + tfenv use latest-allowed-stable; check_active_version 1.1.9; -) || error_and_proceed 'Latest allowed version does not match'; +) || error_and_proceed 'Latest allowed stable version does not match'; cleanup || log 'error' 'Cleanup failed?!'; - -log 'info' '### Install latest-allowed tagged version (#.#.#-tag#)' +log 'info' '### Install latest-allowed-stable tagged version (#.#.#-tag#)' echo "terraform { required_version = \"<=0.13.0-rc1\" -}" > latest_allowed.tf; +}" > latest_allowed_stable.tf; ( - tfenv install latest-allowed; - tfenv use latest-allowed; - check_active_version 0.13.0-rc1; -) || error_and_proceed 'Latest allowed tagged-version does not match'; + tfenv install latest-allowed-stable; + tfenv use latest-allowed-stable; + check_active_version 0.12.31; +) || error_and_proceed 'Latest allowed stable tagged-version does not match'; + +cleanup || log 'error' 'Cleanup failed?!'; + + +echo "terraform { + required_version = \"<=1.1.0-alpha20211006\" +}" > latest_allowed_stable.tf; + +( + tfenv install latest-allowed-stable; + tfenv use latest-allowed-stable; + check_active_version 1.0.11; +) || error_and_proceed 'Latest allowed stable tagged-version does not match'; cleanup || log 'error' 'Cleanup failed?!'; -log 'info' '### Install latest-allowed incomplete version (#.#.)' +log 'info' '### Install latest-allowed-stable incomplete version (#.#.)' echo "terraform { required_version = \"~> 0.12\" -}" >> latest_allowed.tf; +}" >> latest_allowed_stable.tf; ( - tfenv install latest-allowed; - tfenv use latest-allowed; + tfenv install latest-allowed-stable; + tfenv use latest-allowed-stable; check_active_version 0.15.5; -) || error_and_proceed 'Latest allowed incomplete-version does not match'; +) || error_and_proceed 'Latest allowed stable incomplete-version does not match'; cleanup || log 'error' 'Cleanup failed?!'; -log 'info' '### Install latest-allowed with TFENV_AUTO_INSTALL'; +log 'info' '### Install latest-allowed-stable with TFENV_AUTO_INSTALL'; echo "terraform { required_version = \"~> 1.0.0\" -}" >> latest_allowed.tf; -echo 'latest-allowed' > .terraform-version; +}" >> latest_allowed_stable.tf; +echo 'latest-allowed-stable' > .terraform-version; ( TFENV_AUTO_INSTALL=true terraform version; check_active_version 1.0.11; -) || error_and_proceed 'Latest allowed auto-installed version does not match'; +) || error_and_proceed 'Latest allowed stable auto-installed version does not match'; cleanup || log 'error' 'Cleanup failed?!'; @@ -119,7 +131,7 @@ mkdir -p chdir-dir echo "terraform { required_version = \"~> 0.14.3\" }" >> chdir-dir/latest_allowed.tf; -echo 'latest-allowed' > chdir-dir/.terraform-version +echo 'latest-allowed-stable' > chdir-dir/.terraform-version ( TFENV_AUTO_INSTALL=true terraform -chdir=chdir-dir version;