Skip to content

Instantly share code, notes, and snippets.

@slmg
Last active October 3, 2020 09:37
Show Gist options
  • Save slmg/146c073d910d6d83dba37a329e770adf to your computer and use it in GitHub Desktop.
Save slmg/146c073d910d6d83dba37a329e770adf to your computer and use it in GitHub Desktop.
terraform-docs pre-commit hook
#!/usr/bin/env bash
#
# Auto-generate documentation via terraform-docs.
# https://github.com/segmentio/terraform-docs
#
# This hooks is based on a dockerized version which extends the original program
# by allowing to replace only part of a README file, instead of a full overwrite.
# https://github.com/cytopia/docker-terraform-docs
# Exit on error.
set -e
# Exit if docker is not available.
command -v docker > /dev/null || {
exit 1
}
docker_tfd() {
docker container run --rm \
-v "$(pwd)":/data \
cytopia/terraform-docs:0.9.1 \
terraform-docs --sort-by-required markdown "$1" > "$1"/README.md 2> /dev/null
}
docker_tfd_replace() {
docker container run --rm \
-v "$(pwd)":/data \
cytopia/terraform-docs:0.9.1 \
terraform-docs-replace --sort-by-required markdown "$1" 2> /dev/null
}
# Only run this hook for files matching *.tf or README.md, exit otherwise.
staged_files=$(git diff --cached --name-only | grep -E '.*\.tf$|^README.md') || {
exit 0
}
# Determine whether it is suitable to generate doc for the main README.md.
# Does README.md exist in the working directory?
test -f README.md && {
# Are relevant markups defined inside README.md?
grep --quiet -E "<\!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->" README.md && {
# Was any top level .tf file or README.md changed?
test "$(echo "${staged_files[*]}" | grep -vE '^modules/.*')" && {
# Overwrite doc inside README.md.
docker_tfd_replace README.md
git add ./README.md
}
}
}
# Stop execution if no modules files are staged.
module_files=$(echo "${staged_files[*]}" | grep -E '^modules/.*') || {
exit 0
}
# Speed up execution by only executing docker_tfd once per staged module info,
# regardless of how many files have diffs.
modules=()
for file in $module_files; do
# There may be multiple file belonging to the same module.
file_parent=$(dirname "$file")
# Therefore the array modules is likely going to contain duplicate dir.
modules+=( "$file_parent" )
done
# shellcheck disable=SC2207
# Remove duplicate dirs.
uniq_modules=( $(echo "${modules[@]}" | tr ' ' '\n' | sort -u ) )
# Overwritte modules' README.md with up-to-date documentation.
for module in "${uniq_modules[@]}"; do
docker_tfd "$module" && {
git add "./$module/README.md"
}
done

Terraform-docs pre-commit hook

This hook leverages the excellent https://github.com/segmentio/terraform-docs and its dockerized version https://github.com/cytopia/docker-terraform-docs to automatically update README files for every commit.

Installation

Either copy this hook into .git/hooks/ or into a custom directory. If you opt for the latest option, run the below command to add it to your local .gitconfig.

# Example with a hook dir .githooks/
git config --local core.hooksPath .githooks

Usage

Example of working directory structure parsed by the hook:

$ tree
.
|-- main.tf
|-- modules
|   |-- module
|       |-- main.tf
|       |-- variables.tf
|-- README.md
|-- variables.tf

A README.md file is fully auto-generated for every modules found in modules/. A header can optionally be created by adding the below snippet at the beginning of modules/module/main.tf:

/**
* # Main title
*
* Other markdown-friendly content.
*/

In addition, the main README.md located at the root of your project will be partially generated if it contains the following pair of tags:

<\!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

Enjoy!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment