From 353c4b231cc792d68a29f76fd41945eaa8b846c5 Mon Sep 17 00:00:00 2001 From: Andy Chen Date: Mon, 24 Jun 2024 11:04:44 -0700 Subject: [PATCH] feat(hooks): check component is defined inside the correct component file --- docs/modules/component.md | 0 hooks/component-in-component-files/check | 62 +++++++++++++++++++ .../fixtures/bad-component.tf | 7 +++ .../fixtures/bad-foo-bar.tf | 7 +++ .../fixtures/foo-component/main.tf | 7 +++ .../fixtures/good-foo-bar.tf | 7 +++ hooks/component-in-component-files/test | 30 +++++++++ 7 files changed, 120 insertions(+) create mode 100644 docs/modules/component.md create mode 100755 hooks/component-in-component-files/check create mode 100644 hooks/component-in-component-files/fixtures/bad-component.tf create mode 100644 hooks/component-in-component-files/fixtures/bad-foo-bar.tf create mode 100644 hooks/component-in-component-files/fixtures/foo-component/main.tf create mode 100644 hooks/component-in-component-files/fixtures/good-foo-bar.tf create mode 100755 hooks/component-in-component-files/test diff --git a/docs/modules/component.md b/docs/modules/component.md new file mode 100644 index 0000000..e69de29 diff --git a/hooks/component-in-component-files/check b/hooks/component-in-component-files/check new file mode 100755 index 0000000..0c49916 --- /dev/null +++ b/hooks/component-in-component-files/check @@ -0,0 +1,62 @@ +#!/bin/bash -e + +# Function to check if module names follow the 'component_' convention +check_component_module_id() { + local module_name="$1" + if [[ ! "$module_name" =~ ^component_ ]]; then + echo "ERROR: Module name '$module_name' does not follow the 'component_' naming convention." + return 1 + fi + return 0 +} + +# Function to check if the filename matches the expected filename derived from the module 'name' attribute +check_component_file_name() { + local module_name="$1" + local component_name="$2" + local filename="$3" + local expected_file="${component_name//_/-}.tf" + + if [[ "$filename" != "$expected_file" && "$filename" != "main.tf" ]]; then + echo "ERROR: Module '$module_name' with name '$component_name' should be in '$expected_file' or 'main.tf', but found in '$filename'." + return 1 + fi + return 0 +} + +check_component_files() { + has_error=0 + for file in "$@"; do + # Extract the filename from the path + filename=$(basename "$file") + + # Check only '.tf' files to avoid processing other file types + if [[ "$filename" == *.tf ]]; then + # Read through the file line by line to find module blocks and extract the 'name' field + module_name="" + while IFS= read -r line; do + # Check if the line declares a module + if [[ "$line" =~ ^module\ \" ]]; then + module_name=$(echo "$line" | awk -F\" '{print $2}') + check_component_module_id "$module_name" || has_error=1 + fi + # When module_name is set, look for the name attribute within the block + if [[ -n "$module_name" && "$line" =~ ^\ *name\ *= ]]; then + component_name=$(echo "$line" | awk -F\" '{print $2}') + check_component_file_name "$module_name" "$component_name" "$filename" || has_error=1 + # Reset module_name to ensure correct block processing + module_name="" + fi + done <"$file" + fi + done + return $has_error +} + +# Execute the check across all .tf files passed as arguments +if ! check_component_files "$@"; then + echo "components defined in thef iles that do not match our naming convention: '.tf'" + echo "See: https://open-turo.github.io/standards-terraform/modules/component/" +fi + +exit $has_error diff --git a/hooks/component-in-component-files/fixtures/bad-component.tf b/hooks/component-in-component-files/fixtures/bad-component.tf new file mode 100644 index 0000000..ad3b1ae --- /dev/null +++ b/hooks/component-in-component-files/fixtures/bad-component.tf @@ -0,0 +1,7 @@ +module "foo_bar_component" { + source = "app.terraform.io/turo/component-metadata/null" + version = "3.1.2" + + name = "foo-bar" + system_metadata = var.metadata_module.parent_system_metadata +} diff --git a/hooks/component-in-component-files/fixtures/bad-foo-bar.tf b/hooks/component-in-component-files/fixtures/bad-foo-bar.tf new file mode 100644 index 0000000..f451ddc --- /dev/null +++ b/hooks/component-in-component-files/fixtures/bad-foo-bar.tf @@ -0,0 +1,7 @@ +module "component_foo_bar" { + source = "app.terraform.io/turo/component-metadata/null" + version = "3.1.2" + + name = "foo-bar" + system_metadata = var.metadata_module.parent_system_metadata +} diff --git a/hooks/component-in-component-files/fixtures/foo-component/main.tf b/hooks/component-in-component-files/fixtures/foo-component/main.tf new file mode 100644 index 0000000..c4aee84 --- /dev/null +++ b/hooks/component-in-component-files/fixtures/foo-component/main.tf @@ -0,0 +1,7 @@ +module "component_good_foo_bar" { + source = "app.terraform.io/turo/component-metadata/null" + version = "3.1.2" + + name = "good-foo-bar" + system_metadata = var.metadata_module.parent_system_metadata +} diff --git a/hooks/component-in-component-files/fixtures/good-foo-bar.tf b/hooks/component-in-component-files/fixtures/good-foo-bar.tf new file mode 100644 index 0000000..c4aee84 --- /dev/null +++ b/hooks/component-in-component-files/fixtures/good-foo-bar.tf @@ -0,0 +1,7 @@ +module "component_good_foo_bar" { + source = "app.terraform.io/turo/component-metadata/null" + version = "3.1.2" + + name = "good-foo-bar" + system_metadata = var.metadata_module.parent_system_metadata +} diff --git a/hooks/component-in-component-files/test b/hooks/component-in-component-files/test new file mode 100755 index 0000000..4a507f3 --- /dev/null +++ b/hooks/component-in-component-files/test @@ -0,0 +1,30 @@ +#!/bin/bash -e + +# get the directory of the script +script_directory="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" + +echo "testing: $script_directory" + +echo "testing: check $script_directory/fixtures/good-foo-bar.tf" +"$script_directory/check" "$script_directory/fixtures/good-foo-bar.tf" + +echo "testing: check $script_directory/fixtures/foo-component/main.tf" +"$script_directory/check" "$script_directory/fixtures/foo-component/main.tf" + +# check to see if the next file failed +echo "testing: check $script_directory/fixtures/bad-foo-bar.tf" +echo " expecting error" +if "$script_directory/check" "$script_directory/fixtures/bad-foo-bar.tf"; then + echo "ERROR: should have failed" + exit 1 +fi + +# check to see if the next file failed +echo "testing: check $script_directory/fixtures/bad-component.tf" +echo " expecting error" +if "$script_directory/check" "$script_directory/fixtures/bad-component.tf"; then + echo "ERROR: should have failed" + exit 1 +fi + +echo "testing: PASS"