Skip to content

Commit

Permalink
Merge branch 'master' into bug/210-debug
Browse files Browse the repository at this point in the history
  • Loading branch information
Zordrak authored Aug 14, 2021
2 parents 8bff19e + 4e75af3 commit 9de735e
Show file tree
Hide file tree
Showing 12 changed files with 108 additions and 85 deletions.
1 change: 0 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ jobs:
- 'macos-10.15'
- 'ubuntu-20.04'
- 'ubuntu-18.04'
- 'ubuntu-16.04'
- 'windows-2019'
steps:
- uses: 'actions/checkout@v2'
Expand Down
83 changes: 46 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ Currently tfenv supports the following OSes

Install via Homebrew

```console
$ brew install tfenv
```
```console
$ brew install tfenv
```

Install via Arch User Repository (AUR)

```console
$ yay --sync tfenv
```
```console
$ yay --sync tfenv
```

Install via puppet

Expand All @@ -42,31 +42,31 @@ include ::tfenv

1. Check out tfenv into any path (here is `${HOME}/.tfenv`)

```console
$ git clone https://github.com/tfutils/tfenv.git ~/.tfenv
```
```console
$ git clone https://github.com/tfutils/tfenv.git ~/.tfenv
```

2. Add `~/.tfenv/bin` to your `$PATH` any way you like

```console
$ echo 'export PATH="$HOME/.tfenv/bin:$PATH"' >> ~/.bash_profile
```
```console
$ echo 'export PATH="$HOME/.tfenv/bin:$PATH"' >> ~/.bash_profile
```

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
```
```console
$ 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
```
```console
$ mkdir -p ~/.local/bin/
$ . ~/.profile
$ ln -s ~/.tfenv/bin/* ~/.local/bin
$ which tfenv
```

## Usage

Expand All @@ -78,7 +78,7 @@ If no parameter is passed, the version to use is resolved automatically via [.te

If a parameter is passed, available options:

- `i.j.k` exact version to install
- `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:<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.
Expand Down Expand Up @@ -110,7 +110,7 @@ validation failure.

#### .terraform-version

If you use a [.terraform-version file](#terraform-version-file), `tfenv install` (no argument) will install the version written in it.
If you use a [.terraform-version](#terraform-version-file) file, `tfenv install` (no argument) will install the version written in it.

#### min-required

Expand Down Expand Up @@ -141,7 +141,7 @@ String (Default: amd64)
Specify architecture. Architecture other than the default amd64 can be specified with the `TFENV_ARCH` environment variable

```console
TFENV_ARCH=arm tfenv install 0.7.9
$ TFENV_ARCH=arm tfenv install 0.7.9
```

##### `TFENV_AUTO_INSTALL`
Expand All @@ -151,7 +151,7 @@ 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
```

##### `TFENV_CURL_OUTPUT`
Expand Down Expand Up @@ -182,7 +182,17 @@ 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_CONFIG_DIR`

Path (Default: `$TFENV_ROOT`)

The path to a directory where the local terraform versions and configuration files exist.

```console
TFENV_CONFIG_DIR="$XDG_CONFIG_HOME/tfenv"
```

##### `TFENV_TERRAFORM_VERSION`
Expand All @@ -196,7 +206,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
```

#### Bashlog Logging Library
Expand Down Expand Up @@ -237,7 +247,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`
Expand All @@ -259,7 +269,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.

Expand All @@ -275,7 +285,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`
Expand All @@ -299,11 +309,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`
Expand Down Expand Up @@ -359,7 +368,7 @@ $ tfenv uninstall latest:^0.8
List installed versions

```console
% tfenv list
$ tfenv list
* 0.10.7 (set by /opt/tfenv/version)
0.9.0-beta2
0.8.8
Expand All @@ -376,7 +385,7 @@ List installed versions
List installable versions

```console
% tfenv list-remote
$ tfenv list-remote
0.9.0-beta2
0.9.0-beta1
0.8.8
Expand Down
19 changes: 13 additions & 6 deletions lib/helpers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ else
fi;
export TFENV_ROOT;

if [ -z "${TFENV_CONFIG_DIR:-""}" ]; then
TFENV_CONFIG_DIR="$TFENV_ROOT";
else
TFENV_CONFIG_DIR="${TFENV_CONFIG_DIR%/}";
fi
export TFENV_CONFIG_DIR;

if [ "${TFENV_DEBUG:-0}" -gt 0 ]; then
# Only reset DEBUG if TFENV_DEBUG is set, and DEBUG is unset or already a number
if [[ "${DEBUG:-0}" =~ ^[0-9]+$ ]] && [ "${DEBUG:-0}" -gt "${TFENV_DEBUG:-0}" ]; then
Expand All @@ -46,13 +53,13 @@ resolve_version () {
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)";
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}")" \
|| 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)";
log 'debug' "Version File is the default \${TFENV_CONFIG_DIR}/version (${TFENV_CONFIG_DIR}/version)";
version_requested="$(cat "${version_file}")" \
|| log 'error' "Failed to open ${version_file}";

Expand All @@ -63,7 +70,7 @@ resolve_version () {
fi;

else
log 'debug' "Version File is the default \${TFENV_ROOT}/version (${TFENV_ROOT}/version) but it doesn't exist";
log 'debug' "Version File is the default \${TFENV_CONFIG_DIR}/version (${TFENV_CONFIG_DIR}/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;
Expand Down Expand Up @@ -121,14 +128,14 @@ export -f check_active_version;

check_installed_version() {
local v="${1}";
local bin="${TFENV_ROOT}/versions/${v}/terraform";
local bin="${TFENV_CONFIG_DIR}/versions/${v}/terraform";
[ -n "$(${bin} version | grep -E "^Terraform v${v}((-dev)|( \([a-f0-9]+\)))?$")" ];
};
export -f check_installed_version;

check_default_version() {
local v="${1}";
local def="$(cat "${TFENV_ROOT}/version")";
local def="$(cat "${TFENV_CONFIG_DIR}/version")";
[ "${def}" == "${v}" ];
};
export -f check_default_version;
Expand Down
4 changes: 2 additions & 2 deletions libexec/tfenv-exec
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ TFENV_VERSION="$(tfenv-version-name)" \
};
export TFENV_VERSION;

if [ ! -d "${TFENV_ROOT}/versions/${TFENV_VERSION}" ]; then
if [ ! -d "${TFENV_CONFIG_DIR}/versions/${TFENV_VERSION}" ]; then
if [ "${TFENV_AUTO_INSTALL:-true}" == "true" ]; then
if [ -z "${TFENV_TERRAFORM_VERSION:-""}" ]; then
TFENV_VERSION_SOURCE="$(tfenv-version-file)";
Expand All @@ -97,7 +97,7 @@ if [ ! -d "${TFENV_ROOT}/versions/${TFENV_VERSION}" ]; then
fi;
fi;

TF_BIN_PATH="${TFENV_ROOT}/versions/${TFENV_VERSION}/terraform";
TF_BIN_PATH="${TFENV_CONFIG_DIR}/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} $@";
Expand Down
23 changes: 16 additions & 7 deletions libexec/tfenv-install
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,22 @@ 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 '${requested}' found in remote";

dst_path="${TFENV_ROOT}/versions/${version}";
dst_path="${TFENV_CONFIG_DIR}/versions/${version}";
if [ -f "${dst_path}/terraform" ]; then
echo "Terraform v${version} is already installed";
exit 0;
fi;

TFENV_ARCH="${TFENV_ARCH:-amd64}";
# Add support of ARM64 for Linux & Apple Silicon
case "$(uname -m)" in
aarch64* | arm64*)
TFENV_ARCH="${TFENV_ARCH:-arm64}";
;;
*)
TFENV_ARCH="${TFENV_ARCH:-amd64}";
;;
esac;

case "$(uname -s)" in
Darwin*)
os="darwin_${TFENV_ARCH}";
Expand Down Expand Up @@ -171,12 +180,12 @@ if [[ $(uname) == 'Darwin' ]] && [ $(which brew) ]; then
fi

# Verify signature if verification mechanism (keybase, gpg, etc) is present
if [[ -f "${TFENV_ROOT}/use-gnupg" ]]; then
if [[ -f "${TFENV_CONFIG_DIR}/use-gnupg" ]]; then
# GnuPG uses the user's keyring, and any web-of-trust or local signatures or
# anything else they have setup. This is the crazy-powerful mode which is
# overly confusing to newcomers. We don't support it without the user creating
# the file use-gnupg, optionally with directives in it.
gnupg_command="$(sed -E -n -e 's/^binary: *//p' <"${TFENV_ROOT}/use-gnupg")";
gnupg_command="$(sed -E -n -e 's/^binary: *//p' <"${TFENV_CONFIG_DIR}/use-gnupg")";
[[ -n "${gnupg_command}" ]] || gnupg_command=gpg;

download_signature;
Expand All @@ -187,13 +196,13 @@ if [[ -f "${TFENV_ROOT}/use-gnupg" ]]; then
"${download_tmp}/${shasums_name}" \
|| log 'error' 'PGP signature rejected by GnuPG';

elif [[ -f "${TFENV_ROOT}/use-gpgv" ]]; then
elif [[ -f "${TFENV_CONFIG_DIR}/use-gpgv" ]]; then
# gpgv is a much simpler interface to verification, but does require that the
# key have been downloaded and marked trusted.
# We don't force the caller to trust the tfenv repo's copy of their key, they
# have to choose to make that trust decision.
gpgv_command="$(sed -E -n -e 's/^binary: *//p' <"${TFENV_ROOT}/use-gpgv")";
trust_tfenv="$(sed -E -n -e 's/^trust.?tfenv: *//p' <"${TFENV_ROOT}/use-gpgv")";
gpgv_command="$(sed -E -n -e 's/^binary: *//p' <"${TFENV_CONFIG_DIR}/use-gpgv")";
trust_tfenv="$(sed -E -n -e 's/^trust.?tfenv: *//p' <"${TFENV_CONFIG_DIR}/use-gpgv")";
[[ -n "${gpgv_command}" ]] || gpgv_command=gpgv;

download_signature;
Expand Down
8 changes: 4 additions & 4 deletions libexec/tfenv-list
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,11 @@ done;
[ "${#}" -ne 0 ] \
&& log 'error' "usage: tfenv list"

[ -d "${TFENV_ROOT}/versions" ] \
[ -d "${TFENV_CONFIG_DIR}/versions" ] \
|| log 'error' 'No versions available. Please install one with: tfenv install'

[[ -x "${TFENV_ROOT}/versions" && -r "${TFENV_ROOT}/versions" ]] \
|| log 'error' "tfenv versions directory is inaccessible: ${TFENV_ROOT}/versions";
[[ -x "${TFENV_CONFIG_DIR}/versions" && -r "${TFENV_CONFIG_DIR}/versions" ]] \
|| log 'error' "tfenv versions directory is inaccessible: ${TFENV_CONFIG_DIR}/versions";

version_name="$(tfenv-version-name 2>/dev/null || true)" \
&& log 'debug' "tfenv-version-name reported: ${version_name}";
Expand Down Expand Up @@ -94,7 +94,7 @@ print_version () {
};

log 'debug' 'Listing versions...';
local_versions=($(\find "${TFENV_ROOT}/versions" -type d -exec basename {} \; \
local_versions=($(\find "${TFENV_CONFIG_DIR}/versions/" -type d -exec basename {} \; \
| tail -n +2 \
| sort -t'.' -k 1nr,1 -k 2nr,2 -k 3nr,3));

Expand Down
8 changes: 4 additions & 4 deletions libexec/tfenv-min-required
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ fi;
for dir in libexec bin; do
case ":${PATH}:" in
*:${TFENV_ROOT}/${dir}:*) log 'debug' "\$PATH already contains '${TFENV_ROOT}/${dir}', not adding it again";;
*)
*)
log 'debug' "\$PATH does not contain '${TFENV_ROOT}/${dir}', prepending and exporting it now";
export PATH="${TFENV_ROOT}/${dir}:${PATH}";
;;
Expand All @@ -63,7 +63,7 @@ done;

bailout() {
log 'error' 'Error: Could not determine required_version based on your terraform sources.
Make sure at least one of your *tf files includes a required version section like
Make sure at least one of your *tf or *.tf.json files includes a required version section like
terraform {
required_version = ">= 0.0.0"
}
Expand All @@ -73,8 +73,8 @@ see https://www.terraform.io/docs/configuration/terraform.html for details';

find_min_required() {
local root="${1}";
versions="$( echo $(grep -h required_version "${root}"/*.tf 2>/dev/null ) | grep -o '\([0-9]\+\.\?\)\{2,3\}\(-[a-z]\+[0-9]\+\)\?')";

versions="$( echo $(grep -h required_version "${root}"/{*.tf,*.tf.json} 2>/dev/null ) | grep -o '\([0-9]\+\.\?\)\{2,3\}\(-[a-z]\+[0-9]\+\)\?')";

if [[ "${versions}" =~ ([~=!<>]{0,2}[[:blank:]]*[0-9]+[0-9.]+)[^0-9]*(-[a-z]+[0-9]+)? ]]; then
found_min_required="${BASH_REMATCH[1]}${BASH_REMATCH[2]}"
Expand Down
Loading

0 comments on commit 9de735e

Please sign in to comment.