Skip to content

Commit 95a52e3

Browse files
feat(terraform_providers_lock): Fix logical issue in hook modes: Add check-lockfile-is-cross-platform and regenerate-lockfile-if-some-platform-missed modes. Last one is same as only-check-is-current-lockfile-cross-platform, which now is deprecated. Check README for more details (#950)
--------- Co-authored-by: George Yermulnik (Georgii Iermulnik) <yz@yz.kiev.ua>
1 parent d46fbb6 commit 95a52e3

File tree

2 files changed

+84
-18
lines changed

2 files changed

+84
-18
lines changed

README.md

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -759,26 +759,44 @@ To replicate functionality in `terraform_docs` hook:
759759
> - --hook-config=--mode=always-regenerate-lockfile
760760
> ```
761761
>
762-
> Why? When v2.x will be introduced - the default mode will be changed, probably, to `only-check-is-current-lockfile-cross-platform`.
762+
> Why? When v2.x will be introduced - the default mode will be changed, probably, to `check-lockfile-is-cross-platform`.
763763
>
764764
> You can check available modes for hook below.
765765
> </details>
766766

767767

768-
1. The hook can work in a few different modes: `only-check-is-current-lockfile-cross-platform` with and without [terraform_validate hook](#terraform_validate) and `always-regenerate-lockfile` - only with terraform_validate hook.
768+
1. The hook can work in a few different modes:
769769

770-
* `only-check-is-current-lockfile-cross-platform` without terraform_validate - only checks that lockfile has all required SHAs for all providers already added to lockfile.
770+
1. <details><summary><code>--mode=check-lockfile-is-cross-platform</code> (standalone)</summary>
771+
Checks that lockfile has the same number of platform checksums (`h1:`) as requested by the hook configuration. It **does not** check whether these checksums are valid or that they match target platforms.
771772

772773
```yaml
773774
- id: terraform_providers_lock
774775
args:
775-
- --hook-config=--mode=only-check-is-current-lockfile-cross-platform
776+
- --hook-config=--mode=check-lockfile-is-cross-platform
776777
```
777778

778-
* `only-check-is-current-lockfile-cross-platform` with [terraform_validate hook](#terraform_validate) - make up-to-date lockfile by adding/removing providers and only then check that lockfile has all required SHAs.
779+
</details>
780+
781+
2. <details><summary><code>--mode=regenerate-lockfile-if-some-platform-missed</code> (standalone)</summary>
782+
783+
Checks that lockfile has checksums (`h1:`) for all requested platforms for all providers tracked by the lockfile, and if any are missed - tries to add them (but could fail if `terraform init` wasn't run previously).
784+
785+
786+
```yaml
787+
- id: terraform_providers_lock
788+
args:
789+
- --hook-config=--mode=regenerate-lockfile-if-some-platform-missed
790+
```
791+
792+
</details>
793+
794+
3. <details><summary><code>--mode=regenerate-lockfile-if-some-platform-missed</code> with <code>terraform_validate</code> hook</summary>
795+
796+
Regenerates lockfile for all required providers and checks that the lockfile tracks all required platform checksums (`h1:`) afterwards. If any are missed - adds them; superfluous providers are removed.
779797

780798
> **Important**
781-
> Next `terraform_validate` flag requires additional dependency to be installed: `jq`. Also, it could run another slow and time consuming command - `terraform init`
799+
> The following [`terraform_validate`](#terraform_validate) hook's flag requires additional dependency to be installed: [`jq`](https://github.com/jqlang/jq). Also, it could run another slow and time consuming command - `terraform init`
782800

783801
```yaml
784802
- id: terraform_validate
@@ -787,10 +805,14 @@ To replicate functionality in `terraform_docs` hook:
787805
788806
- id: terraform_providers_lock
789807
args:
790-
- --hook-config=--mode=only-check-is-current-lockfile-cross-platform
808+
- --hook-config=--mode=regenerate-lockfile-if-some-platform-missed
791809
```
792810

793-
* `always-regenerate-lockfile` only with [terraform_validate hook](#terraform_validate) - regenerate lockfile from scratch. Can be useful for upgrading providers in lockfile to latest versions
811+
</details>
812+
813+
4. <details><summary><code>always-regenerate-lockfile</code> - meant to be used only along with <code>terraform_validate</code> hook</summary>
814+
815+
Regenerates lockfile from the scratch. May be useful for upgrading providers in the lockfile to the latest versions.
794816

795817
```yaml
796818
- id: terraform_validate
@@ -803,6 +825,8 @@ To replicate functionality in `terraform_docs` hook:
803825
- --hook-config=--mode=always-regenerate-lockfile
804826
```
805827

828+
</details>
829+
806830
2. `terraform_providers_lock` supports custom arguments:
807831

808832
```yaml

hooks/terraform_providers_lock.sh

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,11 @@ function per_dir_hook_unique_part {
101101
local -a -r args=("$@")
102102

103103
local platforms_count=0
104+
local platforms_names=()
104105
for arg in "${args[@]}"; do
105106
if grep -Eq '^-platform=' <<< "$arg"; then
106107
platforms_count=$((platforms_count + 1))
108+
platforms_names+=("${arg#*=}")
107109
fi
108110
done
109111

@@ -121,44 +123,84 @@ function per_dir_hook_unique_part {
121123
key=${config[0]}
122124
value=${config[1]}
123125

124-
case $key in
126+
case "$key" in
125127
--mode)
126128
if [ "$mode" ]; then
127-
common::colorify "yellow" 'Invalid hook config. Make sure that you specify not more than one "--mode" flag'
129+
common::colorify "yellow" 'Invalid hook config. Make sure that you specify not more than one "--mode" flag.'
128130
exit 1
129131
fi
130132
mode=$value
133+
134+
case "$mode" in
135+
check-lockfile-is-cross-platform) ;;
136+
regenerate-lockfile-if-some-platform-missed) ;;
137+
always-regenerate-lockfile) ;;
138+
139+
only-check-is-current-lockfile-cross-platform)
140+
common::colorify "yellow" "DEPRECATION NOTICE: Flag '--mode=only-check-is-current-lockfile-cross-platform' was renamed to '--mode=regenerate-lockfile-if-some-platform-missed' to better reflect its behavior.
141+
Please update your configuration."
142+
mode="regenerate-lockfile-if-some-platform-missed"
143+
;;
144+
*)
145+
common::colorify "red" "Invalid hook config. Supported --mode values are:
146+
- check-lockfile-is-cross-platform
147+
- regenerate-lockfile-if-some-platform-missed
148+
- always-regenerate-lockfile"
149+
exit 1
150+
;;
151+
esac
131152
;;
132153
esac
133154
done
134155

135156
# Available options:
136-
# only-check-is-current-lockfile-cross-platform (will be default)
157+
# check-lockfile-is-cross-platform (will be default in v2.0)
158+
# regenerate-lockfile-if-some-platform-missed
137159
# always-regenerate-lockfile
138160
# TODO: Remove in 2.0
139161
if [ ! "$mode" ]; then
140162
common::colorify "yellow" "DEPRECATION NOTICE: We introduced '--mode' flag for this hook.
141-
Check migration instructions at https://github.com/antonbabenko/pre-commit-terraform#terraform_providers_lock
142-
"
163+
Check migration instructions at https://github.com/antonbabenko/pre-commit-terraform#terraform_providers_lock"
143164
common::terraform_init "$tf_path providers lock" "$dir_path" "$parallelism_disabled" "$tf_path" || {
144165
exit_code=$?
145166
return $exit_code
146167
}
147168
fi
148169

149-
if [ "$mode" == "only-check-is-current-lockfile-cross-platform" ] &&
150-
lockfile_contains_all_needed_sha "$platforms_count"; then
170+
case "$mode" in
171+
"check-lockfile-is-cross-platform")
172+
if lockfile_contains_all_needed_sha "$platforms_count"; then
173+
exit 0
174+
fi
151175

152-
exit 0
153-
fi
176+
common::colorify "red" "$dir_path/.terraform.lock.hcl missing some of required platforms.
177+
All required platforms: ${platforms_names[*]}"
178+
179+
exit 1
180+
;;
181+
"regenerate-lockfile-if-some-platform-missed")
182+
if lockfile_contains_all_needed_sha "$platforms_count"; then
183+
exit 0
184+
fi
185+
186+
common::colorify "yellow" "$dir_path/.terraform.lock.hcl missing some of required platforms.
187+
All required platforms: ${platforms_names[*]}"
188+
189+
;;
190+
esac
154191

155192
#? Don't require `tf init` for providers, but required `tf init` for modules
156193
#? Mitigated by `function match_validate_errors` from terraform_validate hook
157194
# pass the arguments to hook
158195
"$tf_path" providers lock "${args[@]}"
159196

160-
# return exit code to common::per_dir_hook
161197
exit_code=$?
198+
if [[ $exit_code -ne 0 ]]; then
199+
common::colorify "red" "$dir_path run failed. Detailed error above.
200+
Most common issue is that required 'terraform init' command was likely not run before running this hook. It might be run for you automatically by 'terraform_validate' hook - see https://github.com/antonbabenko/pre-commit-terraform#terraform_validate for more details."
201+
fi
202+
203+
# return exit code to common::per_dir_hook
162204
return $exit_code
163205
}
164206

0 commit comments

Comments
 (0)