Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Refactor all hooks #310

Merged
merged 17 commits into from
Jan 6, 2022
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 26 additions & 31 deletions terraform_docs.sh
Original file line number Diff line number Diff line change
@@ -1,35 +1,32 @@
#!/usr/bin/env bash
set -eo pipefail

main() {
initialize_
parse_cmdline_ "$@"
function main {
common::initialize
common::parse_cmdline "$@"
# Support for setting relative PATH to .terraform-docs.yml config.
ARGS=${ARGS[*]/--config=/--config=$(pwd)\/}
terraform_docs_ "${HOOK_CONFIG[*]}" "$ARGS" "${FILES[@]}"
}

initialize_() {
function common::initialize {
local SCRIPT_DIR
# get directory containing this script
local dir
local source
source="${BASH_SOURCE[0]}"
while [[ -L $source ]]; do # resolve $source until the file is no longer a symlink
dir="$(cd -P "$(dirname "$source")" > /dev/null && pwd)"
source="$(readlink "$source")"
# if $source was a relative symlink, we need to resolve it relative to the path where the symlink file was located
[[ $source != /* ]] && source="$dir/$source"
done
_SCRIPT_DIR="$(dirname "$source")"
SCRIPT_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]}")")"

# source getopt function
# shellcheck source=lib_getopt
. "$_SCRIPT_DIR/lib_getopt"
. "$SCRIPT_DIR/lib_getopt"
}

parse_cmdline_() {
declare argv
argv=$(getopt -o a: --long args:,hook-config: -- "$@") || return
# common global arrays.
# Populated in `parse_cmdline` and can used in hooks functions
MaxymVlasov marked this conversation as resolved.
Show resolved Hide resolved
declare -a ARGS=()
declare -a HOOK_CONFIG=()
declare -a FILES=()
function common::parse_cmdline {
MaxymVlasov marked this conversation as resolved.
Show resolved Hide resolved
local argv
argv=$(getopt -o a:,h: --long args:,hook-config: -- "$@") || return
MaxymVlasov marked this conversation as resolved.
Show resolved Hide resolved
eval "set -- $argv"

for argv; do
Expand All @@ -39,9 +36,9 @@ parse_cmdline_() {
ARGS+=("$1")
shift
;;
--hook-config)
-h | --hook-config)
shift
HOOK_CONFIG+=("$1")
HOOK_CONFIG+=("$1;")
yermulnik marked this conversation as resolved.
Show resolved Hide resolved
shift
;;
--)
Expand All @@ -53,12 +50,15 @@ parse_cmdline_() {
done
}

terraform_docs_() {
function terraform_docs_ {
local -r hook_config="$1"
local -r args="$2"
shift 2
local -a -r files=("$@")

# Get hook settings
IFS=";" read -r -a configs <<< "$hook_config"

local hack_terraform_docs
hack_terraform_docs=$(terraform version | sed -n 1p | grep -c 0.12) || true

Expand All @@ -72,7 +72,7 @@ terraform_docs_() {

if [[ -z "$is_old_terraform_docs" ]]; then # Using terraform-docs 0.8+ (preferred)

terraform_docs "0" "$hook_config" "$args" "${files[@]}"
terraform_docs "0" "${configs[*]}" "$args" "${files[@]}"

elif [[ "$hack_terraform_docs" == "1" ]]; then # Using awk script because terraform-docs is older than 0.8 and terraform 0.12 is used

Expand All @@ -84,17 +84,17 @@ terraform_docs_() {
local tmp_file_awk
tmp_file_awk=$(mktemp "${TMPDIR:-/tmp}/terraform-docs-XXXXXXXXXX")
terraform_docs_awk "$tmp_file_awk"
terraform_docs "$tmp_file_awk" "$hook_config" "$args" "${files[@]}"
terraform_docs "$tmp_file_awk" "${configs[*]}" "$args" "${files[@]}"
rm -f "$tmp_file_awk"

else # Using terraform 0.11 and no awk script is needed for that

terraform_docs "0" "$hook_config" "$args" "${files[@]}"
terraform_docs "0" "${configs[*]}" "$args" "${files[@]}"

fi
}

terraform_docs() {
function terraform_docs {
local -r terraform_docs_awk_file="$1"
local -r hook_config="$2"
local -r args="$3"
Expand Down Expand Up @@ -212,7 +212,7 @@ terraform_docs() {
done
}

terraform_docs_awk() {
function terraform_docs_awk {
local -r output_file=$1

cat << "EOF" > "$output_file"
Expand Down Expand Up @@ -371,9 +371,4 @@ EOF

}

# global arrays
declare -a ARGS=()
declare -a FILES=()
declare -a HOOK_CONFIG=()

[[ ${BASH_SOURCE[0]} != "$0" ]] || main "$@"
113 changes: 74 additions & 39 deletions terraform_fmt.sh
Original file line number Diff line number Diff line change
@@ -1,33 +1,30 @@
#!/usr/bin/env bash
set -eo pipefail

main() {
initialize_
parse_cmdline_ "$@"
terraform_fmt_
function main {
common::initialize
common::parse_cmdline "$@"
terraform_fmt_ "${ARGS[*]}" "${FILES[@]}"
}

initialize_() {
function common::initialize {
local SCRIPT_DIR
# get directory containing this script
local dir
local source
source="${BASH_SOURCE[0]}"
while [[ -L $source ]]; do # resolve $source until the file is no longer a symlink
dir="$(cd -P "$(dirname "$source")" > /dev/null && pwd)"
source="$(readlink "$source")"
# if $source was a relative symlink, we need to resolve it relative to the path where the symlink file was located
[[ $source != /* ]] && source="$dir/$source"
done
_SCRIPT_DIR="$(dirname "$source")"
SCRIPT_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]}")")"

# source getopt function
# shellcheck source=lib_getopt
. "$_SCRIPT_DIR/lib_getopt"
. "$SCRIPT_DIR/lib_getopt"
}

parse_cmdline_() {
declare argv
argv=$(getopt -o a: --long args: -- "$@") || return
# common global arrays.
# Populated in `parse_cmdline` and can used in hooks functions
declare -a ARGS=()
declare -a HOOK_CONFIG=()
declare -a FILES=()
function common::parse_cmdline {
local argv
argv=$(getopt -o a:,h: --long args:,hook-config: -- "$@") || return
eval "set -- $argv"

for argv; do
Expand All @@ -37,6 +34,11 @@ parse_cmdline_() {
ARGS+=("$1")
shift
;;
-h | --hook-config)
shift
HOOK_CONFIG+=("$1;")
shift
;;
--)
shift
FILES=("$@")
Expand All @@ -46,44 +48,77 @@ parse_cmdline_() {
done
}

terraform_fmt_() {

declare -a paths
declare -a tfvars_files

index=0

for file_with_path in "${FILES[@]}"; do
function terraform_fmt_ {
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__}"

paths[index]=$(dirname "$file_with_path")

dir_paths[index]=$(dirname "$file_with_path")
# TODO Unique part
if [[ "$file_with_path" == *".tfvars" ]]; then
tfvars_files+=("$file_with_path")
fi

#? End for unique part
MaxymVlasov marked this conversation as resolved.
Show resolved Hide resolved
((index += 1))
MaxymVlasov marked this conversation as resolved.
Show resolved Hide resolved
done

for path_uniq in $(echo "${paths[*]}" | tr ' ' '\n' | sort -u); do
path_uniq="${path_uniq//__REPLACED__SPACE__/ }"
# allow hook to continue if exit_code is greater than 0
# preserve errexit status
shopt -qo errexit && ERREXIT_IS_SET=true
set +e
MaxymVlasov marked this conversation as resolved.
Show resolved Hide resolved
local final_exit_code=0

(
cd "$path_uniq"
terraform fmt "${ARGS[@]}"
)
# run hook for each path
for dir_path in $(echo "${dir_paths[*]}" | tr ' ' '\n' | sort -u); do
MaxymVlasov marked this conversation as resolved.
Show resolved Hide resolved
dir_path="${dir_path//__REPLACED__SPACE__/ }"
pushd "$dir_path" > /dev/null
MaxymVlasov marked this conversation as resolved.
Show resolved Hide resolved

per_dir_hook_unique_part "$args" "$dir_path"

local exit_code=$?
if [ "$exit_code" != 0 ]; then
MaxymVlasov marked this conversation as resolved.
Show resolved Hide resolved
final_exit_code=$exit_code
fi

popd > /dev/null
done

# TODO: Unique part
# terraform.tfvars are excluded by `terraform fmt`
for tfvars_file in "${tfvars_files[@]}"; do
tfvars_file="${tfvars_file//__REPLACED__SPACE__/ }"

terraform fmt "${ARGS[@]}" "$tfvars_file"
local exit_code=$?
if [ "$exit_code" != 0 ]; then
final_exit_code=$exit_code
fi
done
#? End for unique part
# 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

}

# global arrays
declare -a ARGS=()
declare -a FILES=()
function per_dir_hook_unique_part {
# common logic located in common::per_dir_hook
local -r args="$1"
local -r dir_path="$2"

# pass the arguments to terrascan
# shellcheck disable=SC2068 # terrascan fails when quoting is used ("$arg" vs $arg)
terraform fmt ${args[@]}

# return exit code to common::per_dir_hook
local exit_code=$?
return $exit_code
MaxymVlasov marked this conversation as resolved.
Show resolved Hide resolved
}

[[ ${BASH_SOURCE[0]} != "$0" ]] || main "$@"
Loading