Skip to content

Commit

Permalink
Merge branch 'master' into fix_unzip_error
Browse files Browse the repository at this point in the history
  • Loading branch information
Zordrak authored May 26, 2020
2 parents 7f101e3 + fccc154 commit 1bc18a8
Show file tree
Hide file tree
Showing 17 changed files with 353 additions and 163 deletions.
8 changes: 3 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
before_install:
- 'if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; brew install bash; fi' # Bash4 Required
language: generic
matrix:
include:
Expand All @@ -10,10 +8,10 @@ matrix:
- os: linux
dist: trusty
- os: osx
osx_image: xcode11.2
osx_image: xcode11.3
- os: osx
osx_image: xcode10.3
#- os: osx
# osx_image: xcode9.4 # brew update is excruciatingly slow on xcode9.4
- os: osx
osx_image: xcode9.4
script:
- ./test/run.sh
8 changes: 6 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
## 2.0.0 (Unreleased)

* New logging library
* New bash4 dependency
* New logging and debugging library
* Massive testing, logging and loading refactoring
* Fix to 'use' logic: don't overwrite .terraform-version files
* Fix #167 - Never invoke use automatically on install - multiple code and testing changes for new logic
* Fix to not use 0.12.22 during testing which reports its version incorrectly
* Introduce tfenv-resolve-version to deduplicate translation of requested version into actual version
* README.md updates
* Fix #176 - New parameter TFENV_AUTO_INSTALL to handle the version specified by `use` or a `.terraform-version` file not being installed

## 1.0.2 (October 29, 2019)

Expand Down
32 changes: 29 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,19 +66,23 @@ include ::tfenv

### tfenv install [version]

Install a specific version of Terraform. Available options for version:
Install a specific version of Terraform.

If no parameter is passed, the version to use is resolved automatically via .terraform-version files, defaulting to 'latest' if none are found.

If a parameter is passed, available options:

- `i.j.k` exact version to install
- `latest` is a syntax to install latest version
- `latest:<regex>` is a syntax to install latest version matching regex (used by grep -e)
- `min-required` is a syntax to recursively 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](#min-required) section below.

```console
$ tfenv install
$ tfenv install 0.7.0
$ tfenv install latest
$ tfenv install latest:^0.8
$ tfenv install min-required
$ tfenv install
```

If `shasum` is present in the path, tfenv will verify the download against Hashicorp's published sha256 hash.
Expand Down Expand Up @@ -134,6 +138,16 @@ Specify architecture. Architecture other than the default amd64 can be specified
TFENV_ARCH=arm tfenv install 0.7.9
```

##### `TFENV_AUTO_INSTALL`

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_CURL_OUTPUT`

Integer (Default: 2)
Expand All @@ -146,6 +160,15 @@ Set the mechanism used for displaying download progress when downloading terrafo

##### `TFENV_DEBUG`

Integer (Default: 0)

Set the debug level for TFENV.

* 0: No debug output
* 1: Simple debug output
* 2: Extended debug output, with source file names and interactive debug shells on error
* 3: Debug level 2 + Bash execution tracing

##### `TFENV_REMOTE`

String (Default: https://releases.hashicorp.com)
Expand Down Expand Up @@ -279,17 +302,20 @@ Defaults to the PID of the calling process.



### tfenv use &lt;version>
### tfenv use [version]

Switch a version to use

If no parameter is passed, the version to use is resolved automatically via .terraform-version files, defaulting to 'latest' if none are found.

`latest` is a syntax to use the latest installed version

`latest:<regex>` is a syntax to use latest installed version matching regex (used by grep -e)

`min-required` will switch to the version minimally required by your terraform sources (see above `tfenv install`)

```console
$ tfenv use
$ tfenv use min-required
$ tfenv use 0.7.0
$ tfenv use latest
Expand Down
6 changes: 3 additions & 3 deletions bin/terraform
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ log 'debug' "program=\"${0##*/}\"";

declare tfenv_path="${TFENV_ROOT}/bin/tfenv";

log 'debug' "Exec: \"${tfenv_path}\" exec \"${@}\"";
exec "${tfenv_path}" exec "${@}" \
|| log 'error' "Failed to exec: \"${tfenv_path}\" exec \"${@}\"";
log 'debug' "Exec: \"${tfenv_path}\" exec \"$*\"";
exec "${tfenv_path}" exec "$@" \
|| log 'error' "Failed to exec: \"${tfenv_path}\" exec \"$*\"";

log 'error' 'This line should not be reachable. Something catastrophic has occurred';
4 changes: 2 additions & 2 deletions bin/tfenv
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ exit 1;
} | abort && exit 1;
fi;
shift 1;
log 'debug' "Exec: \"${command_path}\" \"${@}\"";
exec "${command_path}" "${@}";
log 'debug' "Exec: \"${command_path}\" \"$*\"";
exec "${command_path}" "$@";
;;
esac;

Expand Down
6 changes: 3 additions & 3 deletions lib/bashlog.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ function _log_exception() {
BASHLOG_JSON=0;
BASHLOG_SYSLOG=0;

log 'error' "Logging Exception: ${@}";
log 'error' "Logging Exception: $*";
);
};
export -f _log_exception;
Expand Down Expand Up @@ -39,7 +39,7 @@ function log() {

shift 1;

local line="${@}";
local line="$@";

# RFC 5424
#
Expand Down Expand Up @@ -154,7 +154,7 @@ function log() {
fi;
;;
*)
log 'error' "Undefined log level trying to log: ${@}";
log 'error' "Undefined log level trying to log: $*";
;;
esac
};
Expand Down
60 changes: 60 additions & 0 deletions lib/helpers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,66 @@ fi;

source "${TFENV_ROOT}/lib/bashlog.sh";

resolve_version () {
declare version_requested version regex min_required version_file;

declare arg="${1:-""}";

if [ -z "${arg}" ]; then
version_file="$(tfenv-version-file)";
log 'debug' "Version File: ${version_file}";

if [ "${version_file}" != "${TFENV_ROOT}/version" ]; then
log 'debug' "Version File (${version_file}) is not the default \${TFENV_ROOT}/version (${TFENV_ROOT}/version)";
version_requested="$(cat "${version_file}")" \
|| log 'error' "Failed to open ${version_file}";

elif [ -f "${version_file}" ]; then
log 'debug' "Version File is the default \${TFENV_ROOT}/version (${TFENV_ROOT}/version)";
version_requested="$(cat "${version_file}")" \
|| log 'error' "Failed to open ${version_file}";

# Absolute fallback
if [ -z "${version_requested}" ]; then
log 'debug' 'Version file had no content. Falling back to "latest"';
version_requested='latest';
fi;

else
log 'debug' "Version File is the default \${TFENV_ROOT}/version (${TFENV_ROOT}/version) but it doesn't exist";
log 'info' 'No version requested on the command line or in the version file search path. Installing "latest"';
version_requested='latest';
fi;
else
version_requested="${arg}";
fi;

log 'debug' "Version Requested: ${version_requested}";

if [[ "${version_requested}" =~ ^min-required$ ]]; then
log 'info' 'Detecting minimum required version...';
min_required="$(tfenv-min-required)" \
|| log 'error' 'tfenv-min-required failed';

log 'info' "Minimum required version detected: ${min_required}";
version_requested="${min_required}";
fi;

if [[ "${version_requested}" =~ ^latest\:.*$ ]]; then
version="${version_requested%%\:*}";
regex="${version_requested##*\:}";
log 'debug' "Version uses latest keyword with regex: ${regex}";
elif [[ "${version_requested}" =~ ^latest$ ]]; then
version="${version_requested}";
regex="^[0-9]\+\.[0-9]\+\.[0-9]\+$";
log 'debug' "Version uses latest keyword alone. Forcing regex to match stable versions only: ${regex}";
else
version="${version_requested}";
regex="^${version_requested}$";
log 'debug' "Version is explicit: ${version}. Regex enforces the version: ${regex}";
fi;
}

# Curl wrapper to switch TLS option for each OS
function curlw () {
local TLS_OPT="--tlsv1.2";
Expand Down
15 changes: 12 additions & 3 deletions libexec/tfenv-exec
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,21 @@ TFENV_VERSION="$(tfenv-version-name)" \
};
export TFENV_VERSION;

if [ ! -d "${TFENV_ROOT}/versions/${TFENV_VERSION}" ]; then
if [ "${TFENV_AUTO_INSTALL:-true}" == "true" ]; then
log 'info' "version '${TFENV_VERSION}' is not installed (set by $(tfenv-version-file)). Installing now as TFENV_AUTO_INSTALL==true";
tfenv-install;
else
log 'error' "version '${TFENV_VERSION}' was requested, but not installed and TFENV_AUTO_INSTALL is not 'true'";
fi;
fi;

TF_BIN_PATH="${TFENV_ROOT}/versions/${TFENV_VERSION}/terraform";
export PATH="${TF_BIN_PATH}:${PATH}";
log 'debug' "TF_BIN_PATH added to PATH: ${TF_BIN_PATH}";
log 'debug' "Executing: ${TF_BIN_PATH} ${@}";
log 'debug' "Executing: ${TF_BIN_PATH} $@";

exec "${TF_BIN_PATH}" "${@}" \
|| log 'error' "Failed to execute: ${TF_BIN_PATH} ${@}";
exec "${TF_BIN_PATH}" "$@" \
|| log 'error' "Failed to execute: ${TF_BIN_PATH} $*";

exit 0;
56 changes: 7 additions & 49 deletions libexec/tfenv-install
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#!/usr/bin/env bash

set -uo pipefail;

####################################
Expand Down Expand Up @@ -61,60 +60,20 @@ done;

[ "${#}" -gt 1 ] && log 'error' 'usage: tfenv install [<version>]';

declare version_requested version regex;
declare arg="${1:-""}";

if [ -z "${arg}" ]; then
version_file="$(tfenv-version-file)";
log 'debug' "Version File: ${version_file}";
if [ "${version_file}" != "${TFENV_ROOT}/version" ]; then
log 'debug' "Version File (${version_file}) is not the default \${TFENV_ROOT}/version (${TFENV_ROOT}/version)";
version_requested="$(cat "${version_file}")" \
|| log 'error' "Failed to open ${version_file}";
elif [ -f "${version_file}" ]; then
log 'debug' "Version File is the default \${TFENV_ROOT}/version (${TFENV_ROOT}/version)";
version_requested="$(cat "${version_file}")" \
|| log 'error' "Failed to open ${version_file}";
else
log 'debug' "Version File is the default \${TFENV_ROOT}/version (${TFENV_ROOT}/version) but it doesn't exist";
log 'info' 'No version requested on the command line or in the version file search path. Installing "latest"';
version_requested='latest';
fi;
else
version_requested="${arg}";
fi;

log 'debug' "Version Requested: ${version_requested}";
declare requested="${1:-""}";

if [[ "${version_requested}" =~ ^min-required$ ]]; then
log 'info' 'Detecting minimal required version...';
found_min_required="$(tfenv-min-required)";
log debug "Resolving version with: tfenv-resolve-version ${requested}";
declare resolved="$(tfenv-resolve-version ${requested})";

if [[ $? -eq 0 ]]; then
log 'info' "Min required version is detected as ${found_min_required}";
version_requested="${found_min_required}";
else
exit 1;
fi;
fi;

if [[ "${version_requested}" =~ ^latest\:.*$ ]]; then
version="${version_requested%%\:*}";
regex="${version_requested##*\:}";
elif [[ "${version_requested}" =~ ^latest$ ]]; then
version="${version_requested}";
regex="^[0-9]\+\.[0-9]\+\.[0-9]\+$";
else
version="${version_requested}";
regex="^${version_requested}$";
fi;
declare version="${resolved%%\:*}";
declare regex="${resolved##*\:}";

[ -n "${version}" ] || log 'error' 'Version is not specified. This should not be possible as we default to latest';

log 'debug' "Processing install for version ${version}, using regex ${regex}";

version="$(tfenv-list-remote | grep -e "${regex}" | head -n 1)";
[ -n "${version}" ] || log 'error' "No versions matching '${arg}' found in remote";
[ -n "${version}" ] || log 'error' "No versions matching '${requested}' found in remote";

dst_path="${TFENV_ROOT}/versions/${version}";
if [ -f "${dst_path}/terraform" ]; then
Expand Down Expand Up @@ -279,5 +238,4 @@ while IFS= read -r unzip_line; do
log 'info' "${unzip_line}";
done < <(printf '%s\n' "${unzip_output}");

log 'info' "Installation of terraform v${version} successful";
tfenv-use "${version}";
log 'info' "Installation of terraform v${version} successful. To make this your default version, run 'tfenv use ${version}'";
Loading

0 comments on commit 1bc18a8

Please sign in to comment.