From 7b11401863b29fc8c83a1e74584ac99dc50630ec Mon Sep 17 00:00:00 2001 From: Maksym Vlasov Date: Fri, 15 Oct 2021 15:26:23 +0300 Subject: [PATCH] feat: Add `terraform_docs` hook settings (#245) --- README.md | 32 +++++++++++++---- terraform_docs.sh | 90 ++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 103 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 5ac14002d..51e0d319f 100644 --- a/README.md +++ b/README.md @@ -225,13 +225,33 @@ For [checkov](https://github.com/bridgecrewio/checkov) you need to specify each 2. It is possible to pass additional arguments to shell scripts when using `terraform_docs` and `terraform_docs_without_aggregate_type_defaults`. Send pull-request with the new hook if something is missing. -For these hooks, you need to specify all arguments as one: +3. It is possible to automatically: + * create docfile (and PATH to it) + * extend exiting docs files, by appending markers to the end of file (see p.1) + * use different than `README.md` docfile name. -```yaml -- id: terraform_docs - args: - - tfvars hcl --output-file terraform.tfvars.model . -``` + ```yaml + - id: terraform_docs + args: + - --hook-config=--path-to-file=README.md # Valid UNIX path. I.e. ../TFDOC.md or docs/README.md etc. + - --hook-config=--add-to-exiting-file=true # Boolean. true or false + - --hook-config=--create-file-if-not-exist=true # Boolean. true or false + ``` + +4. You can provide arguments to terraform_doc. Eg. for [configuration](https://github.com/terraform-docs/terraform-docs/blob/master/docs/user-guide/configuration.md#usage): + + ```yaml + - id: terraform_docs + args: + - --args=--config=.terraform-docs.yml + +5. If you need some exotic settings, it can be be done too. I.e. this one generates HCL files: + + ```yaml + - id: terraform_docs + args: + - tfvars hcl --output-file terraform.tfvars.model . + ``` ### terraform_docs_replace diff --git a/terraform_docs.sh b/terraform_docs.sh index f4335cd34..e817687c2 100755 --- a/terraform_docs.sh +++ b/terraform_docs.sh @@ -6,7 +6,7 @@ main() { parse_cmdline_ "$@" # Support for setting relative PATH to .terraform-docs.yml config. ARGS=${ARGS/--config=/--config=$(pwd)\/} - terraform_docs_ "${ARGS[*]}" "${FILES[@]}" + terraform_docs_ "${HOOK_CONFIG[*]}" "${ARGS[*]}" "${FILES[@]}" } initialize_() { @@ -29,7 +29,7 @@ initialize_() { parse_cmdline_() { declare argv - argv=$(getopt -o a: --long args: -- "$@") || return + argv=$(getopt -o a: --long args:,hook-config: -- "$@") || return eval "set -- $argv" for argv; do @@ -39,6 +39,11 @@ parse_cmdline_() { ARGS+=("$1") shift ;; + --hook-config) + shift + HOOK_CONFIG+=("$1") + shift + ;; --) shift FILES=("$@") @@ -49,8 +54,9 @@ parse_cmdline_() { } terraform_docs_() { - local -r args="$1" - shift + local -r hook_config="$1" + local -r args="$2" + shift 2 local -a -r files=("$@") local hack_terraform_docs @@ -66,7 +72,7 @@ terraform_docs_() { if [[ -z "$is_old_terraform_docs" ]]; then # Using terraform-docs 0.8+ (preferred) - terraform_docs "0" "$args" "${files[@]}" + terraform_docs "0" "$hook_config" "$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 @@ -78,20 +84,21 @@ 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" "$args" "${files[@]}" + terraform_docs "$tmp_file_awk" "$hook_config" "$args" "${files[@]}" rm -f "$tmp_file_awk" else # Using terraform 0.11 and no awk script is needed for that - terraform_docs "0" "$args" "${files[@]}" + terraform_docs "0" "$hook_config" "$args" "${files[@]}" fi } terraform_docs() { local -r terraform_docs_awk_file="$1" - local -r args="$2" - shift 2 + local -r hook_config="$2" + local -r args="$3" + shift 3 local -a -r files=("$@") declare -a paths @@ -107,7 +114,32 @@ terraform_docs() { done local -r tmp_file=$(mktemp) - local -r text_file="README.md" + + # + # Get hook settings + # + local text_file="README.md" + local add_to_exiting=false + local create_if_not_exist=false + + configs=($hook_config) + for c in "${configs[@]}"; do + config=(${c//=/ }) + key=${config[0]} + value=${config[1]} + + case $key in + --path-to-file) + text_file=$value + ;; + --add-to-exiting-file) + add_to_exiting=$value + ;; + --create-file-if-not-exist) + create_if_not_exist=$value + ;; + esac + done local path_uniq for path_uniq in $(echo "${paths[*]}" | tr ' ' '\n' | sort -u); do @@ -115,9 +147,40 @@ terraform_docs() { pushd "$path_uniq" > /dev/null - if [[ ! -f "$text_file" ]]; then - popd > /dev/null - continue + # + # Create file if it not exist and `--create-if-not-exist=true` provided + # + if $create_if_not_exist && [[ ! -f "$text_file" ]]; then + dir_have_tf_files="$( + find . -maxdepth 1 -type f | sed 's|.*\.||' | sort -u | grep -oE '^tf$|^tfvars$' || + exit 0 + )" + + # if no TF files - skip dir + [ ! "$dir_have_tf_files" ] && popd > /dev/null && continue + + dir="$(dirname "$text_file")" + + mkdir -p "$dir" + echo -e "# ${PWD##*/}\n" >> "$text_file" + echo "" >> "$text_file" + echo "" >> "$text_file" + fi + + # If file still not exist - skip dir + [[ ! -f "$text_file" ]] && popd > /dev/null && continue + + # + # If `--add-to-exiting-file=true` set, check is in file exist "hook markers", + # and if not - append "hook markers" to the end of file. + # + if $add_to_exiting; then + HAVE_MARKER=$(grep -o '' "$text_file" || exit 0) + + if [ ! "$HAVE_MARKER" ]; then + echo "" >> "$text_file" + echo "" >> "$text_file" + fi fi if [[ "$terraform_docs_awk_file" == "0" ]]; then @@ -311,5 +374,6 @@ EOF # global arrays declare -a ARGS=() declare -a FILES=() +declare -a HOOK_CONFIG=() [[ ${BASH_SOURCE[0]} != "$0" ]] || main "$@"