Skip to content

Commit 81e4572

Browse files
feat(terraform_docs): Drop support for terraform-docs <0.12.0 (antonbabenko#717)
--------- Co-authored-by: George L. Yermulnik <[email protected]>
1 parent 7813a73 commit 81e4572

File tree

2 files changed

+18
-284
lines changed

2 files changed

+18
-284
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ If you want to support the development of `pre-commit-terraform` and [many other
7575
<sub><sup>Hope that it all will work.
7676
</sup></sub></sup></sub></sup></sub></sup></sub></sup></sub></sup></sub></sup></sub></sup></sub></sup></sub><br><br>
7777
* [`checkov`](https://github.com/bridgecrewio/checkov) required for `terraform_checkov` hook
78-
* [`terraform-docs`](https://github.com/terraform-docs/terraform-docs) required for `terraform_docs` hook
78+
* [`terraform-docs`](https://github.com/terraform-docs/terraform-docs) 0.12.0+ required for `terraform_docs` hook
7979
* [`terragrunt`](https://terragrunt.gruntwork.io/docs/getting-started/install/) required for `terragrunt_validate` and `terragrunt_valid_inputs` hooks
8080
* [`terrascan`](https://github.com/tenable/terrascan) required for `terrascan` hook
8181
* [`TFLint`](https://github.com/terraform-linters/tflint) required for `terraform_tflint` hook

hooks/terraform_docs.sh

Lines changed: 17 additions & 283 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ function main {
2424
ARGS[i]=${ARGS[i]/--config=/--config=$(pwd)\/}
2525
done
2626
# shellcheck disable=SC2153 # False positive
27-
terraform_docs_ "${HOOK_CONFIG[*]}" "${ARGS[*]}" "${FILES[@]}"
27+
terraform_docs "${HOOK_CONFIG[*]}" "${ARGS[*]}" "${FILES[@]}"
2828
}
2929

3030
#######################################################################
@@ -47,79 +47,25 @@ function replace_old_markers {
4747
}
4848

4949
#######################################################################
50-
# Function which prepares hacks for old versions of `terraform` and
51-
# `terraform-docs` that them call `terraform_docs`
50+
# Wrapper around `terraform-docs` tool that checks and changes/creates
51+
# (depending on provided hook_config) terraform documentation in
52+
# Markdown
5253
# Arguments:
5354
# hook_config (string with array) arguments that configure hook behavior
5455
# args (string with array) arguments that configure wrapped tool behavior
5556
# files (array) filenames to check
5657
#######################################################################
57-
function terraform_docs_ {
58+
function terraform_docs {
5859
local -r hook_config="$1"
59-
local -r args="$2"
60+
local args="$2"
6061
shift 2
6162
local -a -r files=("$@")
6263

63-
# Get hook settings
64-
IFS=";" read -r -a configs <<< "$hook_config"
65-
66-
local hack_terraform_docs
67-
local hack_terraform_docs=0
68-
if [[ $(\command -V terraform 2> /dev/null) ]]; then
69-
hack_terraform_docs=$(terraform version | sed -n 1p | grep -c 0.12) || true
70-
fi
71-
7264
if [[ ! $(command -v terraform-docs) ]]; then
7365
echo "ERROR: terraform-docs is required by terraform_docs pre-commit hook but is not installed or in the system's PATH."
7466
exit 1
7567
fi
7668

77-
local is_old_terraform_docs
78-
is_old_terraform_docs=$(terraform-docs version | grep -o "v0.[1-7]\." | tail -1) || true
79-
80-
if [[ -z "$is_old_terraform_docs" ]]; then # Using terraform-docs 0.8+ (preferred)
81-
82-
terraform_docs "0" "${configs[*]}" "$args" "${files[@]}"
83-
84-
elif [[ "$hack_terraform_docs" == "1" ]]; then # Using awk script because terraform-docs is older than 0.8 and terraform 0.12 is used
85-
86-
if [[ ! $(command -v awk) ]]; then
87-
echo "ERROR: awk is required for terraform-docs hack to work with Terraform 0.12."
88-
exit 1
89-
fi
90-
91-
local tmp_file_awk
92-
tmp_file_awk=$(mktemp "${TMPDIR:-/tmp}/terraform-docs-XXXXXXXXXX")
93-
terraform_docs_awk "$tmp_file_awk"
94-
terraform_docs "$tmp_file_awk" "${configs[*]}" "$args" "${files[@]}"
95-
rm -f "$tmp_file_awk"
96-
97-
else # Using terraform 0.11 and no awk script is needed for that
98-
99-
terraform_docs "0" "${configs[*]}" "$args" "${files[@]}"
100-
101-
fi
102-
}
103-
104-
#######################################################################
105-
# Wrapper around `terraform-docs` tool that check and change/create
106-
# (depends on provided hook_config) terraform documentation in
107-
# markdown format
108-
# Arguments:
109-
# terraform_docs_awk_file (string) filename where awk hack for old
110-
# `terraform-docs` was written. Needed for TF 0.12+.
111-
# Hack skipped when `terraform_docs_awk_file == "0"`
112-
# hook_config (string with array) arguments that configure hook behavior
113-
# args (string with array) arguments that configure wrapped tool behavior
114-
# files (array) filenames to check
115-
#######################################################################
116-
function terraform_docs {
117-
local -r terraform_docs_awk_file="$1"
118-
local -r hook_config="$2"
119-
local args="$3"
120-
shift 3
121-
local -a -r files=("$@")
122-
12369
local -a paths
12470

12571
local index=0
@@ -142,7 +88,7 @@ function terraform_docs {
14288
local create_if_not_exist=false
14389
local use_standard_markers=true
14490

145-
read -r -a configs <<< "$hook_config"
91+
IFS=";" read -r -a configs <<< "$hook_config"
14692

14793
for c in "${configs[@]}"; do
14894

@@ -260,64 +206,17 @@ function terraform_docs {
260206

261207
replace_old_markers "$output_file"
262208

263-
if [[ "$terraform_docs_awk_file" == "0" ]]; then
264-
#? TF 0.12+ and terraform-docs 0.12.0+
265-
266-
#
267-
# If `--add-to-existing-file=false` (default behavior), check if "hook markers" exist in file,
268-
# and, if not, skip execution to avoid addition of terraform-docs section, as
269-
# terraform-docs in 'inject' mode adds markers by default if they are not present
270-
#
271-
if [[ $add_to_existing == false ]]; then
272-
have_marker=$(grep -o "$insertion_marker_begin" "$output_file") || unset have_marker
273-
[[ ! $have_marker ]] && continue
274-
fi
275-
# shellcheck disable=SC2086
276-
terraform-docs --output-mode="$output_mode" --output-file="$output_file" $tf_docs_formatter $args ./ > /dev/null
277-
278-
else
279-
#? TF 0.12+ and terraform-docs < 0.8
280-
#? Yes, we don't cover case of TF 0.12+ and terraform-docs 0.8-0.11
281-
#? but I probably just drop this section in next release of the hook,
282-
#? as there's no sense to support hacks for tool versions which were released more than 3 years ago
283-
284-
#
285-
# If `--add-to-existing-file=true` set, check if "hook markers" exist in file,
286-
# and, if not, append "hook markers" to the end of the file.
287-
#
288-
if [[ $add_to_existing == true ]]; then
289-
have_marker=$(grep -o "$insertion_marker_begin" "$output_file") || unset have_marker
290-
291-
if [[ ! $have_marker ]]; then
292-
# Use of insertion markers, when "add_to_existing=true" with no markers in the existing file
293-
echo "$insertion_marker_begin" >> "$output_file"
294-
echo "$insertion_marker_end" >> "$output_file"
295-
fi
296-
fi
297-
# Can't append extension for mktemp, so renaming instead
298-
local tmp_file_docs
299-
tmp_file_docs=$(mktemp "${TMPDIR:-/tmp}/terraform-docs-XXXXXXXXXX")
300-
mv "$tmp_file_docs" "$tmp_file_docs.tf"
301-
local tmp_file_docs_tf
302-
tmp_file_docs_tf="$tmp_file_docs.tf"
303-
304-
awk -f "$terraform_docs_awk_file" ./*.tf > "$tmp_file_docs_tf"
305-
306-
local -r tmp_file=$(mktemp)
307-
# shellcheck disable=SC2086
308-
terraform-docs --output-file="" $tf_docs_formatter $args "$tmp_file_docs_tf" > "$tmp_file"
309-
rm -f "$tmp_file_docs_tf"
310-
311-
# Use of insertion markers to insert the terraform-docs output between the markers
312-
# Replace content between markers with the placeholder - https://stackoverflow.com/questions/1212799/how-do-i-extract-lines-between-two-line-delimiters-in-perl#1212834
313-
perl_expression="if (/$insertion_marker_begin/../$insertion_marker_end/) { print \$_ if /$insertion_marker_begin/; print \"I_WANT_TO_BE_REPLACED\\n\$_\" if /$insertion_marker_end/;} else { print \$_ }"
314-
perl -i -ne "$perl_expression" "$output_file"
315-
316-
# Replace placeholder with the content of the file
317-
perl -i -e 'open(F, "'"$tmp_file"'"); $f = join "", <F>; while(<>){if (/I_WANT_TO_BE_REPLACED/) {print $f} else {print $_};}' "$output_file"
318-
319-
rm -f "$tmp_file"
209+
#
210+
# If `--add-to-existing-file=false` (default behavior), check if "hook markers" exist in file,
211+
# and, if not, skip execution to avoid addition of terraform-docs section, as
212+
# terraform-docs in 'inject' mode adds markers by default if they are not present
213+
#
214+
if [[ $add_to_existing == false ]]; then
215+
have_marker=$(grep -o "$insertion_marker_begin" "$output_file") || unset have_marker
216+
[[ ! $have_marker ]] && continue
320217
fi
218+
# shellcheck disable=SC2086
219+
terraform-docs --output-mode="$output_mode" --output-file="$output_file" $tf_docs_formatter $args ./ > /dev/null
321220

322221
popd > /dev/null
323222
done
@@ -326,169 +225,4 @@ function terraform_docs {
326225
rm -f "$config_file_no_color"
327226
}
328227

329-
#######################################################################
330-
# Function which creates file with `awk` hacks for old versions of
331-
# `terraform-docs`
332-
# Arguments:
333-
# output_file (string) filename where hack will be written to
334-
#######################################################################
335-
function terraform_docs_awk {
336-
local -r output_file=$1
337-
338-
cat << "EOF" > "$output_file"
339-
# This script converts Terraform 0.12 variables/outputs to something suitable for `terraform-docs`
340-
# As of terraform-docs v0.6.0, HCL2 is not supported. This script is a *dirty hack* to get around it.
341-
# https://github.com/terraform-docs/terraform-docs/
342-
# https://github.com/terraform-docs/terraform-docs/issues/62
343-
# Script was originally found here: https://github.com/cloudposse/build-harness/blob/master/bin/terraform-docs.awk
344-
{
345-
if ( $0 ~ /\{/ ) {
346-
braceCnt++
347-
}
348-
if ( $0 ~ /\}/ ) {
349-
braceCnt--
350-
}
351-
# ----------------------------------------------------------------------------------------------
352-
# variable|output "..." {
353-
# ----------------------------------------------------------------------------------------------
354-
# [END] variable/output block
355-
if (blockCnt > 0 && blockTypeCnt == 0 && blockDefaultCnt == 0) {
356-
if (braceCnt == 0 && blockCnt > 0) {
357-
blockCnt--
358-
print $0
359-
}
360-
}
361-
# [START] variable or output block started
362-
if ($0 ~ /^[[:space:]]*(variable|output)[[:space:]][[:space:]]*"(.*?)"/) {
363-
# Normalize the braceCnt and block (should be 1 now)
364-
braceCnt = 1
365-
blockCnt = 1
366-
# [CLOSE] "default" and "type" block
367-
blockDefaultCnt = 0
368-
blockTypeCnt = 0
369-
# Print variable|output line
370-
print $0
371-
}
372-
# ----------------------------------------------------------------------------------------------
373-
# default = ...
374-
# ----------------------------------------------------------------------------------------------
375-
# [END] multiline "default" continues/ends
376-
if (blockCnt > 0 && blockTypeCnt == 0 && blockDefaultCnt > 0) {
377-
print $0
378-
# Count opening blocks
379-
blockDefaultCnt += gsub(/\(/, "")
380-
blockDefaultCnt += gsub(/\[/, "")
381-
blockDefaultCnt += gsub(/\{/, "")
382-
# Count closing blocks
383-
blockDefaultCnt -= gsub(/\)/, "")
384-
blockDefaultCnt -= gsub(/\]/, "")
385-
blockDefaultCnt -= gsub(/\}/, "")
386-
}
387-
# [START] multiline "default" statement started
388-
if (blockCnt > 0 && blockTypeCnt == 0 && blockDefaultCnt == 0) {
389-
if ($0 ~ /^[[:space:]][[:space:]]*(default)[[:space:]][[:space:]]*=/) {
390-
if ($3 ~ "null") {
391-
print " default = \"null\""
392-
} else {
393-
print $0
394-
# Count opening blocks
395-
blockDefaultCnt += gsub(/\(/, "")
396-
blockDefaultCnt += gsub(/\[/, "")
397-
blockDefaultCnt += gsub(/\{/, "")
398-
# Count closing blocks
399-
blockDefaultCnt -= gsub(/\)/, "")
400-
blockDefaultCnt -= gsub(/\]/, "")
401-
blockDefaultCnt -= gsub(/\}/, "")
402-
}
403-
}
404-
}
405-
# ----------------------------------------------------------------------------------------------
406-
# type = ...
407-
# ----------------------------------------------------------------------------------------------
408-
# [END] multiline "type" continues/ends
409-
if (blockCnt > 0 && blockTypeCnt > 0 && blockDefaultCnt == 0) {
410-
# The following 'print $0' would print multiline type definitions
411-
#print $0
412-
# Count opening blocks
413-
blockTypeCnt += gsub(/\(/, "")
414-
blockTypeCnt += gsub(/\[/, "")
415-
blockTypeCnt += gsub(/\{/, "")
416-
# Count closing blocks
417-
blockTypeCnt -= gsub(/\)/, "")
418-
blockTypeCnt -= gsub(/\]/, "")
419-
blockTypeCnt -= gsub(/\}/, "")
420-
}
421-
# [START] multiline "type" statement started
422-
if (blockCnt > 0 && blockTypeCnt == 0 && blockDefaultCnt == 0) {
423-
if ($0 ~ /^[[:space:]][[:space:]]*(type)[[:space:]][[:space:]]*=/ ) {
424-
if ($3 ~ "object") {
425-
print " type = \"object\""
426-
} else {
427-
# Convert multiline stuff into single line
428-
if ($3 ~ /^[[:space:]]*list[[:space:]]*\([[:space:]]*$/) {
429-
type = "list"
430-
} else if ($3 ~ /^[[:space:]]*string[[:space:]]*\([[:space:]]*$/) {
431-
type = "string"
432-
} else if ($3 ~ /^[[:space:]]*map[[:space:]]*\([[:space:]]*$/) {
433-
type = "map"
434-
} else {
435-
type = $3
436-
}
437-
# legacy quoted types: "string", "list", and "map"
438-
if (type ~ /^[[:space:]]*"(.*?)"[[:space:]]*$/) {
439-
print " type = " type
440-
} else {
441-
print " type = \"" type "\""
442-
}
443-
}
444-
# Count opening blocks
445-
blockTypeCnt += gsub(/\(/, "")
446-
blockTypeCnt += gsub(/\[/, "")
447-
blockTypeCnt += gsub(/\{/, "")
448-
# Count closing blocks
449-
blockTypeCnt -= gsub(/\)/, "")
450-
blockTypeCnt -= gsub(/\]/, "")
451-
blockTypeCnt -= gsub(/\}/, "")
452-
}
453-
}
454-
# ----------------------------------------------------------------------------------------------
455-
# description = ...
456-
# ----------------------------------------------------------------------------------------------
457-
# [PRINT] single line "description"
458-
if (blockCnt > 0 && blockTypeCnt == 0 && blockDefaultCnt == 0) {
459-
if ($0 ~ /^[[:space:]][[:space:]]*description[[:space:]][[:space:]]*=/) {
460-
print $0
461-
}
462-
}
463-
# ----------------------------------------------------------------------------------------------
464-
# value = ...
465-
# ----------------------------------------------------------------------------------------------
466-
## [PRINT] single line "value"
467-
#if (blockCnt > 0 && blockTypeCnt == 0 && blockDefaultCnt == 0) {
468-
# if ($0 ~ /^[[:space:]][[:space:]]*value[[:space:]][[:space:]]*=/) {
469-
# print $0
470-
# }
471-
#}
472-
# ----------------------------------------------------------------------------------------------
473-
# Newlines, comments, everything else
474-
# ----------------------------------------------------------------------------------------------
475-
#if (blockTypeCnt == 0 && blockDefaultCnt == 0) {
476-
# Comments with '#'
477-
if ($0 ~ /^[[:space:]]*#/) {
478-
print $0
479-
}
480-
# Comments with '//'
481-
if ($0 ~ /^[[:space:]]*\/\//) {
482-
print $0
483-
}
484-
# Newlines
485-
if ($0 ~ /^[[:space:]]*$/) {
486-
print $0
487-
}
488-
#}
489-
}
490-
EOF
491-
492-
}
493-
494228
[ "${BASH_SOURCE[0]}" != "$0" ] || main "$@"

0 commit comments

Comments
 (0)