diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..64284b9 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +--- +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8a711cd..4b285fb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,7 +21,7 @@ jobs: - 'macos-latest' - 'ubuntu-latest' steps: - - uses: 'actions/checkout@v2' + - uses: 'actions/checkout@v4' with: fetch-depth: 1 - name: 'Install Dependencies' @@ -30,21 +30,21 @@ jobs: run: './test/run.sh' shell: 'bash' - - uses: 'docker/setup-buildx-action@v2' + - uses: 'docker/setup-buildx-action@v3' if: contains(matrix.os, 'ubuntu') with: install: true - - uses: 'docker/build-push-action@v3' + - uses: 'docker/build-push-action@v6' if: contains(matrix.os, 'ubuntu') with: context: . load: true - tags: "tfenv-terraform:${{ github.head_ref }}" + tags: "tfenv-terraform:${{ github.sha }}" - name: 'Check Dockerfile' if: contains(matrix.os, 'ubuntu') run: | expect=1.2.3; - got="$(docker run -e "TFENV_TERRAFORM_VERSION=${expect}" "tfenv-terraform:${{ github.head_ref }}" version)"; + got="$(docker run -e "TFENV_TERRAFORM_VERSION=${expect}" "tfenv-terraform:${{ github.sha }}" version)"; echo "${got}" | tee /dev/stderr | grep -e 'Terraform v1.2.3' # When we push to master, test everything in order to guarantee releases @@ -54,13 +54,14 @@ jobs: strategy: matrix: os: - - 'macos-11' - - 'macos-10.15' - - 'ubuntu-20.04' - - 'ubuntu-18.04' - - 'windows-2019' + - 'ubuntu-24.04' + - 'ubuntu-22.04' + - 'macos-14' + - 'macos-13' + - 'windows-2025' + - 'windows-2022' steps: - - uses: 'actions/checkout@v2' + - uses: 'actions/checkout@v4' with: fetch-depth: 1 - name: 'Install Dependencies' @@ -69,11 +70,11 @@ jobs: run: './test/run.sh' shell: 'bash' - - uses: 'docker/setup-buildx-action@v2' + - uses: 'docker/setup-buildx-action@v3' if: contains(matrix.os, 'ubuntu') with: install: true - - uses: 'docker/build-push-action@v3' + - uses: 'docker/build-push-action@v6' if: contains(matrix.os, 'ubuntu') with: context: . diff --git a/README.md b/README.md index 9155dbe..6b40a1f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![CI](https://github.com/tfutils/tfenv/workflows/CI/badge.svg) +[![CI Test](https://github.com/tfutils/tfenv/actions/workflows/test.yml/badge.svg)](https://github.com/tfutils/tfenv/actions/workflows/test.yml) # tfenv @@ -23,13 +23,13 @@ Currently tfenv supports the following OSes Install via Homebrew ```console -$ brew install tfenv +brew install tfenv ``` Install via Arch User Repository (AUR) ```console -$ yay --sync tfenv +yay --sync tfenv ``` Install via puppet @@ -45,34 +45,45 @@ include ::tfenv 1. Check out tfenv into any path (here is `${HOME}/.tfenv`) ```console -$ git clone --depth=1 https://github.com/tfutils/tfenv.git ~/.tfenv +git clone --depth=1 https://github.com/tfutils/tfenv.git ~/.tfenv ``` 2. Add `~/.tfenv/bin` to your `$PATH` any way you like +bash: ```console -$ echo 'export PATH="$HOME/.tfenv/bin:$PATH"' >> ~/.bash_profile +echo 'export PATH="$HOME/.tfenv/bin:$PATH"' >> ~/.bash_profile ``` - For WSL users +zsh: +```console +echo 'export PATH="$HOME/.tfenv/bin:$PATH"' >> ~/.zprofile +``` + +fish: +```console +echo 'set -x PATH $HOME/.tfenv/bin $PATH' >> ~/.config/fish/config.fish +``` + +For WSL users: ```bash -$ echo 'export PATH=$PATH:$HOME/.tfenv/bin' >> ~/.bashrc +echo 'export PATH=$PATH:$HOME/.tfenv/bin' >> ~/.bashrc ``` OR you can make symlinks for `tfenv/bin/*` scripts into a path that is already added to your `$PATH` (e.g. `/usr/local/bin`) `OSX/Linux Only!` ```console -$ ln -s ~/.tfenv/bin/* /usr/local/bin +ln -s ~/.tfenv/bin/* /usr/local/bin ``` On Ubuntu/Debian touching `/usr/local/bin` might require sudo access, but you can create `${HOME}/bin` or `${HOME}/.local/bin` and on next login it will get added to the session `$PATH` or by running `. ${HOME}/.profile` it will get added to the current shell session's `$PATH`. ```console -$ mkdir -p ~/.local/bin/ -$ . ~/.profile -$ ln -s ~/.tfenv/bin/* ~/.local/bin -$ which tfenv +mkdir -p ~/.local/bin/ +. ~/.profile +ln -s ~/.tfenv/bin/* ~/.local/bin +which tfenv ``` ## Usage @@ -91,7 +102,7 @@ If a parameter is passed, available options: - `latest-allowed` is a syntax to scan your Terraform files to detect which version is maximally allowed. - `min-required` is a syntax to scan your Terraform files to detect which version is minimally required. -See [required_version](https://www.terraform.io/docs/configuration/terraform.html) docs. Also [see min-required & latest-allowed](#min-required) section below. +See [required_version](https://developer.hashicorp.com/terraform/language/settings) docs. Also [see min-required & latest-allowed](#min-required) section below. ```console $ tfenv install @@ -110,8 +121,8 @@ You can opt-in to using GnuPG tools for PGP signature verification if keybase is Where `TFENV_INSTALL_DIR` is for example, `~/.tfenv` or `/usr/local/Cellar/tfenv/` ```console -$ echo 'trust-tfenv: yes' > ${TFENV_INSTALL_DIR}/use-gpgv -$ tfenv install +echo 'trust-tfenv: yes' > ${TFENV_INSTALL_DIR}/use-gpgv +tfenv install ``` The `trust-tfenv` directive means that verification uses a copy of the @@ -157,7 +168,7 @@ Specify architecture. Architecture other than the default amd64 can be specified Note: Default changes to `arm64` for versions that have arm64 builds available when `$(uname -m)` matches `aarch64* | arm64*` ```console -$ TFENV_ARCH=arm64 tfenv install 0.7.9 +TFENV_ARCH=arm64 tfenv install 0.7.9 ``` ##### `TFENV_AUTO_INSTALL` @@ -167,11 +178,11 @@ String (Default: true) Should tfenv automatically install terraform if the version specified by defaults or a .terraform-version file is not currently installed. ```console -$ TFENV_AUTO_INSTALL=false terraform plan +TFENV_AUTO_INSTALL=false terraform plan ``` ```console -$ terraform use +terraform use ``` ##### `TFENV_CURL_OUTPUT` @@ -202,7 +213,7 @@ String (Default: https://releases.hashicorp.com) To install from a remote other than the default ```console -$ TFENV_REMOTE=https://example.jfrog.io/artifactory/hashicorp +TFENV_REMOTE=https://example.jfrog.io/artifactory/hashicorp ``` ##### `TFENV_REVERSE_REMOTE` @@ -217,7 +228,7 @@ is instead providing a list that is oldes-first, set `TFENV_REVERSE_REMOTE=1` an functionality will be restored. ```console -$ TFENV_REVERSE_REMOTE=1 tfenv list-remote +TFENV_REVERSE_REMOTE=1 tfenv list-remote ``` ##### `TFENV_CONFIG_DIR` @@ -241,7 +252,7 @@ If not empty string, this variable overrides Terraform version, specified in [.t e.g. ```console -$ TFENV_TERRAFORM_VERSION=latest:^0.11. terraform --version +TFENV_TERRAFORM_VERSION=latest:^0.11. terraform --version ``` ##### `TFENV_NETRC_PATH` @@ -253,7 +264,7 @@ If not empty string, this variable specifies the credentials file used to access e.g. ```console -$ TFENV_NETRC_PATH="$PWD/.netrc.tfenv" +TFENV_NETRC_PATH="$PWD/.netrc.tfenv" ``` #### Bashlog Logging Library @@ -294,7 +305,7 @@ Each executable logs to its own file. e.g. ```console -$ BASHLOG_FILE=1 tfenv use latest +BASHLOG_FILE=1 tfenv use latest ``` will log to `/tmp/tfenv-use.log` @@ -316,7 +327,7 @@ This variable allows you to pass a string containing a command that will be exec e.g. ```console -$ BASHLOG_I_PROMISE_TO_BE_CAREFUL_CUSTOM_EVAL_PREFIX='echo "${$$} "' +BASHLOG_I_PROMISE_TO_BE_CAREFUL_CUSTOM_EVAL_PREFIX='echo "${$$} "' ``` will prefix every log line with the calling process' PID. @@ -332,7 +343,7 @@ Each executable logs to its own file. e.g. ```console -$ BASHLOG_JSON=1 tfenv use latest +BASHLOG_JSON=1 tfenv use latest ``` will log in JSON format to `/tmp/tfenv-use.log.json` @@ -356,10 +367,10 @@ To log to syslog using the `logger` binary, set this to 1. The basic functionality is thus: ```console -$ local tag="${BASHLOG_SYSLOG_TAG:-$(basename "${0}")}"; -$ local facility="${BASHLOG_SYSLOG_FACILITY:-local0}"; -$ local pid="${$}"; -$ logger --id="${pid}" -t "${tag}" -p "${facility}.${severity}" "${syslog_line}" +local tag="${BASHLOG_SYSLOG_TAG:-$(basename "${0}")}"; +local facility="${BASHLOG_SYSLOG_FACILITY:-local0}"; +local pid="${$}"; +logger --id="${pid}" -t "${tag}" -p "${facility}.${severity}" "${syslog_line}" ``` ##### `BASHLOG_SYSLOG_FACILITY` @@ -489,13 +500,13 @@ Terraform v0.7.3 ## Upgrading ```console -$ git --git-dir=~/.tfenv/.git pull +git --git-dir=~/.tfenv/.git pull ``` ## Uninstalling ```console -$ rm -rf /some/path/to/tfenv +rm -rf /some/path/to/tfenv ``` ## LICENSE diff --git a/lib/helpers.sh b/lib/helpers.sh index 535232d..0f0de24 100755 --- a/lib/helpers.sh +++ b/lib/helpers.sh @@ -118,10 +118,17 @@ export -f check_default_version; function cleanup() { log 'info' 'Performing cleanup'; local pwd="$(pwd)"; - log 'debug' "Deleting ${pwd}/version"; - rm -rf ./version; - log 'debug' "Deleting ${pwd}/versions"; - rm -rf ./versions; + + # Safety check to ensure TFENV_CONFIG_DIR is set and not empty + if [ -z "${TFENV_CONFIG_DIR:-""}" ]; then + log 'error' 'TFENV_CONFIG_DIR is not set, cannot perform cleanup safely'; + return 1; + fi; + + log 'debug' "Deleting ${TFENV_CONFIG_DIR}/version"; + rm -rf "${TFENV_CONFIG_DIR}/version"; + log 'debug' "Deleting ${TFENV_CONFIG_DIR}/versions"; + rm -rf "${TFENV_CONFIG_DIR}/versions"; log 'debug' "Deleting ${pwd}/.terraform-version"; rm -rf ./.terraform-version; log 'debug' "Deleting ${pwd}/latest_allowed.tf"; diff --git a/lib/tfenv-exec.sh b/lib/tfenv-exec.sh index 189d222..66af4cd 100644 --- a/lib/tfenv-exec.sh +++ b/lib/tfenv-exec.sh @@ -2,11 +2,39 @@ set -uo pipefail; +function realpath-relative-to() { + # A basic implementation of GNU `realpath --relative-to=$1 $2` + # that can also be used on macOS. + + # http://stackoverflow.com/questions/1055671/how-can-i-get-the-behavior-of-gnus-readlink-f-on-a-mac + readlink_f() { + local target_file="${1}"; + local file_name; + + while [ "${target_file}" != "" ]; do + cd "$(dirname "$target_file")" || early_death "Failed to 'cd \$(${target_file%/*})'"; + file_name="${target_file##*/}" || early_death "Failed to '\"${target_file##*/}\"'"; + target_file="$(readlink "${file_name}")"; + done; + + echo "$(pwd -P)/${file_name}"; + }; + + local relative_to="$(readlink_f "${1}")"; + local path="$(readlink_f "${2}")"; + + echo "${path#"${relative_to}/"}"; + return 0; +} +export -f realpath-relative-to; + function tfenv-exec() { for _arg in ${@:1}; do if [[ "${_arg}" == -chdir=* ]]; then - log 'debug' "Found -chdir arg. Setting TFENV_DIR to: ${_arg#-chdir=}"; - export TFENV_DIR="${PWD}/${_arg#-chdir=}"; + chdir="${_arg#-chdir=}"; + log 'debug' "Found -chdir arg: ${chdir}"; + export TFENV_DIR="${PWD}/$(realpath-relative-to "${PWD}" "${chdir}")"; + log 'debug' "Setting TFENV_DIR to: ${TFENV_DIR}"; fi; done; diff --git a/lib/tfenv-version-name.sh b/lib/tfenv-version-name.sh index 3975769..c457875 100644 --- a/lib/tfenv-version-name.sh +++ b/lib/tfenv-version-name.sh @@ -10,7 +10,7 @@ function tfenv-version-name() { && log 'debug' "TFENV_VERSION_FILE retrieved from tfenv-version-file: ${TFENV_VERSION_FILE}" \ || log 'error' 'Failed to retrieve TFENV_VERSION_FILE from tfenv-version-file'; - TFENV_VERSION="$(cat "${TFENV_VERSION_FILE}" || true)" \ + TFENV_VERSION="$(cat "${TFENV_VERSION_FILE}" || true | tr -d '\r')" \ && log 'debug' "TFENV_VERSION specified in TFENV_VERSION_FILE: ${TFENV_VERSION}"; TFENV_VERSION_SOURCE="${TFENV_VERSION_FILE}"; diff --git a/libexec/tfenv-install b/libexec/tfenv-install index d13b384..9b7d69a 100755 --- a/libexec/tfenv-install +++ b/libexec/tfenv-install @@ -89,10 +89,10 @@ case "$(uname -s)" in MINGW64*) kernel="windows"; ;; - MSYSNT*) + MSYS*NT*) kernel="windows"; ;; - CYGWINNT*) + CYGWIN*NT*) kernel="windows"; ;; FreeBSD*) @@ -124,7 +124,7 @@ case "$(uname -m)" in ;; "darwin") # No Apple Silicon builds before 1.0.2 - if [[ "${version}" =~ 0\..+$ || "${version}" =~ 1\.0\.0|1$ + if [[ "${version}" =~ ^0\.[0-9]+\.[0-9]+ || "${version}" =~ ^1\.0\.[0-1]$ ]]; then TFENV_ARCH="${TFENV_ARCH:-amd64}"; else diff --git a/libexec/tfenv-min-required b/libexec/tfenv-min-required index 80d91b1..ee1642c 100755 --- a/libexec/tfenv-min-required +++ b/libexec/tfenv-min-required @@ -68,7 +68,7 @@ terraform { required_version = ">= 0.0.0" } -see https://www.terraform.io/docs/configuration/terraform.html for details'; +see https://developer.hashicorp.com/terraform/language/settings for details'; }; declare min_required="$(tfenv-min-required "${TFENV_DIR:-$(pwd)}")"; diff --git a/libexec/tfenv-resolve-version b/libexec/tfenv-resolve-version index d0b66bc..46d0704 100755 --- a/libexec/tfenv-resolve-version +++ b/libexec/tfenv-resolve-version @@ -77,12 +77,12 @@ if [ -z "${arg}" -a -z "${TFENV_TERRAFORM_VERSION:-""}" ]; then if [ "${version_file}" != "${TFENV_CONFIG_DIR}/version" ]; then log 'debug' "Version File (${version_file}) is not the default \${TFENV_CONFIG_DIR}/version (${TFENV_CONFIG_DIR}/version)"; - version_requested="$(cat "${version_file}")" \ + version_requested="$(cat "${version_file}" | tr -d '\r')" \ || log 'error' "Failed to open ${version_file}"; elif [ -f "${version_file}" ]; then log 'debug' "Version File is the default \${TFENV_CONFIG_DIR}/version (${TFENV_CONFIG_DIR}/version)"; - version_requested="$(cat "${version_file}")" \ + version_requested="$(cat "${version_file}" | tr -d '\r')" \ || log 'error' "Failed to open ${version_file}"; # Absolute fallback @@ -129,7 +129,7 @@ fi; if [[ "${version_requested}" =~ ^latest-allowed$ ]]; then log 'debug' 'Detecting latest allowable version...'; - version_spec="$(grep -h required_version "${TFENV_DIR:-$(pwd)}"/{*.tf,*.tf.json} 2>/dev/null | rev | cut -d'"' -f2 | rev | cut -d, -f1)"; + 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.]+//')"; log 'debug' "Using ${version_num} from version spec: ${version_spec}"; @@ -141,8 +141,8 @@ if [[ "${version_requested}" =~ ^latest-allowed$ ]]; then version_requested="${version_num}"; ;; '~>'*) - version_without_rightmost="$(echo "${version_num}" | rev | cut -d. -f2- | rev)"; - version_requested="latest:^${version_without_rightmost}"; + version_without_rightmost="${version_num%.*}"; + version_requested="latest:^${version_without_rightmost}\."; ;; *) log 'error' "Unsupported version spec: '${version_spec}', only >, >=, <=, and ~> are supported."; diff --git a/test/run.sh b/test/run.sh index 0e1d362..cfec2fc 100755 --- a/test/run.sh +++ b/test/run.sh @@ -1,54 +1,12 @@ #!/usr/bin/env bash -set -uo pipefail; -#################################### -# Ensure we can execute standalone # -#################################### - -function early_death() { - echo "[FATAL] ${0}: ${1}" >&2; - exit 1; -}; - -if [ -z "${TFENV_ROOT:-""}" ]; then - # http://stackoverflow.com/questions/1055671/how-can-i-get-the-behavior-of-gnus-readlink-f-on-a-mac - readlink_f() { - local target_file="${1}"; - local file_name; - - while [ "${target_file}" != "" ]; do - cd "$(dirname ${target_file})" || early_death "Failed to 'cd \$(dirname ${target_file})' while trying to determine TFENV_ROOT"; - file_name="$(basename "${target_file}")" || early_death "Failed to 'basename \"${target_file}\"' while trying to determine TFENV_ROOT"; - target_file="$(readlink "${file_name}")"; - done; - - echo "$(pwd -P)/${file_name}"; - }; - - TFENV_ROOT="$(cd "$(dirname "$(readlink_f "${0}")")/.." && pwd)"; - [ -n ${TFENV_ROOT} ] || early_death "Failed to 'cd \"\$(dirname \"\$(readlink_f \"${0}\")\")/..\" && pwd' while trying to determine TFENV_ROOT"; -else - TFENV_ROOT="${TFENV_ROOT%/}"; -fi; -export TFENV_ROOT; - -if [ -n "${TFENV_HELPERS:-""}" ]; then - log 'debug' 'TFENV_HELPERS is set, not sourcing helpers again'; -else - [ "${TFENV_DEBUG:-0}" -gt 0 ] && echo "[DEBUG] Sourcing helpers from ${TFENV_ROOT}/lib/helpers.sh"; - if source "${TFENV_ROOT}/lib/helpers.sh"; then - log 'debug' 'Helpers sourced successfully'; - else - early_death "Failed to source helpers from ${TFENV_ROOT}/lib/helpers.sh"; - fi; -fi; +# Source common test setup +source "$(dirname "${0}")/test_common.sh"; ##################### # Begin Script Body # ##################### -export PATH="${TFENV_ROOT}/bin:${PATH}"; - errors=(); if [ "${#}" -ne 0 ]; then targets="$@"; diff --git a/test/test_common.sh b/test/test_common.sh new file mode 100644 index 0000000..2797137 --- /dev/null +++ b/test/test_common.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash + +# Common test setup header +# Source this file at the beginning of test scripts to set up the test environment + +set -uo pipefail; + +#################################### +# Ensure we can execute standalone # +#################################### + +function early_death() { + echo "[FATAL] ${0}: ${1}" >&2; + exit 1; +}; + +if [ -z "${TFENV_ROOT:-""}" ]; then + # http://stackoverflow.com/questions/1055671/how-can-i-get-the-behavior-of-gnus-readlink-f-on-a-mac + readlink_f() { + local target_file="${1}"; + local file_name; + + while [ "${target_file}" != "" ]; do + cd "$(dirname ${target_file})" || early_death "Failed to 'cd \$(dirname ${target_file})' while trying to determine TFENV_ROOT"; + file_name="$(basename "${target_file}")" || early_death "Failed to 'basename \"${target_file}\"' while trying to determine TFENV_ROOT"; + target_file="$(readlink "${file_name}")"; + done; + + echo "$(pwd -P)/${file_name}"; + }; + + TFENV_ROOT="$(cd "$(dirname "$(readlink_f "${0}")")/.." && pwd)"; + [ -n ${TFENV_ROOT} ] || early_death "Failed to 'cd \"\$(dirname \"\$(readlink_f \"${0}\")\")/..\" && pwd' while trying to determine TFENV_ROOT"; +else + TFENV_ROOT="${TFENV_ROOT%/}"; +fi; +export TFENV_ROOT; + +if [ -n "${TFENV_HELPERS:-""}" ]; then + log 'debug' 'TFENV_HELPERS is set, not sourcing helpers again'; +else + [ "${TFENV_DEBUG:-0}" -gt 0 ] && echo "[DEBUG] Sourcing helpers from ${TFENV_ROOT}/lib/helpers.sh"; + if source "${TFENV_ROOT}/lib/helpers.sh"; then + log 'debug' 'Helpers sourced successfully'; + else + early_death "Failed to source helpers from ${TFENV_ROOT}/lib/helpers.sh"; + fi; +fi; + +# Ensure local tfenv binaries take precedence +export PATH="${TFENV_ROOT}/bin:${PATH}"; diff --git a/test/test_install_and_use.sh b/test/test_install_and_use.sh index fd2b6f0..e5d13d8 100755 --- a/test/test_install_and_use.sh +++ b/test/test_install_and_use.sh @@ -1,47 +1,7 @@ #!/usr/bin/env bash -set -uo pipefail; -#################################### -# Ensure we can execute standalone # -#################################### - -function early_death() { - echo "[FATAL] ${0}: ${1}" >&2; - exit 1; -}; - -if [ -z "${TFENV_ROOT:-""}" ]; then - # http://stackoverflow.com/questions/1055671/how-can-i-get-the-behavior-of-gnus-readlink-f-on-a-mac - readlink_f() { - local target_file="${1}"; - local file_name; - - while [ "${target_file}" != "" ]; do - cd "$(dirname ${target_file})" || early_death "Failed to 'cd \$(dirname ${target_file})' while trying to determine TFENV_ROOT"; - file_name="$(basename "${target_file}")" || early_death "Failed to 'basename \"${target_file}\"' while trying to determine TFENV_ROOT"; - target_file="$(readlink "${file_name}")"; - done; - - echo "$(pwd -P)/${file_name}"; - }; - - TFENV_ROOT="$(cd "$(dirname "$(readlink_f "${0}")")/.." && pwd)"; - [ -n ${TFENV_ROOT} ] || early_death "Failed to 'cd \"\$(dirname \"\$(readlink_f \"${0}\")\")/..\" && pwd' while trying to determine TFENV_ROOT"; -else - TFENV_ROOT="${TFENV_ROOT%/}"; -fi; -export TFENV_ROOT; - -if [ -n "${TFENV_HELPERS:-""}" ]; then - log 'debug' 'TFENV_HELPERS is set, not sourcing helpers again'; -else - [ "${TFENV_DEBUG:-0}" -gt 0 ] && echo "[DEBUG] Sourcing helpers from ${TFENV_ROOT}/lib/helpers.sh"; - if source "${TFENV_ROOT}/lib/helpers.sh"; then - log 'debug' 'Helpers sourced successfully'; - else - early_death "Failed to source helpers from ${TFENV_ROOT}/lib/helpers.sh"; - fi; -fi; +# Source common test setup +source "$(dirname "${0}")/test_common.sh"; ##################### # Begin Script Body # @@ -105,11 +65,28 @@ tests__kv=( "$(tfenv list-remote | grep 'rc' | head -n 1),latest:rc" "$(tfenv list-remote | grep '^0\.11\.' | head -n 1),latest:^0.11." '0.11.15-oci,0.11.15-oci' - '0.8.8,latest:^0.8' - '0.7.13,0.7.13' + '1.3.10,latest:^1\.3' + '1.6.3,1.6.3' '0.14.6,v0.14.6' ); +log 'info' "Kernel under test: $(uname -s)"; + +if [[ "$(uname -s)" != Darwin* ]]; then + log 'info' "We're not Darwin! Adding legacy tests."; + tests__desc+=( + 'legacy latest version matching regex' + 'legacy specific version' + ); + + tests__kv+=( + '0.8.8,latest:^0.8' + '0.7.13,0.7.13' + ); +else + log 'warn' "We're Darwin! Skipping legacy tests."; +fi; + tests_count=${#tests__desc[@]}; declare desc kv k v test_num; diff --git a/test/test_list.sh b/test/test_list.sh index bcb8d57..a9a171b 100755 --- a/test/test_list.sh +++ b/test/test_list.sh @@ -1,48 +1,7 @@ #!/usr/bin/env bash -set -uo pipefail; - -#################################### -# Ensure we can execute standalone # -#################################### - -function early_death() { - echo "[FATAL] ${0}: ${1}" >&2; - exit 1; -}; - -if [ -z "${TFENV_ROOT:-""}" ]; then - # http://stackoverflow.com/questions/1055671/how-can-i-get-the-behavior-of-gnus-readlink-f-on-a-mac - readlink_f() { - local target_file="${1}"; - local file_name; - - while [ "${target_file}" != "" ]; do - cd "$(dirname ${target_file})" || early_death "Failed to 'cd \$(dirname ${target_file})' while trying to determine TFENV_ROOT"; - file_name="$(basename "${target_file}")" || early_death "Failed to 'basename \"${target_file}\"' while trying to determine TFENV_ROOT"; - target_file="$(readlink "${file_name}")"; - done; - - echo "$(pwd -P)/${file_name}"; - }; - - TFENV_ROOT="$(cd "$(dirname "$(readlink_f "${0}")")/.." && pwd)"; - [ -n ${TFENV_ROOT} ] || early_death "Failed to 'cd \"\$(dirname \"\$(readlink_f \"${0}\")\")/..\" && pwd' while trying to determine TFENV_ROOT"; -else - TFENV_ROOT="${TFENV_ROOT%/}"; -fi; -export TFENV_ROOT; - -if [ -n "${TFENV_HELPERS:-""}" ]; then - log 'debug' 'TFENV_HELPERS is set, not sourcing helpers again'; -else - [ "${TFENV_DEBUG:-0}" -gt 0 ] && echo "[DEBUG] Sourcing helpers from ${TFENV_ROOT}/lib/helpers.sh"; - if source "${TFENV_ROOT}/lib/helpers.sh"; then - log 'debug' 'Helpers sourced successfully'; - else - early_death "Failed to source helpers from ${TFENV_ROOT}/lib/helpers.sh"; - fi; -fi; +# Source common test setup +source "$(dirname "${0}")/test_common.sh"; ##################### # Begin Script Body # diff --git a/test/test_symlink.sh b/test/test_symlink.sh index 3c99bfd..ac47eac 100755 --- a/test/test_symlink.sh +++ b/test/test_symlink.sh @@ -1,48 +1,7 @@ #!/usr/bin/env bash -set -uo pipefail; - -#################################### -# Ensure we can execute standalone # -#################################### - -function early_death() { - echo "[FATAL] ${0}: ${1}" >&2; - exit 1; -}; - -if [ -z "${TFENV_ROOT:-""}" ]; then - # http://stackoverflow.com/questions/1055671/how-can-i-get-the-behavior-of-gnus-readlink-f-on-a-mac - readlink_f() { - local target_file="${1}"; - local file_name; - - while [ "${target_file}" != "" ]; do - cd "$(dirname ${target_file})" || early_death "Failed to 'cd \$(dirname ${target_file})' while trying to determine TFENV_ROOT"; - file_name="$(basename "${target_file}")" || early_death "Failed to 'basename \"${target_file}\"' while trying to determine TFENV_ROOT"; - target_file="$(readlink "${file_name}")"; - done; - - echo "$(pwd -P)/${file_name}"; - }; - - TFENV_ROOT="$(cd "$(dirname "$(readlink_f "${0}")")/.." && pwd)"; - [ -n ${TFENV_ROOT} ] || early_death "Failed to 'cd \"\$(dirname \"\$(readlink_f \"${0}\")\")/..\" && pwd' while trying to determine TFENV_ROOT"; -else - TFENV_ROOT="${TFENV_ROOT%/}"; -fi; -export TFENV_ROOT; - -if [ -n "${TFENV_HELPERS:-""}" ]; then - log 'debug' 'TFENV_HELPERS is set, not sourcing helpers again'; -else - [ "${TFENV_DEBUG:-0}" -gt 0 ] && echo "[DEBUG] Sourcing helpers from ${TFENV_ROOT}/lib/helpers.sh"; - if source "${TFENV_ROOT}/lib/helpers.sh"; then - log 'debug' 'Helpers sourced successfully'; - else - early_death "Failed to source helpers from ${TFENV_ROOT}/lib/helpers.sh"; - fi; -fi; +# Source common test setup +source "$(dirname "${0}")/test_common.sh"; ##################### # Begin Script Body # @@ -52,22 +11,22 @@ declare -a errors=(); log 'info' '### Testing symlink functionality'; -TFENV_BIN_DIR='/tmp/tfenv-test'; -log 'info' "## Creating/clearing ${TFENV_BIN_DIR}" -rm -rf "${TFENV_BIN_DIR}" && mkdir "${TFENV_BIN_DIR}"; -log 'info' "## Symlinking ${PWD}/bin/* into ${TFENV_BIN_DIR}"; -ln -s "${PWD}"/bin/* "${TFENV_BIN_DIR}"; +TFENV_BIN_DIR="$(mktemp -d)"; +log 'info' "## Using temporary directory ${TFENV_BIN_DIR}"; +trap 'rm -rf "${TFENV_BIN_DIR}"' EXIT; +log 'info' "## Symlinking ${TFENV_ROOT}/bin/* into ${TFENV_BIN_DIR}"; +ln -s "${TFENV_ROOT}"/bin/* "${TFENV_BIN_DIR}"; cleanup || log 'error' 'Cleanup failed?!'; -log 'info' '## Installing 0.8.2'; -${TFENV_BIN_DIR}/tfenv install 0.8.2 || error_and_proceed 'Install failed'; +log 'info' '## Installing 1.6.1'; +${TFENV_BIN_DIR}/tfenv install 1.6.1 || error_and_proceed 'Install failed'; -log 'info' '## Using 0.8.2'; -${TFENV_BIN_DIR}/tfenv use 0.8.2 || error_and_proceed 'Use failed'; +log 'info' '## Using 1.6.1'; +${TFENV_BIN_DIR}/tfenv use 1.6.1 || error_and_proceed 'Use failed'; -log 'info' '## Check-Version for 0.8.2'; -check_active_version 0.8.2 || error_and_proceed 'Version check failed'; +log 'info' '## Check-Version for 1.6.1'; +check_active_version 1.6.1 || error_and_proceed 'Version check failed'; if [ "${#errors[@]}" -gt 0 ]; then log 'warn' '===== The following symlink tests failed ====='; diff --git a/test/test_uninstall.sh b/test/test_uninstall.sh index 70fe803..f75e4ae 100755 --- a/test/test_uninstall.sh +++ b/test/test_uninstall.sh @@ -1,48 +1,7 @@ #!/usr/bin/env bash -set -uo pipefail; - -#################################### -# Ensure we can execute standalone # -#################################### - -function early_death() { - echo "[FATAL] ${0}: ${1}" >&2; - exit 1; -}; - -if [ -z "${TFENV_ROOT:-""}" ]; then - # http://stackoverflow.com/questions/1055671/how-can-i-get-the-behavior-of-gnus-readlink-f-on-a-mac - readlink_f() { - local target_file="${1}"; - local file_name; - - while [ "${target_file}" != "" ]; do - cd "$(dirname ${target_file})" || early_death "Failed to 'cd \$(dirname ${target_file})' while trying to determine TFENV_ROOT"; - file_name="$(basename "${target_file}")" || early_death "Failed to 'basename \"${target_file}\"' while trying to determine TFENV_ROOT"; - target_file="$(readlink "${file_name}")"; - done; - - echo "$(pwd -P)/${file_name}"; - }; - - TFENV_ROOT="$(cd "$(dirname "$(readlink_f "${0}")")/.." && pwd)"; - [ -n ${TFENV_ROOT} ] || early_death "Failed to 'cd \"\$(dirname \"\$(readlink_f \"${0}\")\")/..\" && pwd' while trying to determine TFENV_ROOT"; -else - TFENV_ROOT="${TFENV_ROOT%/}"; -fi; -export TFENV_ROOT; - -if [ -n "${TFENV_HELPERS:-""}" ]; then - log 'debug' 'TFENV_HELPERS is set, not sourcing helpers again'; -else - [ "${TFENV_DEBUG:-0}" -gt 0 ] && echo "[DEBUG] Sourcing helpers from ${TFENV_ROOT}/lib/helpers.sh"; - if source "${TFENV_ROOT}/lib/helpers.sh"; then - log 'debug' 'Helpers sourced successfully'; - else - early_death "Failed to source helpers from ${TFENV_ROOT}/lib/helpers.sh"; - fi; -fi; +# Source common test setup +source "$(dirname "${0}")/test_common.sh"; ##################### # Begin Script Body # @@ -94,11 +53,11 @@ cleanup || error_and_die "Cleanup failed?!" ( tfenv install 0.12.1 || exit 1 tfenv install 0.12.2 || exit 1 - [ -d "./versions" ] || exit 1 + [ -d "${TFENV_CONFIG_DIR}/versions" ] || exit 1 tfenv uninstall 0.12.1 || exit 1 - [ -d "./versions" ] || exit 1 + [ -d "${TFENV_CONFIG_DIR}/versions" ] || exit 1 tfenv uninstall 0.12.2 || exit 1 - [ -d "./versions" ] && exit 1 || exit 0 + [ -d "${TFENV_CONFIG_DIR}/versions" ] && exit 1 || exit 0 ) || error_and_proceed "Removing last version deletes versions directory" if [ "${#errors[@]}" -gt 0 ]; then diff --git a/test/test_use_latestallowed.sh b/test/test_use_latestallowed.sh index 10af0d5..bc4a07d 100755 --- a/test/test_use_latestallowed.sh +++ b/test/test_use_latestallowed.sh @@ -1,48 +1,7 @@ #!/usr/bin/env bash -set -uo pipefail; - -#################################### -# Ensure we can execute standalone # -#################################### - -function early_death() { - echo "[FATAL] ${0}: ${1}" >&2; - exit 1; -}; - -if [ -z "${TFENV_ROOT:-""}" ]; then - # http://stackoverflow.com/questions/1055671/how-can-i-get-the-behavior-of-gnus-readlink-f-on-a-mac - readlink_f() { - local target_file="${1}"; - local file_name; - - while [ "${target_file}" != "" ]; do - cd "$(dirname ${target_file})" || early_death "Failed to 'cd \$(dirname ${target_file})' while trying to determine TFENV_ROOT"; - file_name="$(basename "${target_file}")" || early_death "Failed to 'basename \"${target_file}\"' while trying to determine TFENV_ROOT"; - target_file="$(readlink "${file_name}")"; - done; - - echo "$(pwd -P)/${file_name}"; - }; - - TFENV_ROOT="$(cd "$(dirname "$(readlink_f "${0}")")/.." && pwd)"; - [ -n ${TFENV_ROOT} ] || early_death "Failed to 'cd \"\$(dirname \"\$(readlink_f \"${0}\")\")/..\" && pwd' while trying to determine TFENV_ROOT"; -else - TFENV_ROOT="${TFENV_ROOT%/}"; -fi; -export TFENV_ROOT; - -if [ -n "${TFENV_HELPERS:-""}" ]; then - log 'debug' 'TFENV_HELPERS is set, not sourcing helpers again'; -else - [ "${TFENV_DEBUG:-0}" -gt 0 ] && echo "[DEBUG] Sourcing helpers from ${TFENV_ROOT}/lib/helpers.sh"; - if source "${TFENV_ROOT}/lib/helpers.sh"; then - log 'debug' 'Helpers sourced successfully'; - else - early_death "Failed to source helpers from ${TFENV_ROOT}/lib/helpers.sh"; - fi; -fi; +# Source common test setup +source "$(dirname "${0}")/test_common.sh"; ##################### # Begin Script Body # @@ -63,7 +22,7 @@ echo "terraform { tfenv install latest-allowed; tfenv use latest-allowed; check_active_version 1.1.9; -) || error_and_proceed 'Latest allowed version does not match'; +) || error_and_proceed 'Latest allowed version does not match. Requested: "~> 1.1.0", Expected: 1.1.9'; cleanup || log 'error' 'Cleanup failed?!'; @@ -78,7 +37,7 @@ 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'; +) || error_and_proceed 'Latest allowed tagged-version does not match. Requested: "<=0.13.0-rc1", Expected: 0.13.0-rc1'; cleanup || log 'error' 'Cleanup failed?!'; @@ -93,7 +52,7 @@ echo "terraform { tfenv install latest-allowed; tfenv use latest-allowed; check_active_version 0.15.5; -) || error_and_proceed 'Latest allowed incomplete-version does not match'; +) || error_and_proceed 'Latest allowed incomplete-version does not match. Requested: "~> 0.12", Expected: 0.15.5'; cleanup || log 'error' 'Cleanup failed?!'; @@ -108,7 +67,7 @@ echo 'latest-allowed' > .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 auto-installed version does not match. Requested: "~> 1.0.0", Expected: 1.0.11'; cleanup || log 'error' 'Cleanup failed?!'; @@ -124,7 +83,7 @@ echo 'latest-allowed' > chdir-dir/.terraform-version ( TFENV_AUTO_INSTALL=true terraform -chdir=chdir-dir version; check_active_version 0.14.11 chdir-dir; -) || error_and_proceed 'Latest allowed version from -chdir does not match'; +) || error_and_proceed 'Latest allowed version from -chdir does not match. Requested: "~> 0.14.3", Expected: 0.14.11'; cleanup || log 'error' 'Cleanup failed?!'; diff --git a/test/test_use_minrequired.sh b/test/test_use_minrequired.sh index b53b2fa..de25949 100755 --- a/test/test_use_minrequired.sh +++ b/test/test_use_minrequired.sh @@ -1,48 +1,7 @@ #!/usr/bin/env bash -set -uo pipefail; - -#################################### -# Ensure we can execute standalone # -#################################### - -function early_death() { - echo "[FATAL] ${0}: ${1}" >&2; - exit 1; -}; - -if [ -z "${TFENV_ROOT:-""}" ]; then - # http://stackoverflow.com/questions/1055671/how-can-i-get-the-behavior-of-gnus-readlink-f-on-a-mac - readlink_f() { - local target_file="${1}"; - local file_name; - - while [ "${target_file}" != "" ]; do - cd "$(dirname ${target_file})" || early_death "Failed to 'cd \$(dirname ${target_file})' while trying to determine TFENV_ROOT"; - file_name="$(basename "${target_file}")" || early_death "Failed to 'basename \"${target_file}\"' while trying to determine TFENV_ROOT"; - target_file="$(readlink "${file_name}")"; - done; - - echo "$(pwd -P)/${file_name}"; - }; - - TFENV_ROOT="$(cd "$(dirname "$(readlink_f "${0}")")/.." && pwd)"; - [ -n ${TFENV_ROOT} ] || early_death "Failed to 'cd \"\$(dirname \"\$(readlink_f \"${0}\")\")/..\" && pwd' while trying to determine TFENV_ROOT"; -else - TFENV_ROOT="${TFENV_ROOT%/}"; -fi; -export TFENV_ROOT; - -if [ -n "${TFENV_HELPERS:-""}" ]; then - log 'debug' 'TFENV_HELPERS is set, not sourcing helpers again'; -else - [ "${TFENV_DEBUG:-0}" -gt 0 ] && echo "[DEBUG] Sourcing helpers from ${TFENV_ROOT}/lib/helpers.sh"; - if source "${TFENV_ROOT}/lib/helpers.sh"; then - log 'debug' 'Helpers sourced successfully'; - else - early_death "Failed to source helpers from ${TFENV_ROOT}/lib/helpers.sh"; - fi; -fi; +# Source common test setup +source "$(dirname "${0}")/test_common.sh"; ##################### # Begin Script Body # @@ -55,7 +14,7 @@ cleanup || log 'error' 'Cleanup failed?!'; log 'info' '### Install min-required normal version (#.#.#)'; -minv='0.8.0'; +minv='1.6.0'; echo "terraform { required_version = \">=${minv}\" @@ -72,7 +31,7 @@ cleanup || log 'error' 'Cleanup failed?!'; log 'info' '### Install min-required tagged version (#.#.#-tag#)' -minv='0.13.0-rc1' +minv='1.5.0-rc1' echo "terraform { required_version = \">=${minv}\" @@ -89,7 +48,7 @@ cleanup || log 'error' 'Cleanup failed?!'; log 'info' '### Install min-required incomplete version (#.#.)' -minv='0.12'; +minv='1.3'; echo "terraform { required_version = \">=${minv}\" @@ -106,7 +65,7 @@ cleanup || log 'error' 'Cleanup failed?!'; log 'info' '### Install min-required with TFENV_AUTO_INSTALL'; -minv='1.0.0'; +minv='1.2.0'; echo "terraform { required_version = \">=${minv}\" @@ -121,7 +80,7 @@ echo 'min-required' > .terraform-version; cleanup || log 'error' 'Cleanup failed?!'; -log 'info' '### Install min-required with TFENV_AUTO_INSTALL & -chdir'; +log 'info' '### Install min-required with TFENV_AUTO_INSTALL & -chdir with rel path'; minv='1.1.0'; @@ -138,6 +97,24 @@ echo 'min-required' > chdir-dir/.terraform-version cleanup || log 'error' 'Cleanup failed?!'; + +log 'info' '### Install min-required with TFENV_AUTO_INSTALL & -chdir with abs path'; + +minv='1.2.3'; + +mkdir -p chdir-dir +echo "terraform { + required_version = \">=${minv}\" +}" >> chdir-dir/min_required.tf; +echo 'min-required' > chdir-dir/.terraform-version + +( + TFENV_AUTO_INSTALL=true terraform -chdir="${PWD}/chdir-dir" version; + check_active_version "${minv}" chdir-dir; +) || error_and_proceed 'Min required version from -chdir does not match'; + +cleanup || log 'error' 'Cleanup failed?!'; + if [ "${#errors[@]}" -gt 0 ]; then log 'warn' '===== The following use_minrequired tests failed ====='; for error in "${errors[@]}"; do