├── .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 [](https://github.com/virtualroot/asdf-opentofu/actions/workflows/build.yml) [](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 |
--------------------------------------------------------------------------------