├── .editorconfig ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── PULL_REQUEST │ └── pull_request_template.md ├── dependabot.yml └── workflows │ ├── build.yml │ ├── lint.yml │ ├── release.yml │ ├── semantic-pr.yml │ └── test.yml ├── .tool-versions ├── CHANGELOG.md ├── LICENSE ├── README.md ├── bin ├── download ├── help.links ├── help.overview ├── install ├── latest-stable ├── list-all ├── list-legacy-filenames └── parse-legacy-file ├── contributing.md ├── lib └── utils.bash ├── renovate.json ├── scripts ├── format.bash └── lint.bash ├── test └── parse-legacy-file.bats └── version.txt /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = tab 5 | end_of_line = lf 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | 10 | [*.{md,yml,yaml}] 11 | indent_style = space 12 | indent_size = 2 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "" 5 | labels: bug 6 | assignees: "" 7 | --- 8 | 9 | **Describe the bug** 10 | 11 | 12 | 13 | **Steps to reproduce** 14 | 15 | 16 | 17 | **Expected behavior** 18 | 19 | 20 | 21 | **Screenshots** 22 | 23 | 24 | 25 | **Additional context** 26 | 27 | 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "" 5 | labels: enhancement 6 | assignees: "" 7 | --- 8 | 9 | **Is your feature request related to a problem? Please describe.** 10 | 11 | 12 | 13 | **Describe the solution you'd like** 14 | 15 | 16 | 17 | **Describe alternatives you've considered** 18 | 19 | 20 | 21 | **Additional context** 22 | 23 | 24 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Description 4 | 5 | 6 | 7 | ## Motivation and Context 8 | 9 | 10 | 11 | 12 | ## Types of changes 13 | 14 | 15 | 16 | - [ ] Bug fix (non-breaking change which fixes an issue) 17 | - [ ] New feature (non-breaking change which adds functionality) 18 | - [ ] Breaking change (fix or feature that would cause existing functionality to change) 19 | 20 | ## Usage examples 21 | 22 | 23 | 24 | ## How Has This Been Tested? 25 | 26 | 27 | 28 | ## Checklist 29 | 30 | 31 | 32 | 33 | - [ ] I have updated the documentation accordingly. 34 | - [ ] I have added tests to cover my changes. 35 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | 9 | jobs: 10 | plugin_test: 11 | name: asdf plugin test 12 | strategy: 13 | fail-fast: false 14 | matrix: 15 | os: 16 | - ubuntu-latest 17 | - macos-latest 18 | - macos-14 19 | cosign: 20 | - true 21 | - false 22 | runs-on: ${{ matrix.os }} 23 | steps: 24 | - name: Install Cosign 25 | if: ${{ matrix.cosign }} 26 | uses: sigstore/cosign-installer@v3 27 | - name: Get Cosign version 28 | if: ${{ matrix.cosign }} 29 | run: cosign version 30 | - name: asdf_plugin_test 31 | uses: asdf-vm/actions/plugin-test@v4 32 | with: 33 | command: tofu version 34 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | 9 | jobs: 10 | lint: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v4 14 | - uses: asdf-vm/actions/install@v4 15 | - run: scripts/lint.bash 16 | 17 | actionlint: 18 | runs-on: ubuntu-latest 19 | steps: 20 | - uses: actions/checkout@v4 21 | - name: Check workflow files 22 | uses: docker://rhysd/actionlint:1.7.7 23 | with: 24 | args: -color 25 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | permissions: 9 | contents: write 10 | pull-requests: write 11 | 12 | jobs: 13 | release-please: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: GoogleCloudPlatform/release-please-action@v4 17 | with: 18 | release-type: simple 19 | -------------------------------------------------------------------------------- /.github/workflows/semantic-pr.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: 4 | pull_request_target: 5 | types: 6 | - opened 7 | - edited 8 | - synchronize 9 | 10 | jobs: 11 | semantic-pr: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: amannn/action-semantic-pull-request@v5.5.3 15 | env: 16 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 17 | with: 18 | validateSingleCommit: true 19 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | 9 | jobs: 10 | test: 11 | name: bats 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - name: Checkout 16 | uses: actions/checkout@v4 17 | with: 18 | fetch-depth: 0 19 | 20 | - name: Install bats 21 | run: npm install bats@1.11.0 22 | 23 | - name: Run tests 24 | run: npm exec -- bats test/*.bats 25 | -------------------------------------------------------------------------------- /.tool-versions: -------------------------------------------------------------------------------- 1 | shellcheck 0.10.0 2 | shfmt 3.11.0 3 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [1.2.0](https://github.com/virtualroot/asdf-opentofu/compare/v1.1.4...v1.2.0) (2024-09-19) 4 | 5 | 6 | ### Features 7 | 8 | * support for legacy_version_file mode ([#38](https://github.com/virtualroot/asdf-opentofu/issues/38)) ([b44c09e](https://github.com/virtualroot/asdf-opentofu/commit/b44c09e70286b534bc2bcbbcb238d09728f72e4e)) 9 | 10 | ## [1.1.4](https://github.com/virtualroot/asdf-opentofu/compare/v1.1.3...v1.1.4) (2024-01-05) 11 | 12 | 13 | ### Bug Fixes 14 | 15 | * Change to regexp for certificate-identity URL ([#24](https://github.com/virtualroot/asdf-opentofu/issues/24)) ([f6e1873](https://github.com/virtualroot/asdf-opentofu/commit/f6e18730f914464ecf29150d78286c562493d0df)) 16 | 17 | ## [1.1.3](https://github.com/virtualroot/asdf-opentofu/compare/v1.1.2...v1.1.3) (2023-12-19) 18 | 19 | 20 | ### Bug Fixes 21 | 22 | * Change certificate-identity URL ([#21](https://github.com/virtualroot/asdf-opentofu/issues/21)) ([4f301b1](https://github.com/virtualroot/asdf-opentofu/commit/4f301b1b68c305ae5cac94b5ddfdca0374380431)) 23 | 24 | ## [1.1.2](https://github.com/virtualroot/asdf-opentofu/compare/v1.1.1...v1.1.2) (2023-12-19) 25 | 26 | 27 | ### Bug Fixes 28 | 29 | * typo in URL :( ([28d8a07](https://github.com/virtualroot/asdf-opentofu/commit/28d8a0764049bb27273350c59f2f337bfe0bac50)) 30 | 31 | ## [1.1.1](https://github.com/virtualroot/asdf-opentofu/compare/v1.1.0...v1.1.1) (2023-12-19) 32 | 33 | 34 | ### Bug Fixes 35 | 36 | * Change certificate-identity URL ([#18](https://github.com/virtualroot/asdf-opentofu/issues/18)) ([f8efc56](https://github.com/virtualroot/asdf-opentofu/commit/f8efc5627907c7da24e7b9cb52aad95184742dd1)) 37 | 38 | ## [1.1.0](https://github.com/virtualroot/asdf-opentofu/compare/v1.0.0...v1.1.0) (2023-11-11) 39 | 40 | 41 | ### Features 42 | 43 | * add help output for asdf ([6534fc2](https://github.com/virtualroot/asdf-opentofu/commit/6534fc2e4000baac11cdee4bceefaf0b7e7ffb84)) 44 | 45 | ## 1.0.0 (2023-10-11) 46 | 47 | 48 | ### Features 49 | 50 | * add signature verification ([dca8208](https://github.com/virtualroot/asdf-opentofu/commit/dca82086a87e9c166743eb93ea0fe6c1a8cf759a)) 51 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Alejandro Lazaro 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | # asdf-opentofu [![Build](https://github.com/virtualroot/asdf-opentofu/actions/workflows/build.yml/badge.svg)](https://github.com/virtualroot/asdf-opentofu/actions/workflows/build.yml) [![Lint](https://github.com/virtualroot/asdf-opentofu/actions/workflows/lint.yml/badge.svg)](https://github.com/virtualroot/asdf-opentofu/actions/workflows/lint.yml) 4 | 5 | Official [opentofu](https://opentofu.org/) plugin for the [asdf version manager](https://asdf-vm.com). 6 | 7 |
8 | 9 | # Contents 10 | 11 | - [Dependencies](#dependencies) 12 | - [Install](#install) 13 | - [Contributing](#contributing) 14 | - [License](#license) 15 | 16 | # Dependencies 17 | 18 | - `bash`, `curl`, `unzip` 19 | - `cosign`: (optional) If installed, asdf will perform signature verification 20 | 21 | # Install 22 | 23 | Plugin: 24 | 25 | ```shell 26 | asdf plugin add opentofu 27 | # or 28 | asdf plugin add opentofu https://github.com/virtualroot/asdf-opentofu.git 29 | ``` 30 | 31 | OpenTofu: 32 | 33 | ```shell 34 | # Show all installable versions 35 | asdf list-all opentofu 36 | 37 | # Install a specific version 38 | asdf install opentofu latest 39 | 40 | # Set a version globally (on your ~/.tool-versions file) 41 | asdf global opentofu latest 42 | 43 | # Now OpenTofu commands are available 44 | tofu version 45 | ``` 46 | 47 | Check [asdf](https://github.com/asdf-vm/asdf) readme for more instructions on how to 48 | install & manage versions. 49 | 50 | # Environment Variable Options 51 | 52 | * `ASDF_OPENTOFU_SKIP_VERIFY`: skip verifying checksums and signatures (default: `false`) 53 | * `ASDF_OPENTOFU_VERSION_FILE`: Which .tofu-file to examine for version constraints when using the `legacy_version_file` option in `~/.asdfrc`. (default: `main.tofu`) 54 | 55 | # Contributing 56 | 57 | Contributions of any kind are welcome! See the [contributing guide](contributing.md). 58 | 59 | [Thanks goes to these contributors](https://github.com/virtualroot/asdf-opentofu/graphs/contributors)! 60 | 61 | # License 62 | 63 | See [LICENSE](LICENSE) © [Alejandro Lazaro](https://github.com/virtualroot/) 64 | -------------------------------------------------------------------------------- /bin/download: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euo pipefail 4 | 5 | current_script_path=${BASH_SOURCE[0]} 6 | plugin_dir=$(dirname "$(dirname "$current_script_path")") 7 | 8 | # shellcheck source=./lib/utils.bash 9 | source "${plugin_dir}/lib/utils.bash" 10 | 11 | mkdir -p "$ASDF_DOWNLOAD_PATH" 12 | 13 | # Download zip file to the download directory 14 | download_release "$ASDF_INSTALL_VERSION" 15 | -------------------------------------------------------------------------------- /bin/help.links: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euo pipefail 4 | 5 | current_script_path=${BASH_SOURCE[0]} 6 | plugin_dir=$(dirname "$(dirname "${current_script_path}")") 7 | 8 | # shellcheck source=./lib/utils.bash 9 | source "${plugin_dir}/lib/utils.bash" 10 | 11 | cat <&2 23 | if [[ "$redirect_url" == "$GH_REPO/releases" ]]; then 24 | version="$(list_all_versions | sort_versions | tail -n1 | xargs echo)" 25 | else 26 | version="$(printf "%s\n" "$redirect_url" | sed 's|.*/tag/v\{0,1\}||')" 27 | fi 28 | 29 | printf "%s\n" "$version" 30 | -------------------------------------------------------------------------------- /bin/list-all: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euo pipefail 4 | 5 | current_script_path=${BASH_SOURCE[0]} 6 | plugin_dir=$(dirname "$(dirname "$current_script_path")") 7 | 8 | # shellcheck source=./lib/utils.bash 9 | source "${plugin_dir}/lib/utils.bash" 10 | 11 | list_all_versions | sort_versions | xargs echo 12 | -------------------------------------------------------------------------------- /bin/list-legacy-filenames: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # SPDX-License-Identifier: MIT 4 | # SPDX-FileCopyrightText: Copyright (c) 2017 Jack Henry & Associates 5 | 6 | echo ".opentofu-version ${ASDF_OPENTOFU_VERSION_FILE:-main.tofu}" 7 | -------------------------------------------------------------------------------- /bin/parse-legacy-file: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # SPDX-License-Identifier: MIT 4 | # SPDX-FileCopyrightText: Copyright (c) 2017 Jack Henry & Associates 5 | 6 | set -Eeuo pipefail 7 | 8 | [[ -n ${DEBUG-} ]] && set -x 9 | 10 | # override is exposed for testing purposes. 11 | THIS_PLUGIN="${ASDF_OPENTOFU_THIS_PLUGIN:-"$(basename "$(dirname "$(dirname "$0")")")"}" 12 | SUPPORTED_PLUGINS=(opentofu) 13 | 14 | is_strict_equality_version_constraint() { 15 | local -r version_constraint="$1" 16 | grep --quiet -E '^=?[[:digit:]]+\.[[:digit:]]+.[[:digit:]]+' <<<"${version_constraint}" 17 | } 18 | 19 | read_version_from_main_tofu() { 20 | local -r version_file="$1" 21 | local -r required_version_constraint="$(grep --no-filename \ 22 | --recursive \ 23 | --fixed-strings \ 24 | required_version \ 25 | "${version_file}" | 26 | sed -E 's/[[:space:]]*required_version[[:space:]]*=//' | 27 | tr -d '" ')" 28 | 29 | [[ -z ${required_version_constraint} ]] && return 0 30 | 31 | if is_strict_equality_version_constraint "${required_version_constraint}"; then 32 | tr -d '=' <<<"${required_version_constraint}" 33 | else 34 | cat >&2 < [--asdf-tool-version ] [--asdf-plugin-gitref ] [test-command*] 7 | 8 | asdf plugin test opentofu https://github.com/virtualroot/asdf-opentofu.git "tofu version" 9 | ``` 10 | 11 | Tests are automatically run in GitHub Actions on push and PR. 12 | -------------------------------------------------------------------------------- /lib/utils.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euo pipefail 4 | 5 | GH_REPO="https://github.com/opentofu/opentofu" 6 | TOOL_BIN_NAME="tofu" 7 | TOOL_NAME="opentofu" 8 | TOOL_TEST="tofu version" 9 | SKIP_VERIFY=${ASDF_OPENTOFU_SKIP_VERIFY:-"false"} 10 | 11 | fail() { 12 | echo -e "asdf-$TOOL_NAME: $*" 13 | exit 1 14 | } 15 | 16 | curl_opts=(-fsSL) 17 | 18 | # NOTE: You might want to remove this if opentofu is not hosted on GitHub releases. 19 | if [ -n "${GITHUB_API_TOKEN:-}" ]; then 20 | curl_opts=("${curl_opts[@]}" -H "Authorization: token $GITHUB_API_TOKEN") 21 | fi 22 | 23 | sort_versions() { 24 | sed 'h; s/[+-]/./g; s/.p\([[:digit:]]\)/.z\1/; s/$/.z/; G; s/\n/ /' | 25 | LC_ALL=C sort -t. -k 1,1 -k 2,2n -k 3,3n -k 4,4n -k 5,5n | awk '{print $2}' 26 | } 27 | 28 | list_github_tags() { 29 | git ls-remote --tags --refs "$GH_REPO" | 30 | grep -o 'refs/tags/.*' | cut -d/ -f3- | 31 | sed 's/^v//' # NOTE: You might want to adapt this sed to remove non-version strings from tags 32 | } 33 | 34 | list_all_versions() { 35 | # Change this function if opentofu has other means of determining installable versions. 36 | list_github_tags 37 | } 38 | 39 | get_platform() { 40 | local -r kernel="$(uname -s)" 41 | if [[ ${OSTYPE} == "msys" || ${kernel} == "CYGWIN"* || ${kernel} == "MINGW"* ]]; then 42 | echo windows 43 | else 44 | uname | tr '[:upper:]' '[:lower:]' 45 | fi 46 | } 47 | 48 | get_arch() { 49 | local -r machine="$(uname -m)" 50 | 51 | if [[ ${machine} == "arm64" ]] || [[ ${machine} == "aarch64" ]]; then 52 | echo "arm64" 53 | elif [[ ${machine} == *"arm"* ]] || [[ ${machine} == *"aarch"* ]]; then 54 | echo "arm" 55 | elif [[ ${machine} == *"386"* ]]; then 56 | echo "386" 57 | else 58 | echo "amd64" 59 | fi 60 | } 61 | 62 | get_release_file() { 63 | echo "${ASDF_DOWNLOAD_PATH}/${TOOL_NAME}-${ASDF_INSTALL_VERSION}.zip" 64 | } 65 | 66 | download_release() { 67 | local version filename url 68 | version="$1" 69 | local -r filename="$(get_release_file)" 70 | local -r platform="$(get_platform)" 71 | local -r arch="$(get_arch)" 72 | 73 | url="$GH_REPO/releases/download/v${version}/${TOOL_BIN_NAME}_${version}_${platform}_${arch}.zip" 74 | 75 | echo "* Downloading $TOOL_NAME release v$version..." 76 | curl "${curl_opts[@]}" -o "$filename" -C - "$url" || fail "Could not download $url" 77 | 78 | # Extract contents of zip file into the download directory 79 | unzip -qq "$filename" -d "$ASDF_DOWNLOAD_PATH" || fail "Could not extract $filename" 80 | } 81 | 82 | install_version() { 83 | local install_type="$1" 84 | local version="$2" 85 | local install_path="${3%/bin}/bin" 86 | 87 | if [ "$install_type" != "version" ]; then 88 | fail "asdf-$TOOL_NAME supports release installs only" 89 | fi 90 | 91 | if command -v cosign >/dev/null 2>&1 && [ "$SKIP_VERIFY" == "false" ]; then 92 | echo "Verifying signatures and checksums" 93 | verify "$version" "$ASDF_DOWNLOAD_PATH" 94 | else 95 | echo "Skipping verifying signatures and checksums either because cosign is not installed or explicitly skipped with ASDF_OPENTOFU_SKIP_VERIFY" 96 | fi 97 | 98 | ( 99 | mkdir -p "$install_path" 100 | cp -r "$ASDF_DOWNLOAD_PATH"/* "$install_path" 101 | 102 | local tool_cmd 103 | tool_cmd="$(echo "$TOOL_TEST" | cut -d' ' -f1)" 104 | test -x "$install_path/$tool_cmd" || fail "Expected $install_path/$tool_cmd to be executable." 105 | 106 | echo "$TOOL_NAME $version installation was successful!" 107 | rm "$(get_release_file)" 108 | ) || ( 109 | rm -rf "$install_path" 110 | fail "An error occurred while installing $TOOL_NAME $version." 111 | ) 112 | } 113 | 114 | verify() { 115 | local -r version="$1" 116 | local -r download_path="$2" 117 | local -r checksum_file="${TOOL_BIN_NAME}_${version}_SHA256SUMS" 118 | local -r signature_file="${checksum_file}.sig" 119 | local -r cert_file="${checksum_file}.pem" 120 | local -r cert_identity="https://github\.com/opentofu/opentofu/\.github/workflows/release\.yml@refs/(heads|tags)/(main|v1\..+)" 121 | local -r cert_oidc_issuer="https://token.actions.githubusercontent.com" 122 | 123 | baseURL="$GH_REPO/releases/download/v${version}" 124 | local files=("$checksum_file" "$signature_file" "$cert_file") 125 | echo "* Downloading signature files ..." 126 | for file in "${files[@]}"; do 127 | curl "${curl_opts[@]}" -o "${download_path}/${file}" "${baseURL}/${file}" || fail "Could not download ${baseURL}/${file}" 128 | done 129 | 130 | if ! ( 131 | cosign verify-blob --signature "${download_path}/${signature_file}" \ 132 | --certificate "${download_path}/${cert_file}" \ 133 | --certificate-identity-regexp="${cert_identity}" \ 134 | --certificate-oidc-issuer="${cert_oidc_issuer}" \ 135 | "${download_path}/${checksum_file}" 136 | ); then 137 | echo "signature verification failed" >&2 138 | return 1 139 | fi 140 | } 141 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:recommended" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /scripts/format.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | shfmt --language-dialect bash --write \ 4 | ./bin/* \ 5 | ./lib/* \ 6 | ./scripts/* 7 | -------------------------------------------------------------------------------- /scripts/lint.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | shellcheck --shell=bash --external-sources \ 4 | bin/* --source-path=template/lib/ \ 5 | lib/* \ 6 | scripts/* 7 | 8 | shfmt --language-dialect bash --diff \ 9 | ./bin/* \ 10 | ./lib/* \ 11 | ./scripts/* 12 | -------------------------------------------------------------------------------- /test/parse-legacy-file.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | # SPDX-License-Identifier: MIT 4 | # SPDX-FileCopyrightText: Copyright (c) 2017 Jack Henry & Associates 5 | 6 | setup() { 7 | ASDF_OPENTOFU="$(dirname "$BATS_TEST_DIRNAME")" 8 | PARSE_LEGACY_FILE="${ASDF_OPENTOFU}/bin/parse-legacy-file" 9 | } 10 | 11 | @test "supports legacy opentofu version 'required_version' with strict equality" { 12 | local -r expected_opentofu_version=0.13.7 13 | local -r tmpdir="$(mktemp -d)" 14 | local -r version_file="${tmpdir}/main.tofu" 15 | cat <"${version_file}" 16 | terraform { 17 | required_version = "= ${expected_opentofu_version}" 18 | } 19 | EOF 20 | 21 | local -r actual_opentofu_version="$(ASDF_OPENTOFU_THIS_PLUGIN=opentofu "${PARSE_LEGACY_FILE}" "${version_file}")" 22 | 23 | [[ ${actual_opentofu_version} == "${expected_opentofu_version}" ]] 24 | } 25 | 26 | @test "supports alternate file for opentofu version constraints" { 27 | local -r expected_opentofu_version=0.13.7 28 | local -r tmpdir="$(mktemp -d)" 29 | local -r version_file="${tmpdir}/versions.tofu" 30 | cat <"${version_file}" 31 | terraform { 32 | required_version = "= ${expected_opentofu_version}" 33 | } 34 | EOF 35 | 36 | local -r actual_opentofu_version="$(ASDF_OPENTOFU_VERSION_FILE=versions.tofu ASDF_OPENTOFU_THIS_PLUGIN=opentofu "${PARSE_LEGACY_FILE}" "${version_file}")" 37 | 38 | [[ ${actual_opentofu_version} == "${expected_opentofu_version}" ]] 39 | } 40 | 41 | @test "supports legacy opentofu version 'required_version' with strict equality, no equals literal" { 42 | local -r expected_opentofu_version=0.13.7 43 | local -r tmpdir="$(mktemp -d)" 44 | local -r version_file="${tmpdir}/main.tofu" 45 | cat <"${version_file}" 46 | terraform { 47 | required_version = "${expected_opentofu_version}" 48 | } 49 | EOF 50 | 51 | local -r actual_opentofu_version="$(ASDF_OPENTOFU_THIS_PLUGIN=opentofu "${PARSE_LEGACY_FILE}" "${version_file}")" 52 | 53 | [[ ${actual_opentofu_version} == "${expected_opentofu_version}" ]] 54 | } 55 | 56 | @test "supports legacy file .opentofu-version" { 57 | local -r expected_opentofu_version=0.13.7 58 | local -r tmpdir="$(mktemp -d)" 59 | local -r version_file="${tmpdir}/.opentofu-version" 60 | 61 | echo "${expected_opentofu_version}" >"${tmpdir}/.opentofu-version" 62 | 63 | local -r actual_opentofu_version="$(ASDF_OPENTOFU_THIS_PLUGIN=opentofu "${PARSE_LEGACY_FILE}" "${version_file}")" 64 | 65 | [[ ${actual_opentofu_version} == "${expected_opentofu_version}" ]] 66 | } 67 | 68 | @test "does not support 'not equal' version constraint expressions" { 69 | local -r tmpdir="$(mktemp -d)" 70 | local -r version_file="${tmpdir}/main.tofu" 71 | cat <"${version_file}" 72 | terraform { 73 | required_version = "!= 0.13.7" 74 | } 75 | EOF 76 | 77 | local -r actual_opentofu_version="$(ASDF_OPENTOFU_THIS_PLUGIN=opentofu "${PARSE_LEGACY_FILE}" "${version_file}")" 78 | 79 | [[ ${actual_opentofu_version} == "" ]] 80 | } 81 | 82 | @test "does not support 'greater than' version constraint expressions" { 83 | local -r tmpdir="$(mktemp -d)" 84 | local -r version_file="${tmpdir}/main.tofu" 85 | cat <"${version_file}" 86 | terraform { 87 | required_version = "> 0.13.7" 88 | } 89 | EOF 90 | 91 | local -r actual_opentofu_version="$(ASDF_OPENTOFU_THIS_PLUGIN=opentofu "${PARSE_LEGACY_FILE}" "${version_file}")" 92 | 93 | [[ ${actual_opentofu_version} == "" ]] 94 | } 95 | 96 | @test "does not support 'less than' version constraint expressions" { 97 | local -r tmpdir="$(mktemp -d)" 98 | local -r version_file="${tmpdir}/main.tofu" 99 | cat <"${version_file}" 100 | terraform { 101 | required_version = "< 0.13.7" 102 | } 103 | EOF 104 | 105 | local -r actual_opentofu_version="$(ASDF_OPENTOFU_THIS_PLUGIN=opentofu "${PARSE_LEGACY_FILE}" "${version_file}")" 106 | 107 | [[ ${actual_opentofu_version} == "" ]] 108 | } 109 | 110 | @test "does not support squiggly arrow version constraint expressions" { 111 | local -r tmpdir="$(mktemp -d)" 112 | local -r version_file="${tmpdir}/main.tofu" 113 | cat <"${version_file}" 114 | terraform { 115 | required_version = "~> 0.13.7" 116 | } 117 | EOF 118 | 119 | local -r actual_opentofu_version="$(ASDF_OPENTOFU_THIS_PLUGIN=opentofu "${PARSE_LEGACY_FILE}" "${version_file}")" 120 | 121 | [[ ${actual_opentofu_version} == "" ]] 122 | } 123 | 124 | @test "does not support compound version constraint expressions" { 125 | local -r tmpdir="$(mktemp -d)" 126 | local -r version_file="${tmpdir}/main.tofu" 127 | cat <"${version_file}" 128 | terraform { 129 | required_version = "> 0.13.0, < 0.14.0" 130 | } 131 | EOF 132 | 133 | local -r actual_opentofu_version="$(ASDF_OPENTOFU_THIS_PLUGIN=opentofu "${PARSE_LEGACY_FILE}" "${version_file}")" 134 | 135 | [[ ${actual_opentofu_version} == "" ]] 136 | } 137 | 138 | # https://github.com/asdf-community/asdf-hashicorp/pull/43#discussion_r816027246 139 | @test 'does not get confused by multiple legacy version files for different plugins' { 140 | local -r expected_opentofu_version=0.13.7 141 | local -r tmpdir="$(mktemp -d)" 142 | local -r version_file="${tmpdir}/main.tofu" 143 | cat <"${version_file}" 144 | terraform { 145 | required_version = "= ${expected_opentofu_version}" 146 | } 147 | EOF 148 | 149 | echo 'foo' >"${tmpdir}/.opentofu-version" 150 | 151 | local -r actual_opentofu_version="$(ASDF_OPENTOFU_THIS_PLUGIN=opentofu "${PARSE_LEGACY_FILE}" "${version_file}")" 152 | 153 | [[ ${actual_opentofu_version} == "${expected_opentofu_version}" ]] 154 | } 155 | 156 | @test "does not output error if required_version is not specified" { 157 | local -r tmpdir="$(mktemp -d)" 158 | local -r version_file="${tmpdir}/main.tofu" 159 | touch "${version_file}" 160 | 161 | local -r actual_opentofu_version="$(ASDF_OPENTOFU_THIS_PLUGIN=opentofu "${PARSE_LEGACY_FILE}" "${version_file}" 2>&1)" 162 | 163 | [[ ${actual_opentofu_version} == "" ]] 164 | } 165 | -------------------------------------------------------------------------------- /version.txt: -------------------------------------------------------------------------------- 1 | 1.2.0 2 | --------------------------------------------------------------------------------