forked from antonbabenko/pre-commit-terraform
-
Notifications
You must be signed in to change notification settings - Fork 1
/
terraform_providers_lock.sh
executable file
·141 lines (114 loc) · 3.15 KB
/
terraform_providers_lock.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/bin/env bash
set -eo pipefail
function main {
common::initialize
common::parse_cmdline "$@"
common::per_dir_hook "${ARGS[*]}" "${FILES[@]}"
}
function common::colorify {
# shellcheck disable=SC2034
local -r red="\e[0m\e[31m"
# shellcheck disable=SC2034
local -r green="\e[0m\e[32m"
# shellcheck disable=SC2034
local -r yellow="\e[0m\e[33m"
# Color reset
local -r RESET="\e[0m"
# Params start #
local COLOR="${!1}"
local -r TEXT=$2
# Params end #
if [ "$PRE_COMMIT_COLOR" = "never" ]; then
COLOR=$RESET
fi
echo -e "${COLOR}${TEXT}${RESET}"
}
function common::initialize {
local SCRIPT_DIR
# get directory containing this script
SCRIPT_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]}")")"
# source getopt function
# shellcheck source=lib_getopt
. "$SCRIPT_DIR/lib_getopt"
}
function common::parse_cmdline {
# common global arrays.
# Populated via `common::parse_cmdline` and can be used inside hooks' functions
declare -g -a ARGS=() FILES=() HOOK_CONFIG=()
local argv
argv=$(getopt -o a:,h: --long args:,hook-config: -- "$@") || return
eval "set -- $argv"
for argv; do
case $argv in
-a | --args)
shift
ARGS+=("$1")
shift
;;
-h | --hook-config)
shift
HOOK_CONFIG+=("$1;")
shift
;;
--)
shift
FILES=("$@")
break
;;
esac
done
}
function common::per_dir_hook {
local -r args="$1"
shift 1
local -a -r files=("$@")
# consume modified files passed from pre-commit so that
# hook runs against only those relevant directories
local index=0
for file_with_path in "${files[@]}"; do
file_with_path="${file_with_path// /__REPLACED__SPACE__}"
dir_paths[index]=$(dirname "$file_with_path")
((index += 1))
done
# preserve errexit status
shopt -qo errexit && ERREXIT_IS_SET=true
# allow hook to continue if exit_code is greater than 0
set +e
local final_exit_code=0
# run hook for each path
for dir_path in $(echo "${dir_paths[*]}" | tr ' ' '\n' | sort -u); do
dir_path="${dir_path//__REPLACED__SPACE__/ }"
pushd "$dir_path" > /dev/null || continue
per_dir_hook_unique_part "$args" "$dir_path"
local exit_code=$?
if [ $exit_code -ne 0 ]; then
final_exit_code=$exit_code
fi
popd > /dev/null
done
# restore errexit if it was set before the "for" loop
[[ $ERREXIT_IS_SET ]] && set -e
# return the hook final exit_code
exit $final_exit_code
}
function per_dir_hook_unique_part {
# common logic located in common::per_dir_hook
local -r args="$1"
local -r dir_path="$2"
if [ ! -d ".terraform" ]; then
init_output=$(terraform init -backend=false 2>&1)
init_code=$?
if [ $init_code -ne 0 ]; then
common::colorify "red" "Init before validation failed: $dir_path"
common::colorify "red" "$init_output"
exit $init_code
fi
fi
# pass the arguments to hook
# shellcheck disable=SC2068 # hook fails when quoting is used ("$arg[@]")
terraform providers lock ${args[@]}
# return exit code to common::per_dir_hook
local exit_code=$?
return $exit_code
}
[ "${BASH_SOURCE[0]}" != "$0" ] || main "$@"