diff --git a/README.md b/README.md index 6b40a1f..b04d98a 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ If a parameter is passed, available options: - `x.y.z` [Semver 2.0.0](https://semver.org/) string specifying the exact version to install - `latest` is a syntax to install latest version - `latest:` is a syntax to install latest version matching regex (used by grep -e) -- `latest-allowed` is a syntax to scan your Terraform files to detect which version is maximally allowed. +- `latest-allowed` is a syntax to scan your Terraform files to detect which version is maximally allowed. Only considers stable versions, not pre-releases. - `min-required` is a syntax to scan your Terraform files to detect which version is minimally required. See [required_version](https://developer.hashicorp.com/terraform/language/settings) docs. Also [see min-required & latest-allowed](#min-required) section below. diff --git a/lib/helpers.sh b/lib/helpers.sh index 0f0de24..98486c5 100755 --- a/lib/helpers.sh +++ b/lib/helpers.sh @@ -156,6 +156,7 @@ function check_dependencies() { alias grep=ggrep; fi; }; + export -f check_dependencies; source "$TFENV_ROOT/lib/tfenv-exec.sh"; diff --git a/libexec/tfenv-resolve-version b/libexec/tfenv-resolve-version index 46d0704..c0a6023 100755 --- a/libexec/tfenv-resolve-version +++ b/libexec/tfenv-resolve-version @@ -138,11 +138,37 @@ if [[ "${version_requested}" =~ ^latest-allowed$ ]]; then version_requested=latest; ;; '<='*) - version_requested="${version_num}"; + IFS='.-' read -r major minor patch pre_release <<< "${version_num}" + if [[ -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 + else + 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+="$" + fi ;; *) log 'error' "Unsupported version spec: '${version_spec}', only >, >=, <=, and ~> are supported."; diff --git a/test/test_use_latestallowed.sh b/test/test_use_latestallowed.sh index bc4a07d..3b938e8 100755 --- a/test/test_use_latestallowed.sh +++ b/test/test_use_latestallowed.sh @@ -27,7 +27,7 @@ echo "terraform { cleanup || log 'error' 'Cleanup failed?!'; -log 'info' '### Install latest-allowed tagged version (#.#.#-tag#)' +log 'info' '### Install latest-allowed tagged version (#.#.#-tag#) - should skip to stable' echo "terraform { required_version = \"<=0.13.0-rc1\" @@ -36,8 +36,23 @@ echo "terraform { ( 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. Requested: "<=0.13.0-rc1", Expected: 0.13.0-rc1'; + check_active_version 0.12.31; +) || error_and_proceed 'Latest allowed should skip pre-release. Requested: "<=0.13.0-rc1", Expected: 0.12.31 (stable)'; + +cleanup || log 'error' 'Cleanup failed?!'; + + +log 'info' '### Install latest-allowed with alpha constraint - should skip to stable' + +echo "terraform { + required_version = \"<=1.1.0-alpha20211006\" +}" > latest_allowed.tf; + +( + tfenv install latest-allowed; + tfenv use latest-allowed; + check_active_version 1.0.11; +) || error_and_proceed 'Latest allowed should skip alpha versions. Requested: "<=1.1.0-alpha20211006", Expected: 1.0.11 (stable)'; cleanup || log 'error' 'Cleanup failed?!';