Skip to content

Commit a446642

Browse files
authored
feat: Add support for version constraints in tfupdate (antonbabenko#437)
1 parent f5aa7c8 commit a446642

12 files changed

+140
-112
lines changed

hooks/_common.sh

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,22 @@ function common::parse_cmdline {
5151
case $argv in
5252
-a | --args)
5353
shift
54-
ARGS+=("$1")
54+
# `argv` is an string from array with content like:
55+
# ('provider aws' '--version "> 0.14"' '--ignore-path "some/path"')
56+
# where each element is the value of each `--args` from hook config.
57+
# `echo` prints contents of `argv` as an expanded string
58+
# `xargs` passes expanded string to `printf`
59+
# `printf` which splits it into NUL-separated elements,
60+
# NUL-separated elements read by `read` using empty separator
61+
# (`-d ''` or `-d $'\0'`)
62+
# into an `ARGS` array
63+
64+
# This allows to "rebuild" initial `args` array of sort of grouped elements
65+
# into a proper array, where each element is a standalone array slice
66+
# with quoted elements being treated as a standalone slice of array as well.
67+
while read -r -d '' ARG; do
68+
ARGS+=("$ARG")
69+
done < <(echo "$1" | xargs printf '%s\0')
5570
shift
5671
;;
5772
-h | --hook-config)
@@ -129,7 +144,7 @@ function common::parse_and_export_env_vars {
129144
#######################################################################
130145
function common::is_hook_run_on_whole_repo {
131146
local -r hook_id="$1"
132-
shift 1
147+
shift
133148
local -a -r files=("$@")
134149
# get directory containing `.pre-commit-hooks.yaml` file
135150
local -r root_config_dir="$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)")"
@@ -163,21 +178,31 @@ function common::is_hook_run_on_whole_repo {
163178
# 2.1. If at least 1 check failed - change exit code to non-zero
164179
# 3. Complete hook execution and return exit code
165180
# Arguments:
166-
# args (string with array) arguments that configure wrapped tool behavior
167181
# hook_id (string) hook ID, see `- id` for details in .pre-commit-hooks.yaml file
182+
# args_array_length (integer) Count of arguments in args array.
183+
# args (array) arguments that configure wrapped tool behavior
168184
# files (array) filenames to check
169185
#######################################################################
170186
function common::per_dir_hook {
171-
local -r args="$1"
172-
local -r hook_id="$2"
187+
local -r hook_id="$1"
188+
local -i args_array_length=$2
173189
shift 2
190+
local -a args=()
191+
# Expand args to a true array.
192+
# Based on https://stackoverflow.com/a/10953834
193+
while ((args_array_length-- > 0)); do
194+
args+=("$1")
195+
shift
196+
done
197+
# assign rest of function's positional ARGS into `files` array,
198+
# despite there's only one positional ARG left
174199
local -a -r files=("$@")
175200

176201
# check is (optional) function defined
177202
if [ "$(type -t run_hook_on_whole_repo)" == function ] &&
178203
# check is hook run via `pre-commit run --all`
179204
common::is_hook_run_on_whole_repo "$hook_id" "${files[@]}"; then
180-
run_hook_on_whole_repo "$args"
205+
run_hook_on_whole_repo "${args[@]}"
181206
exit 0
182207
fi
183208

@@ -203,7 +228,7 @@ function common::per_dir_hook {
203228
dir_path="${dir_path//__REPLACED__SPACE__/ }"
204229
pushd "$dir_path" > /dev/null || continue
205230

206-
per_dir_hook_unique_part "$args" "$dir_path"
231+
per_dir_hook_unique_part "$dir_path" "${args[@]}"
207232

208233
local exit_code=$?
209234
if [ $exit_code -ne 0 ]; then

hooks/terraform_checkov.sh

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,34 +13,35 @@ function main {
1313
common::export_provided_env_vars "${ENV_VARS[@]}"
1414
common::parse_and_export_env_vars
1515
# Support for setting PATH to repo root.
16-
# shellcheck disable=SC2178 # It's the simplest syntax for that case
17-
ARGS=${ARGS[*]/__GIT_WORKING_DIR__/$(pwd)\/}
16+
for i in "${!ARGS[@]}"; do
17+
ARGS[i]=${ARGS[i]/__GIT_WORKING_DIR__/$(pwd)\/}
18+
done
19+
1820
# Suppress checkov color
1921
if [ "$PRE_COMMIT_COLOR" = "never" ]; then
2022
export ANSI_COLORS_DISABLED=true
2123
fi
22-
# shellcheck disable=SC2128 # It's the simplest syntax for that case
23-
common::per_dir_hook "$ARGS" "$HOOK_ID" "${FILES[@]}"
24+
25+
common::per_dir_hook "$HOOK_ID" "${#ARGS[@]}" "${ARGS[@]}" "${FILES[@]}"
2426
}
2527

2628
#######################################################################
2729
# Unique part of `common::per_dir_hook`. The function is executed in loop
2830
# on each provided dir path. Run wrapped tool with specified arguments
2931
# Arguments:
30-
# args (string with array) arguments that configure wrapped tool behavior
3132
# dir_path (string) PATH to dir relative to git repo root.
3233
# Can be used in error logging
34+
# args (array) arguments that configure wrapped tool behavior
3335
# Outputs:
3436
# If failed - print out hook checks status
3537
#######################################################################
3638
function per_dir_hook_unique_part {
37-
# common logic located in common::per_dir_hook
38-
local -r args="$1"
3939
# shellcheck disable=SC2034 # Unused var.
40-
local -r dir_path="$2"
40+
local -r dir_path="$1"
41+
shift
42+
local -a -r args=("$@")
4143

42-
# shellcheck disable=SC2068 # hook fails when quoting is used ("$arg[@]")
43-
checkov -d . ${args[@]}
44+
checkov -d . "${args[@]}"
4445

4546
# return exit code to common::per_dir_hook
4647
local exit_code=$?
@@ -51,14 +52,13 @@ function per_dir_hook_unique_part {
5152
# Unique part of `common::per_dir_hook`. The function is executed one time
5253
# in the root git repo
5354
# Arguments:
54-
# args (string with array) arguments that configure wrapped tool behavior
55+
# args (array) arguments that configure wrapped tool behavior
5556
#######################################################################
5657
function run_hook_on_whole_repo {
57-
local -r args="$1"
58+
local -a -r args=("$@")
5859

5960
# pass the arguments to hook
60-
# shellcheck disable=SC2068 # hook fails when quoting is used ("$arg[@]")
61-
checkov -d "$(pwd)" ${args[@]}
61+
checkov -d "$(pwd)" "${args[@]}"
6262

6363
# return exit code to common::per_dir_hook
6464
local exit_code=$?

hooks/terraform_docs.sh

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ function main {
1313
common::export_provided_env_vars "${ENV_VARS[@]}"
1414
common::parse_and_export_env_vars
1515
# Support for setting relative PATH to .terraform-docs.yml config.
16-
# shellcheck disable=SC2178 # It's the simplest syntax for that case
17-
ARGS=${ARGS[*]/--config=/--config=$(pwd)\/}
18-
# shellcheck disable=SC2128 # It's the simplest syntax for that case
16+
for i in "${!ARGS[@]}"; do
17+
ARGS[i]=${ARGS[i]/--config=/--config=$(pwd)\/}
18+
done
1919
# shellcheck disable=SC2153 # False positive
20-
terraform_docs_ "${HOOK_CONFIG[*]}" "$ARGS" "${FILES[@]}"
20+
terraform_docs_ "${HOOK_CONFIG[*]}" "${ARGS[*]}" "${FILES[@]}"
2121
}
2222

2323
#######################################################################
@@ -91,7 +91,7 @@ function terraform_docs {
9191
shift 3
9292
local -a -r files=("$@")
9393

94-
declare -a paths
94+
local -a paths
9595

9696
local index=0
9797
local file_with_path

hooks/terraform_fmt.sh

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,27 +19,27 @@ function main {
1919
fi
2020

2121
# shellcheck disable=SC2153 # False positive
22-
common::per_dir_hook "${ARGS[*]}" "$HOOK_ID" "${FILES[@]}"
22+
common::per_dir_hook "$HOOK_ID" "${#ARGS[@]}" "${ARGS[@]}" "${FILES[@]}"
2323
}
2424

2525
#######################################################################
2626
# Unique part of `common::per_dir_hook`. The function is executed in loop
2727
# on each provided dir path. Run wrapped tool with specified arguments
2828
# Arguments:
29-
# args (string with array) arguments that configure wrapped tool behavior
3029
# dir_path (string) PATH to dir relative to git repo root.
3130
# Can be used in error logging
31+
# args (array) arguments that configure wrapped tool behavior
3232
# Outputs:
3333
# If failed - print out hook checks status
3434
#######################################################################
3535
function per_dir_hook_unique_part {
36-
local -r args="$1"
3736
# shellcheck disable=SC2034 # Unused var.
38-
local -r dir_path="$2"
37+
local -r dir_path="$1"
38+
shift
39+
local -a -r args=("$@")
3940

4041
# pass the arguments to hook
41-
# shellcheck disable=SC2068 # hook fails when quoting is used ("$arg[@]")
42-
terraform fmt ${args[@]}
42+
terraform fmt "${args[@]}"
4343

4444
# return exit code to common::per_dir_hook
4545
local exit_code=$?

hooks/terraform_providers_lock.sh

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,23 @@ function main {
1616
# JFYI: suppress color for `terraform providers lock` is N/A`
1717

1818
# shellcheck disable=SC2153 # False positive
19-
common::per_dir_hook "${ARGS[*]}" "$HOOK_ID" "${FILES[@]}"
19+
common::per_dir_hook "$HOOK_ID" "${#ARGS[@]}" "${ARGS[@]}" "${FILES[@]}"
2020
}
2121

2222
#######################################################################
2323
# Unique part of `common::per_dir_hook`. The function is executed in loop
2424
# on each provided dir path. Run wrapped tool with specified arguments
2525
# Arguments:
26-
# args (string with array) arguments that configure wrapped tool behavior
2726
# dir_path (string) PATH to dir relative to git repo root.
2827
# Can be used in error logging
28+
# args (array) arguments that configure wrapped tool behavior
2929
# Outputs:
3030
# If failed - print out hook checks status
3131
#######################################################################
3232
function per_dir_hook_unique_part {
33-
local -r args="$1"
34-
local -r dir_path="$2"
33+
local -r dir_path="$1"
34+
shift
35+
local -a -r args=("$@")
3536

3637
local exit_code
3738

@@ -41,8 +42,7 @@ function per_dir_hook_unique_part {
4142
}
4243

4344
# pass the arguments to hook
44-
# shellcheck disable=SC2068 # hook fails when quoting is used ("$arg[@]")
45-
terraform providers lock ${args[@]}
45+
terraform providers lock "${args[@]}"
4646

4747
# return exit code to common::per_dir_hook
4848
exit_code=$?

hooks/terraform_tflint.sh

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ function main {
1414
common::export_provided_env_vars "${ENV_VARS[@]}"
1515
common::parse_and_export_env_vars
1616
# Support for setting PATH to repo root.
17-
# shellcheck disable=SC2178 # It's the simplest syntax for that case
18-
ARGS=${ARGS[*]/__GIT_WORKING_DIR__/$(pwd)\/}
17+
for i in "${!ARGS[@]}"; do
18+
ARGS[i]=${ARGS[i]/__GIT_WORKING_DIR__/$(pwd)\/}
19+
done
1920
# JFYI: tflint color already suppressed via PRE_COMMIT_COLOR=never
2021

2122
# Run `tflint --init` for check that plugins installed.
@@ -30,31 +31,31 @@ function main {
3031
echo "${TFLINT_INIT}"
3132
return ${exit_code}
3233
}
33-
# shellcheck disable=SC2128 # It's the simplest syntax for that case
34-
common::per_dir_hook "$ARGS" "$HOOK_ID" "${FILES[@]}"
34+
35+
common::per_dir_hook "$HOOK_ID" "${#ARGS[@]}" "${ARGS[@]}" "${FILES[@]}"
3536
}
3637

3738
#######################################################################
3839
# Unique part of `common::per_dir_hook`. The function is executed in loop
3940
# on each provided dir path. Run wrapped tool with specified arguments
4041
# Arguments:
41-
# args (string with array) arguments that configure wrapped tool behavior
4242
# dir_path (string) PATH to dir relative to git repo root.
4343
# Can be used in error logging
44+
# args (array) arguments that configure wrapped tool behavior
4445
# Outputs:
4546
# If failed - print out hook checks status
4647
#######################################################################
4748
function per_dir_hook_unique_part {
48-
local -r args="$1"
49-
local -r dir_path="$2"
49+
local -r dir_path="$1"
50+
shift
51+
local -a -r args=("$@")
5052

5153
# Print checked PATH **only** if TFLint have any messages
5254
# shellcheck disable=SC2091,SC2068 # Suppress error output
5355
$(tflint ${args[@]} 2>&1) 2> /dev/null || {
5456
common::colorify "yellow" "TFLint in $dir_path/:"
5557

56-
# shellcheck disable=SC2068 # hook fails when quoting is used ("$arg[@]")
57-
tflint ${args[@]}
58+
tflint "${args[@]}"
5859
}
5960

6061
# return exit code to common::per_dir_hook

hooks/terraform_tfsec.sh

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,37 +13,36 @@ function main {
1313
common::export_provided_env_vars "${ENV_VARS[@]}"
1414
common::parse_and_export_env_vars
1515
# Support for setting PATH to repo root.
16-
# shellcheck disable=SC2178 # It's the simplest syntax for that case
17-
ARGS=${ARGS[*]/__GIT_WORKING_DIR__/$(pwd)\/}
16+
for i in "${!ARGS[@]}"; do
17+
ARGS[i]=${ARGS[i]/__GIT_WORKING_DIR__/$(pwd)\/}
18+
done
1819

1920
# Suppress tfsec color
2021
if [ "$PRE_COMMIT_COLOR" = "never" ]; then
21-
# shellcheck disable=SC2178,SC2128 # It's the simplest syntax for that case
22-
ARGS+=" --no-color"
22+
ARGS+=("--no-color")
2323
fi
2424

25-
# shellcheck disable=SC2128 # It's the simplest syntax for that case
26-
common::per_dir_hook "$ARGS" "$HOOK_ID" "${FILES[@]}"
25+
common::per_dir_hook "$HOOK_ID" "${#ARGS[@]}" "${ARGS[@]}" "${FILES[@]}"
2726
}
2827

2928
#######################################################################
3029
# Unique part of `common::per_dir_hook`. The function is executed in loop
3130
# on each provided dir path. Run wrapped tool with specified arguments
3231
# Arguments:
33-
# args (string with array) arguments that configure wrapped tool behavior
3432
# dir_path (string) PATH to dir relative to git repo root.
3533
# Can be used in error logging
34+
# args (array) arguments that configure wrapped tool behavior
3635
# Outputs:
3736
# If failed - print out hook checks status
3837
#######################################################################
3938
function per_dir_hook_unique_part {
40-
local -r args="$1"
4139
# shellcheck disable=SC2034 # Unused var.
42-
local -r dir_path="$2"
40+
local -r dir_path="$1"
41+
shift
42+
local -a -r args=("$@")
4343

4444
# pass the arguments to hook
45-
# shellcheck disable=SC2068 # hook fails when quoting is used ("$arg[@]")
46-
tfsec ${args[@]}
45+
tfsec "${args[@]}"
4746

4847
# return exit code to common::per_dir_hook
4948
local exit_code=$?
@@ -54,14 +53,13 @@ function per_dir_hook_unique_part {
5453
# Unique part of `common::per_dir_hook`. The function is executed one time
5554
# in the root git repo
5655
# Arguments:
57-
# args (string with array) arguments that configure wrapped tool behavior
56+
# args (array) arguments that configure wrapped tool behavior
5857
#######################################################################
5958
function run_hook_on_whole_repo {
60-
local -r args="$1"
59+
local -a -r args=("$@")
6160

6261
# pass the arguments to hook
63-
# shellcheck disable=SC2068 # hook fails when quoting is used ("$arg[@]")
64-
tfsec "$(pwd)" ${args[@]}
62+
tfsec "$(pwd)" "${args[@]}"
6563

6664
# return exit code to common::per_dir_hook
6765
local exit_code=$?

hooks/terraform_validate.sh

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ function main {
2121
ARGS+=("-no-color")
2222
fi
2323
# shellcheck disable=SC2153 # False positive
24-
common::per_dir_hook "${ARGS[*]}" "$HOOK_ID" "${FILES[@]}"
24+
common::per_dir_hook "$HOOK_ID" "${#ARGS[@]}" "${ARGS[@]}" "${FILES[@]}"
2525
}
2626

2727
#######################################################################
@@ -31,17 +31,16 @@ function main {
3131
# 2. Run `terraform validate`
3232
# 3. If at least 1 check failed - change the exit code to non-zero
3333
# Arguments:
34-
# args (string with array) arguments that configure wrapped tool behavior
3534
# dir_path (string) PATH to dir relative to git repo root.
3635
# Can be used in error logging
37-
# ENV_VARS (array) environment variables that will be used with
38-
# `terraform` commands
36+
# args (array) arguments that configure wrapped tool behavior
3937
# Outputs:
4038
# If failed - print out hook checks status
4139
#######################################################################
4240
function per_dir_hook_unique_part {
43-
local -r args="$1"
44-
local -r dir_path="$2"
41+
local -r dir_path="$1"
42+
shift
43+
local -a -r args=("$@")
4544

4645
local exit_code
4746
local validate_output
@@ -52,8 +51,7 @@ function per_dir_hook_unique_part {
5251
}
5352

5453
# pass the arguments to hook
55-
# shellcheck disable=SC2068 # hook fails when quoting is used ("$arg[@]")
56-
validate_output=$(terraform validate ${args[@]} 2>&1)
54+
validate_output=$(terraform validate "${args[@]}" 2>&1)
5755
exit_code=$?
5856

5957
if [ $exit_code -ne 0 ]; then

0 commit comments

Comments
 (0)