diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 9ca16f0..d354141 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -2,18 +2,18 @@ ## Accepted Rules -Terraform Language rules implement recommendations from the [Terraform Language documentation](https://www.terraform.io/language). This ruleset _does not_ provide configurable rules for personal/team style or usage preferences. If you'd like to enforce stylistic rules beyond the official Terraform Language recommendations, you should [author your own ruleset plugin](https://github.com/terraform-linters/tflint/blob/master/docs/developer-guide/plugins.md). +OpenTofu Language rules implement recommendations from the [OpenTofu Language documentation](https://opentofu.org/docs/language/). This ruleset _does not_ provide configurable rules for personal/team style or usage preferences. If you'd like to enforce stylistic rules beyond the official OpenTofu Language recommendations, you should [author your own ruleset plugin](https://github.com/terraform-linters/tflint/blob/master/docs/developer-guide/plugins.md). -In rare circumstances, we may also accept rules that detect language usage errors that are _not_ already detected by `terraform validate`. +In rare circumstances, we may also accept rules that detect language usage errors that are _not_ already detected by `tofu validate`. -If you are unsure whether your proposed rule meets these criteria, [open a discussion](https://github.com/terraform-linters/tflint-ruleset-terraform/discussions/new?category=ideas) thread first before authoring a pull request. +If you are unsure whether your proposed rule meets these criteria, [open a discussion](https://github.com/diofeher/tflint-ruleset-opentofu/discussions/new?category=ideas) thread first before authoring a pull request. ## Authoring a Rule Each rule should have: * A source file implementing the rule -* Tests that check expected issues against different Terraform configurations to cover applicable cases +* Tests that check expected issues against different OpenTofu configurations to cover applicable cases * Documentation explaining the rule, its motivation, and how users should fix their configuration -You will also need to add your rule to applicable [presets](https://github.com/terraform-linters/tflint-ruleset-terraform/blob/main/rules/preset.go). +You will also need to add your rule to applicable [presets](https://github.com/terraform-linters/tflint-ruleset-opentofu/blob/main/rules/preset.go). diff --git a/Makefile b/Makefile index ae8ed7c..9110895 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ build: install: build mkdir -p ~/.tflint.d/plugins - mv ./tflint-ruleset-terraform ~/.tflint.d/plugins + mv ./tflint-ruleset-opentofu ~/.tflint.d/plugins release: cd tools/release; go run main.go diff --git a/README.md b/README.md index 201bb89..41063d0 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,13 @@ -# TFLint Ruleset for Terraform Language -[![Build Status](https://github.com/terraform-linters/tflint-ruleset-terraform/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/terraform-linters/tflint-ruleset-terraform/actions) -[![GitHub release](https://img.shields.io/github/release/terraform-linters/tflint-ruleset-terraform.svg)](https://github.com/terraform-linters/tflint-ruleset-terraform/releases/latest) +# TFLint Ruleset for OpenTofu Language +[![Build Status](https://github.com/diofeher/tflint-ruleset-opentofu/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/diofeher/tflint-ruleset-opentofu/actions) +[![GitHub release](https://img.shields.io/github/release/terraform-linters/tflint-ruleset-terraform.svg)](https://github.com/diofeher/tflint-ruleset-opentofu/releases/latest) [![License: MPL 2.0](https://img.shields.io/badge/License-MPL%202.0-blue.svg)](LICENSE) -TFLint ruleset plugin for Terraform Language +TFLint ruleset plugin for OpenTofu Language -This ruleset focus on possible errors and best practices about Terraform Language. +This project is forked from https://github.com/terraform-linters/tflint-ruleset-terraform + +This ruleset focus on possible errors and best practices about OpenTofu Language. ## Requirements @@ -19,16 +21,16 @@ This ruleset is built into TFLint, so you usually don't need to worry about how ``` $ tflint -v TFLint version 0.52.0 -+ ruleset.terraform (0.8.0-bundled) ++ ruleset.opentofu (0.8.0-bundled) ``` If you want to use a version different from the built-in version, you can declare `plugin` in `.tflint.hcl` as follows and install it with `tflint --init`: ```hcl -plugin "terraform" { +plugin "opentofu" { enabled = true version = "0.13.0" - source = "github.com/terraform-linters/tflint-ruleset-terraform" + source = "github.com/diofeher/tflint-ruleset-opentofu" } ``` @@ -55,7 +57,7 @@ $ make install Note that if you install the plugin with `make install`, you must omit the `version` and `source` attributes in` .tflint.hcl`: ```hcl -plugin "terraform" { +plugin "opentofu" { enabled = true } ``` diff --git a/docs/rules/terraform_comment_syntax.md b/docs/rules/opentofu_comment_syntax.md similarity index 84% rename from docs/rules/terraform_comment_syntax.md rename to docs/rules/opentofu_comment_syntax.md index 78a6fea..2b69585 100644 --- a/docs/rules/terraform_comment_syntax.md +++ b/docs/rules/opentofu_comment_syntax.md @@ -18,7 +18,7 @@ Warning: Single line comments should begin with # (terraform_comment_syntax) on main.tf line 2: 2: // Bad -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_comment_syntax.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_comment_syntax.md ``` ## Why diff --git a/docs/rules/terraform_deprecated_index.md b/docs/rules/opentofu_deprecated_index.md similarity index 85% rename from docs/rules/terraform_deprecated_index.md rename to docs/rules/opentofu_deprecated_index.md index dc7efb7..fa5ad1c 100644 --- a/docs/rules/terraform_deprecated_index.md +++ b/docs/rules/opentofu_deprecated_index.md @@ -22,7 +22,7 @@ Warning: List items should be accessed using square brackets (terraform_deprecat on example.tf line 3: 3: value = list.0 -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_deprecated_index.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_deprecated_index.md ``` ```hcl @@ -41,7 +41,7 @@ Warning: List items should be accessed using square brackets (terraform_deprecat on example.tf line 3: 3: value = list.*.a -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_deprecated_index.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_deprecated_index.md ``` ## Why diff --git a/docs/rules/terraform_deprecated_interpolation.md b/docs/rules/opentofu_deprecated_interpolation.md similarity index 88% rename from docs/rules/terraform_deprecated_interpolation.md rename to docs/rules/opentofu_deprecated_interpolation.md index b4dd447..b9b2fcc 100644 --- a/docs/rules/terraform_deprecated_interpolation.md +++ b/docs/rules/opentofu_deprecated_interpolation.md @@ -25,7 +25,7 @@ Warning: Interpolation-only expressions are deprecated in Terraform v0.12.14 (te on example.tf line 2: 2: instance_type = "${var.type}" -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_deprecated_interpolation.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_deprecated_interpolation.md ``` diff --git a/docs/rules/terraform_deprecated_lookup.md b/docs/rules/opentofu_deprecated_lookup.md similarity index 89% rename from docs/rules/terraform_deprecated_lookup.md rename to docs/rules/opentofu_deprecated_lookup.md index 4666b9c..2636f51 100644 --- a/docs/rules/terraform_deprecated_lookup.md +++ b/docs/rules/opentofu_deprecated_lookup.md @@ -22,7 +22,7 @@ Warning: [Fixable] Lookup with 2 arguments is deprecated (terraform_deprecated_l on main.tf line 3: 3: value = lookup(local.map, "a") -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.5.0/docs/rules/terraform_deprecated_lookup.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.5.0/docs/rules/opentofu_deprecated_lookup.md ``` ## Why diff --git a/docs/rules/terraform_documented_outputs.md b/docs/rules/opentofu_documented_outputs.md similarity index 79% rename from docs/rules/terraform_documented_outputs.md rename to docs/rules/opentofu_documented_outputs.md index 915f7b2..2813236 100644 --- a/docs/rules/terraform_documented_outputs.md +++ b/docs/rules/opentofu_documented_outputs.md @@ -29,14 +29,14 @@ Notice: `no_description` output has no description (terraform_documented_outputs on template.tf line 1: 1: output "no_description" { -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_documented_outputs.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_documented_outputs.md Notice: `empty_description` output has no description (terraform_documented_outputs) on template.tf line 5: 5: output "empty_description" { -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_documented_outputs.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_documented_outputs.md ``` diff --git a/docs/rules/terraform_documented_variables.md b/docs/rules/opentofu_documented_variables.md similarity index 79% rename from docs/rules/terraform_documented_variables.md rename to docs/rules/opentofu_documented_variables.md index e14de31..0da80de 100644 --- a/docs/rules/terraform_documented_variables.md +++ b/docs/rules/opentofu_documented_variables.md @@ -29,14 +29,14 @@ Notice: `no_description` variable has no description (terraform_documented_varia on template.tf line 1: 1: variable "no_description" { -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_documented_variables.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_documented_variables.md Notice: `empty_description` variable has no description (terraform_documented_variables) on template.tf line 5: 5: variable "empty_description" { -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_documented_variables.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_documented_variables.md ``` diff --git a/docs/rules/terraform_empty_list_equality.md b/docs/rules/opentofu_empty_list_equality.md similarity index 89% rename from docs/rules/terraform_empty_list_equality.md rename to docs/rules/opentofu_empty_list_equality.md index 96be19d..52c9b00 100644 --- a/docs/rules/terraform_empty_list_equality.md +++ b/docs/rules/opentofu_empty_list_equality.md @@ -25,7 +25,7 @@ Warning: Comparing a collection with an empty list is invalid. To detect an empt on test.tf line 5: 5: count = var.my_list == [] ? 0 : 1 -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_empty_list_equality.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_empty_list_equality.md ``` diff --git a/docs/rules/terraform_json_syntax.md b/docs/rules/opentofu_json_syntax.md similarity index 93% rename from docs/rules/terraform_json_syntax.md rename to docs/rules/opentofu_json_syntax.md index c059621..0ca9bd5 100644 --- a/docs/rules/terraform_json_syntax.md +++ b/docs/rules/opentofu_json_syntax.md @@ -17,7 +17,7 @@ Warning: JSON configuration uses array syntax at root, expected object (terrafor on main.tf.json line 1: 1: [{"resource": {"aws_instance": {"example": {"ami": "ami-12345678"}}}}] -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_json_syntax.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_json_syntax.md ``` ## Why diff --git a/docs/rules/terraform_map_duplicate_keys.md b/docs/rules/opentofu_map_duplicate_keys.md similarity index 85% rename from docs/rules/terraform_map_duplicate_keys.md rename to docs/rules/opentofu_map_duplicate_keys.md index 4c18de9..1de419e 100644 --- a/docs/rules/terraform_map_duplicate_keys.md +++ b/docs/rules/opentofu_map_duplicate_keys.md @@ -25,7 +25,7 @@ Warning: Duplicate key: "bar", first defined at main.tf:4,5-8 (terraform_map_dup on main.tf line 5: 5: bar = 3 // duplicated key -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.9.0/docs/rules/terraform_map_duplicate_keys.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.9.0/docs/rules/opentofu_map_duplicate_keys.md ``` ## Why diff --git a/docs/rules/terraform_module_pinned_source.md b/docs/rules/opentofu_module_pinned_source.md similarity index 83% rename from docs/rules/terraform_module_pinned_source.md rename to docs/rules/opentofu_module_pinned_source.md index e2aa109..d8b6333 100644 --- a/docs/rules/terraform_module_pinned_source.md +++ b/docs/rules/opentofu_module_pinned_source.md @@ -55,21 +55,21 @@ Warning: Module source "git://hashicorp.com/consul.git" is not pinned (terraform on template.tf line 2: 2: source = "git://hashicorp.com/consul.git" -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_module_pinned_source.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_module_pinned_source.md Warning: Module source "git://hashicorp.com/consul.git?ref=master" uses a default branch as ref (master) (terraform_module_pinned_source) on template.tf line 6: 6: source = "git://hashicorp.com/consul.git?ref=master" -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_module_pinned_source.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_module_pinned_source.md Warning: Module source "hg::http://hashicorp.com/consul.hg?rev=default" uses a default branch as rev (default) (terraform_module_pinned_source) on template.tf line 10: 10: source = "hg::http://hashicorp.com/consul.hg?rev=default" -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_module_pinned_source.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_module_pinned_source.md ``` @@ -100,14 +100,14 @@ Warning: Module source "git://hashicorp.com/consul.git" is not pinned (terraform on template.tf line 2: 2: source = "git://hashicorp.com/consul.git" -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_module_pinned_source.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_module_pinned_source.md Warning: Module source "git://hashicorp.com/consul.git?ref=feature" uses a ref which is not a semantic version string (terraform_module_pinned_source) on template.tf line 6: 6: source = "git://hashicorp.com/consul.git?ref=feature" -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_module_pinned_source.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_module_pinned_source.md ``` diff --git a/docs/rules/terraform_module_shallow_clone.md b/docs/rules/opentofu_module_shallow_clone.md similarity index 90% rename from docs/rules/terraform_module_shallow_clone.md rename to docs/rules/opentofu_module_shallow_clone.md index d71fe5e..49208f5 100644 --- a/docs/rules/terraform_module_shallow_clone.md +++ b/docs/rules/opentofu_module_shallow_clone.md @@ -19,7 +19,7 @@ Warning: Module source "git::ssh://git@github.com/hashicorp/consul.git?ref=v1.0. on main.tf line 2: 3: source = "git::ssh://git@github.com/hashicorp/consul.git?ref=v1.0.0" -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.13.0/docs/rules/terraform_module_shallow_clone.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.13.0/docs/rules/opentofu_module_shallow_clone.md ``` ## Why diff --git a/docs/rules/terraform_module_version.md b/docs/rules/opentofu_module_version.md similarity index 92% rename from docs/rules/terraform_module_version.md rename to docs/rules/opentofu_module_version.md index 73e366a..91c5ffa 100644 --- a/docs/rules/terraform_module_version.md +++ b/docs/rules/opentofu_module_version.md @@ -44,7 +44,7 @@ Warning: module "latest" should specify a version (terraform_module_version) on main.tf line 11: 11: module "latest" { -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_module_version.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_module_version.md ``` ### Exact @@ -77,7 +77,7 @@ Warning: module "range" should specify an exact version, but a range was found ( on main.tf line 8: 8: version = ">= 1.0.0" -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/v0.1.0/master/docs/rules/terraform_module_version.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/v0.1.0/master/docs/rules/opentofu_module_version.md ``` ## Why diff --git a/docs/rules/terraform_naming_convention.md b/docs/rules/opentofu_naming_convention.md similarity index 90% rename from docs/rules/terraform_naming_convention.md rename to docs/rules/opentofu_naming_convention.md index 671c0e0..8a9a6a7 100644 --- a/docs/rules/terraform_naming_convention.md +++ b/docs/rules/opentofu_naming_convention.md @@ -77,7 +77,7 @@ Notice: data name `camelCase` must match the following format: snake_case (terra on template.tf line 1: 1: data "aws_eip" "camelCase" { -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_naming_convention.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_naming_convention.md ``` @@ -113,7 +113,7 @@ Notice: resource name `Invalid_Name_With_Number123` must match the following Reg on template.tf line 1: 1: resource "aws_eip" "Invalid_Name_With_Number123" { -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_naming_convention.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_naming_convention.md ``` @@ -155,7 +155,7 @@ Notice: resource name `Invalid_Name_With_Number123` must match the following for on template.tf line 1: 1: resource "aws_eip" "Invalid_Name_With_Number123" { -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_naming_convention.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_naming_convention.md ``` @@ -199,7 +199,7 @@ Notice: module name `invalid_module_with_number_1a` must match the following Reg on template.tf line 9: 9: module "invalid_module_with_number_1a" { -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_naming_convention.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_naming_convention.md ``` @@ -273,7 +273,7 @@ Notice: local value name `invalid-name` must match the following format: snake_c on template.tf line 12: 12: invalid-name = "dashes are not allowed with snake_case" -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_naming_convention.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_naming_convention.md ``` diff --git a/docs/rules/terraform_required_providers.md b/docs/rules/opentofu_required_providers.md similarity index 83% rename from docs/rules/terraform_required_providers.md rename to docs/rules/opentofu_required_providers.md index 8dfa25e..a058b39 100644 --- a/docs/rules/terraform_required_providers.md +++ b/docs/rules/opentofu_required_providers.md @@ -31,7 +31,7 @@ Warning: Missing version constraint for provider "template" in `required_provide on main.tf line 1: 1: provider "template" {} -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_required_providers.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_required_providers.md ```
@@ -51,14 +51,14 @@ Warning: provider.template: version constraint should be specified via "required on main.tf line 1: 1: provider "template" { -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_required_providers.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_required_providers.md Warning: Missing version constraint for provider "template" in `required_providers` (terraform_required_providers) on main.tf line 1: 1: provider "template" { -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_required_providers.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_required_providers.md ```
@@ -84,7 +84,7 @@ Warning: Legacy version constraint for provider "template" in `required_provider on main.tf line 5: 5: template = "~> 2" -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_required_providers.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_required_providers.md ```
@@ -112,7 +112,7 @@ Warning: Missing `source` for provider "template" in `required_providers` (terra 6: version = "~> 2" 7: } -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_required_providers.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_required_providers.md ``` ## Why diff --git a/docs/rules/terraform_required_version.md b/docs/rules/opentofu_required_version.md similarity index 64% rename from docs/rules/terraform_required_version.md rename to docs/rules/opentofu_required_version.md index 4918bbd..0cde415 100644 --- a/docs/rules/terraform_required_version.md +++ b/docs/rules/opentofu_required_version.md @@ -26,12 +26,12 @@ $ tflint Warning: terraform "required_version" attribute is required -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_required_version.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_required_version.md ``` ## Why -The `required_version` setting can be used to constrain which versions of the Terraform CLI can be used with your configuration. -If the running version of Terraform doesn't match the constraints specified, Terraform will produce an error and exit without +The `required_version` setting can be used to constrain which versions of the OpenTofu CLI are compatible with your configuration. +If the running version of OpenTofu doesn't match the constraints specified, OpenTofu will produce an error and exit without taking any further actions. ## How To Fix diff --git a/docs/rules/terraform_standard_module_structure.md b/docs/rules/opentofu_standard_module_structure.md similarity index 86% rename from docs/rules/terraform_standard_module_structure.md rename to docs/rules/opentofu_standard_module_structure.md index ff24a21..011ccd1 100644 --- a/docs/rules/terraform_standard_module_structure.md +++ b/docs/rules/opentofu_standard_module_structure.md @@ -18,7 +18,7 @@ Warning: variable "v" should be moved from main.tf to variables.tf (terraform_st on main.tf line 1: 1: variable "v" {} -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_standard_module_structure.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_standard_module_structure.md ``` ## Why diff --git a/docs/rules/terraform_typed_variables.md b/docs/rules/opentofu_typed_variables.md similarity index 86% rename from docs/rules/terraform_typed_variables.md rename to docs/rules/opentofu_typed_variables.md index c0c231f..41eb8b3 100644 --- a/docs/rules/terraform_typed_variables.md +++ b/docs/rules/opentofu_typed_variables.md @@ -27,7 +27,7 @@ Warning: `no_type` variable has no type (terraform_typed_variables) on template.tf line 1: 1: variable "no_type" { -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_typed_variables.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_typed_variables.md ``` diff --git a/docs/rules/terraform_unused_declarations.md b/docs/rules/opentofu_unused_declarations.md similarity index 94% rename from docs/rules/terraform_unused_declarations.md rename to docs/rules/opentofu_unused_declarations.md index dccbd4a..3180ea5 100644 --- a/docs/rules/terraform_unused_declarations.md +++ b/docs/rules/opentofu_unused_declarations.md @@ -24,7 +24,7 @@ Warning: variable "not_used" is declared but not used (terraform_unused_declarat on config.tf line 1: 1: variable "not_used" { -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_unused_declarations.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_unused_declarations.md ``` diff --git a/docs/rules/terraform_unused_required_providers.md b/docs/rules/opentofu_unused_required_providers.md similarity index 94% rename from docs/rules/terraform_unused_required_providers.md rename to docs/rules/opentofu_unused_required_providers.md index 56953ab..b02858b 100644 --- a/docs/rules/terraform_unused_required_providers.md +++ b/docs/rules/opentofu_unused_required_providers.md @@ -35,7 +35,7 @@ Warning: provider 'null' is declared in required_providers but not used by the m 4: source = "hashicorp/null" 5: } -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_unused_required_providers.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.1.0/docs/rules/opentofu_unused_required_providers.md ``` ## Why diff --git a/docs/rules/terraform_workspace_remote.md b/docs/rules/opentofu_workspace_remote.md similarity index 94% rename from docs/rules/terraform_workspace_remote.md rename to docs/rules/opentofu_workspace_remote.md index f4b2c92..5791f93 100644 --- a/docs/rules/terraform_workspace_remote.md +++ b/docs/rules/opentofu_workspace_remote.md @@ -42,7 +42,7 @@ Warning: terraform.workspace should not be used with a 'remote' backend (terrafo 10: workspace = terraform.workspace 11: } -Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.5.0/docs/rules/terraform_workspace_remote.md +Reference: https://github.com/diofeher/tflint-ruleset-opentofu/blob/v0.5.0/docs/rules/opentofu_workspace_remote.md ``` ## Why diff --git a/go.mod b/go.mod index 3238ee2..f4a4365 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/terraform-linters/tflint-ruleset-terraform +module github.com/diofeher/tflint-ruleset-opentofu go 1.25.3 @@ -8,7 +8,7 @@ require ( github.com/hashicorp/go-getter v1.8.3 github.com/hashicorp/go-version v1.8.0 github.com/hashicorp/hcl/v2 v2.24.0 - github.com/hashicorp/terraform-registry-address v0.4.0 + github.com/opentofu/registry-address v0.0.0-20230922120653-901b9ae4061a github.com/terraform-linters/tflint-plugin-sdk v0.23.1 github.com/zclconf/go-cty v1.17.0 ) diff --git a/go.sum b/go.sum index c2e95cb..c0c8b33 100644 --- a/go.sum +++ b/go.sum @@ -129,8 +129,6 @@ github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bP github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/hcl/v2 v2.24.0 h1:2QJdZ454DSsYGoaE6QheQZjtKZSUs9Nh2izTWiwQxvE= github.com/hashicorp/hcl/v2 v2.24.0/go.mod h1:oGoO1FIQYfn/AgyOhlg9qLC6/nOJPX3qGbkZpYAcqfM= -github.com/hashicorp/terraform-registry-address v0.4.0 h1:S1yCGomj30Sao4l5BMPjTGZmCNzuv7/GDTDX99E9gTk= -github.com/hashicorp/terraform-registry-address v0.4.0/go.mod h1:LRS1Ay0+mAiRkUyltGT+UHWkIqTFvigGn/LbMshfflE= github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc= github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8= @@ -153,6 +151,8 @@ github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQ github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= +github.com/opentofu/registry-address v0.0.0-20230922120653-901b9ae4061a h1:NyM/PPbc+kxxv2d4OKfE32C5fLtVTLceyg4YKKCYO9Y= +github.com/opentofu/registry-address v0.0.0-20230922120653-901b9ae4061a/go.mod h1:HzQhpVo/NJnGmN+7FPECCVCA5ijU7AUcvf39enBKYOc= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= diff --git a/main.go b/main.go index b67f6de..53faba4 100644 --- a/main.go +++ b/main.go @@ -1,18 +1,18 @@ package main import ( + "github.com/diofeher/tflint-ruleset-opentofu/opentofu" + "github.com/diofeher/tflint-ruleset-opentofu/project" + "github.com/diofeher/tflint-ruleset-opentofu/rules" "github.com/terraform-linters/tflint-plugin-sdk/plugin" "github.com/terraform-linters/tflint-plugin-sdk/tflint" - "github.com/terraform-linters/tflint-ruleset-terraform/project" - "github.com/terraform-linters/tflint-ruleset-terraform/rules" - "github.com/terraform-linters/tflint-ruleset-terraform/terraform" ) func main() { plugin.Serve(&plugin.ServeOpts{ - RuleSet: &terraform.RuleSet{ + RuleSet: &opentofu.RuleSet{ BuiltinRuleSet: tflint.BuiltinRuleSet{ - Name: "terraform", + Name: "opentofu", Version: project.Version, }, PresetRules: rules.PresetRules, diff --git a/terraform/config.go b/opentofu/config.go similarity index 86% rename from terraform/config.go rename to opentofu/config.go index d4a23d6..24c957b 100644 --- a/terraform/config.go +++ b/opentofu/config.go @@ -1,4 +1,4 @@ -package terraform +package opentofu // Config is the configuration for the ruleset. type Config struct { diff --git a/opentofu/opentofu.go b/opentofu/opentofu.go new file mode 100644 index 0000000..1389d5d --- /dev/null +++ b/opentofu/opentofu.go @@ -0,0 +1,321 @@ +package opentofu + +import ( + "fmt" + + "github.com/hashicorp/go-version" + "github.com/hashicorp/hcl/v2" + "github.com/hashicorp/hcl/v2/gohcl" + "github.com/hashicorp/hcl/v2/hclsyntax" + hcljson "github.com/hashicorp/hcl/v2/json" + regaddr "github.com/opentofu/registry-address" + "github.com/terraform-linters/tflint-plugin-sdk/hclext" + "github.com/zclconf/go-cty/cty" +) + +// ModuleCall represents a "module" block. +type ModuleCall struct { + Name string + DefRange hcl.Range + Source string + SourceAttr *hclext.Attribute + Version version.Constraints + VersionAttr *hclext.Attribute +} + +// @see https://github.com/hashicorp/terraform/blob/v1.2.7/internal/configs/module_call.go#L36-L224 +func decodeModuleCall(block *hclext.Block) (*ModuleCall, hcl.Diagnostics) { + module := &ModuleCall{ + Name: block.Labels[0], + DefRange: block.DefRange, + } + diags := hcl.Diagnostics{} + + if source, exists := block.Body.Attributes["source"]; exists { + module.SourceAttr = source + sourceDiags := gohcl.DecodeExpression(source.Expr, nil, &module.Source) + diags = diags.Extend(sourceDiags) + } + + if versionAttr, exists := block.Body.Attributes["version"]; exists { + module.VersionAttr = versionAttr + + var versionVal string + versionDiags := gohcl.DecodeExpression(versionAttr.Expr, nil, &versionVal) + diags = diags.Extend(versionDiags) + if diags.HasErrors() { + return module, diags + } + + constraints, err := version.NewConstraint(versionVal) + if err != nil { + diags = append(diags, &hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid version constraint", + Detail: "This string does not use correct version constraint syntax.", + Subject: versionAttr.Expr.Range().Ptr(), + }) + } + module.Version = constraints + } + + return module, diags +} + +// Local represents a single entry from a "locals" block. +type Local struct { + Name string + Attribute *hcl.Attribute + DefRange hcl.Range +} + +// ProviderRef represents a reference to a provider like `provider = google.europe` in a resource or module. +type ProviderRef struct { + Name string + Alias string + AliasRange *hcl.Range + KeyExpression hcl.Expression + DefRange hcl.Range +} + +func ExprIsNativeQuotedString(expr hcl.Expression) bool { + _, ok := expr.(*hclsyntax.TemplateExpr) + return ok +} + +func IsProviderPartNormalized(str string) (bool, error) { + normalized, err := regaddr.ParseProviderPart(str) + if err != nil { + return false, err + } + if str == normalized { + return true, nil + } + return false, nil +} + +func checkProviderNameNormalized(name string, declrange hcl.Range) hcl.Diagnostics { + var diags hcl.Diagnostics + // verify that the provider local name is normalized + normalized, err := IsProviderPartNormalized(name) + if err != nil { + diags = append(diags, &hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid provider local name", + Detail: fmt.Sprintf("%s is an invalid provider local name: %s", name, err), + Subject: &declrange, + }) + return diags + } + if !normalized { + // we would have returned this error already + normalizedProvider, _ := regaddr.ParseProviderPart(name) + diags = append(diags, &hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid provider local name", + Detail: fmt.Sprintf("Provider names must be normalized. Replace %q with %q to fix this error.", name, normalizedProvider), + Subject: &declrange, + }) + } + return diags +} + +func ConvertJSONExpressionToHCL(expr hcl.Expression) (hcl.Expression, hcl.Diagnostics) { + var diags hcl.Diagnostics + // We can abuse the hcl json api and rely on the fact that calling + // Value on a json expression with no EvalContext will return the + // raw string. We can then parse that as normal hcl syntax, and + // continue with the decoding. + value, ds := expr.Value(nil) + diags = append(diags, ds...) + if diags.HasErrors() { + return nil, diags + } + + if value.Type() != cty.String || value.IsNull() { + diags = append(diags, &hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Expected string expression", + Detail: fmt.Sprintf("This value must be a string, but got %s.", value.Type().FriendlyName()), + Subject: expr.Range().Ptr(), + }) + return nil, diags + } + + expr, ds = hclsyntax.ParseExpression([]byte(value.AsString()), expr.Range().Filename, expr.Range().Start) + diags = append(diags, ds...) + if diags.HasErrors() { + return nil, diags + } + + return expr, diags +} + +// @see https://github.com/opentofu/opentofu/blob/3258c673194ecba26d856fb825d4eb4a7e36ab34/internal/configs/resource.go#L903 +func decodeProviderRef(expr hcl.Expression, defRange hcl.Range) (*ProviderRef, hcl.Diagnostics) { + var diags hcl.Diagnostics + var keyExpr hcl.Expression + const ( + // name.alias[const_key] + nameIndex = 0 + aliasIndex = 1 + keyIndex = 2 + ) + + var maxTraversalLength = keyIndex + 1 + + if ok := hcljson.IsJSONExpression(expr); ok { + expr, diags = ConvertJSONExpressionToHCL(expr) + if diags.HasErrors() { + return nil, diags + } + } + + // name.alias[expr_key] + if iex, ok := expr.(*hclsyntax.IndexExpr); ok { + maxTraversalLength = aliasIndex + 1 // expr key found, no const key allowed + + keyExpr = iex.Key + expr = iex.Collection + } + + var shimDiags hcl.Diagnostics + expr, shimDiags = shimTraversalInString(expr) + diags = append(diags, shimDiags...) + + traversal, travDiags := hcl.AbsTraversalForExpr(expr) + + // AbsTraversalForExpr produces only generic errors, so we'll discard + // the errors given and produce our own with extra context. If we didn't + // get any errors then we might still have warnings, though. + if !travDiags.HasErrors() { + diags = append(diags, travDiags...) + } + + if len(traversal) == 0 || len(traversal) > maxTraversalLength { + // A provider reference was given as a string literal in the legacy + // configuration language and there are lots of examples out there + // showing that usage, so we'll sniff for that situation here and + // produce a specialized error message for it to help users find + // the new correct form. + if ExprIsNativeQuotedString(expr) { + diags = append(diags, &hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid provider configuration reference", + Detail: "A provider configuration reference must not be given in quotes.", + Subject: expr.Range().Ptr(), + }) + return nil, diags + } + + diags = append(diags, &hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid provider configuration reference", + Detail: fmt.Sprintf("The provider argument requires a provider type name, optionally followed by a period and then a configuration alias and optional instance key."), + Subject: expr.Range().Ptr(), + }) + return nil, diags + } + + // verify that the provider local name is normalized + name := traversal.RootName() + nameDiags := checkProviderNameNormalized(name, traversal[nameIndex].SourceRange()) + diags = append(diags, nameDiags...) + if diags.HasErrors() { + return nil, diags + } + + ret := &ProviderRef{ + Name: traversal.RootName(), + DefRange: defRange, + KeyExpression: keyExpr, + AliasRange: nil, + } + + if len(traversal) > aliasIndex { + aliasStep, ok := traversal[aliasIndex].(hcl.TraverseAttr) + if !ok { + diags = append(diags, &hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid provider configuration reference", + Detail: "Provider name must either stand alone or be followed by a period and then a configuration alias.", + Subject: traversal[aliasIndex].SourceRange().Ptr(), + }) + return ret, diags + } + + ret.Alias = aliasStep.Name + ret.AliasRange = aliasStep.SourceRange().Ptr() + } + + if len(traversal) > keyIndex { + indexStep, ok := traversal[keyIndex].(hcl.TraverseIndex) + if !ok { + diags = append(diags, &hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid provider configuration reference", + Detail: "Provider name must either stand alone or be followed by a period and then a configuration alias.", + Subject: traversal[keyIndex].SourceRange().Ptr(), + }) + return ret, diags + } + + ret.KeyExpression = hcl.StaticExpr(indexStep.Key, traversal.SourceRange()) + } + + if len(ret.Alias) == 0 && ret.KeyExpression != nil { + diags = append(diags, &hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid provider configuration reference", + Detail: "Provider assignment requires an alias when specifying an instance key, in the form of provider.name[instance_key]", + Subject: traversal.SourceRange().Ptr(), + }) + } + + return ret, nil +} + +// @see https://github.com/hashicorp/terraform/blob/v1.2.5/internal/configs/compat_shim.go#L34 +func shimTraversalInString(expr hcl.Expression) (hcl.Expression, hcl.Diagnostics) { + // ObjectConsKeyExpr is a special wrapper type used for keys on object + // constructors to deal with the fact that naked identifiers are normally + // handled as "bareword" strings rather than as variable references. Since + // we know we're interpreting as a traversal anyway (and thus it won't + // matter whether it's a string or an identifier) we can safely just unwrap + // here and then process whatever we find inside as normal. + if ocke, ok := expr.(*hclsyntax.ObjectConsKeyExpr); ok { + expr = ocke.Wrapped + } + + if _, ok := expr.(*hclsyntax.TemplateExpr); !ok { + return expr, nil + } + + strVal, diags := expr.Value(nil) + if diags.HasErrors() || strVal.IsNull() || !strVal.IsKnown() { + // Since we're not even able to attempt a shim here, we'll discard + // the diagnostics we saw so far and let the caller's own error + // handling take care of reporting the invalid expression. + return expr, nil + } + + // The position handling here isn't _quite_ right because it won't + // take into account any escape sequences in the literal string, but + // it should be close enough for any error reporting to make sense. + srcRange := expr.Range() + startPos := srcRange.Start // copy + startPos.Column++ // skip initial quote + startPos.Byte++ // skip initial quote + + traversal, tDiags := hclsyntax.ParseTraversalAbs( + []byte(strVal.AsString()), + srcRange.Filename, + startPos, + ) + diags = append(diags, tDiags...) + + return &hclsyntax.ScopeTraversalExpr{ + Traversal: traversal, + SrcRange: srcRange, + }, diags +} diff --git a/terraform/ruleset.go b/opentofu/ruleset.go similarity index 99% rename from terraform/ruleset.go rename to opentofu/ruleset.go index 9b66d88..cedec40 100644 --- a/terraform/ruleset.go +++ b/opentofu/ruleset.go @@ -1,4 +1,4 @@ -package terraform +package opentofu import ( "fmt" diff --git a/terraform/ruleset_test.go b/opentofu/ruleset_test.go similarity index 99% rename from terraform/ruleset_test.go rename to opentofu/ruleset_test.go index 61d708b..8172943 100644 --- a/terraform/ruleset_test.go +++ b/opentofu/ruleset_test.go @@ -1,4 +1,4 @@ -package terraform +package opentofu import ( "testing" diff --git a/terraform/runner.go b/opentofu/runner.go similarity index 99% rename from terraform/runner.go rename to opentofu/runner.go index 11c61a4..e5778cd 100644 --- a/terraform/runner.go +++ b/opentofu/runner.go @@ -1,4 +1,4 @@ -package terraform +package opentofu import ( "strings" @@ -230,6 +230,7 @@ func (r *Runner) GetProviderRefs() (map[string]*ProviderRef, hcl.Diagnostics) { for _, data := range block.Body.Blocks { if attr, exists := data.Body.Attributes["provider"]; exists { ref, decodeDiags := decodeProviderRef(attr.Expr, data.DefRange) + diags = diags.Extend(decodeDiags) if decodeDiags.HasErrors() { continue diff --git a/terraform/runner_test.go b/opentofu/runner_test.go similarity index 99% rename from terraform/runner_test.go rename to opentofu/runner_test.go index 9e66e37..b1602d9 100644 --- a/terraform/runner_test.go +++ b/opentofu/runner_test.go @@ -1,4 +1,4 @@ -package terraform +package opentofu import ( "testing" diff --git a/rules/terraform_comment_syntax.go b/rules/opentofu_comment_syntax.go similarity index 65% rename from rules/terraform_comment_syntax.go rename to rules/opentofu_comment_syntax.go index eeb689f..6dfa94a 100644 --- a/rules/terraform_comment_syntax.go +++ b/rules/opentofu_comment_syntax.go @@ -3,44 +3,44 @@ package rules import ( "strings" + "github.com/diofeher/tflint-ruleset-opentofu/project" "github.com/hashicorp/hcl/v2" "github.com/hashicorp/hcl/v2/hclsyntax" "github.com/terraform-linters/tflint-plugin-sdk/tflint" - "github.com/terraform-linters/tflint-ruleset-terraform/project" ) -// TerraformCommentSyntaxRule checks whether comments use the preferred syntax -type TerraformCommentSyntaxRule struct { +// OpentofuCommentSyntaxRule checks whether comments use the preferred syntax +type OpentofuCommentSyntaxRule struct { tflint.DefaultRule } -// NewTerraformCommentSyntaxRule returns a new rule -func NewTerraformCommentSyntaxRule() *TerraformCommentSyntaxRule { - return &TerraformCommentSyntaxRule{} +// NewOpentofuCommentSyntaxRule returns a new rule +func NewOpentofuCommentSyntaxRule() *OpentofuCommentSyntaxRule { + return &OpentofuCommentSyntaxRule{} } // Name returns the rule name -func (r *TerraformCommentSyntaxRule) Name() string { - return "terraform_comment_syntax" +func (r *OpentofuCommentSyntaxRule) Name() string { + return "opentofu_comment_syntax" } // Enabled returns whether the rule is enabled by default -func (r *TerraformCommentSyntaxRule) Enabled() bool { +func (r *OpentofuCommentSyntaxRule) Enabled() bool { return true } // Severity returns the rule severity -func (r *TerraformCommentSyntaxRule) Severity() tflint.Severity { +func (r *OpentofuCommentSyntaxRule) Severity() tflint.Severity { return tflint.WARNING } // Link returns the rule reference link -func (r *TerraformCommentSyntaxRule) Link() string { +func (r *OpentofuCommentSyntaxRule) Link() string { return project.ReferenceLink(r.Name()) } // Check checks whether single line comments is used -func (r *TerraformCommentSyntaxRule) Check(runner tflint.Runner) error { +func (r *OpentofuCommentSyntaxRule) Check(runner tflint.Runner) error { path, err := runner.GetModulePath() if err != nil { return err @@ -63,7 +63,7 @@ func (r *TerraformCommentSyntaxRule) Check(runner tflint.Runner) error { return nil } -func (r *TerraformCommentSyntaxRule) checkComments(runner tflint.Runner, filename string, file *hcl.File) error { +func (r *OpentofuCommentSyntaxRule) checkComments(runner tflint.Runner, filename string, file *hcl.File) error { if strings.HasSuffix(filename, ".json") { return nil } diff --git a/rules/terraform_comment_syntax_test.go b/rules/opentofu_comment_syntax_test.go similarity index 92% rename from rules/terraform_comment_syntax_test.go rename to rules/opentofu_comment_syntax_test.go index ded48ea..ae03592 100644 --- a/rules/terraform_comment_syntax_test.go +++ b/rules/opentofu_comment_syntax_test.go @@ -7,7 +7,7 @@ import ( "github.com/terraform-linters/tflint-plugin-sdk/helper" ) -func Test_TerraformCommentSyntaxRule(t *testing.T) { +func Test_OpentofuCommentSyntaxRule(t *testing.T) { cases := []struct { Name string Content string @@ -34,7 +34,7 @@ func Test_TerraformCommentSyntaxRule(t *testing.T) { Content: `// foo`, Expected: helper.Issues{ { - Rule: NewTerraformCommentSyntaxRule(), + Rule: NewOpentofuCommentSyntaxRule(), Message: "Single line comments should begin with #", Range: hcl.Range{ Filename: "variables.tf", @@ -68,7 +68,7 @@ variable "foo" { }, } - rule := NewTerraformCommentSyntaxRule() + rule := NewOpentofuCommentSyntaxRule() for _, tc := range cases { t.Run(tc.Name, func(t *testing.T) { diff --git a/rules/terraform_deprecated_index.go b/rules/opentofu_deprecated_index.go similarity index 73% rename from rules/terraform_deprecated_index.go rename to rules/opentofu_deprecated_index.go index c6996a7..ef8059a 100644 --- a/rules/terraform_deprecated_index.go +++ b/rules/opentofu_deprecated_index.go @@ -3,45 +3,45 @@ package rules import ( "strings" + "github.com/diofeher/tflint-ruleset-opentofu/project" "github.com/hashicorp/hcl/v2" "github.com/hashicorp/hcl/v2/hclsyntax" "github.com/hashicorp/hcl/v2/json" "github.com/terraform-linters/tflint-plugin-sdk/tflint" - "github.com/terraform-linters/tflint-ruleset-terraform/project" ) -// TerraformDeprecatedIndexRule warns about usage of the legacy dot syntax for indexes (foo.0) -type TerraformDeprecatedIndexRule struct { +// OpentofuDeprecatedIndexRule warns about usage of the legacy dot syntax for indexes (foo.0) +type OpentofuDeprecatedIndexRule struct { tflint.DefaultRule } -// NewTerraformDeprecatedIndexRule return a new rule -func NewTerraformDeprecatedIndexRule() *TerraformDeprecatedIndexRule { - return &TerraformDeprecatedIndexRule{} +// NewOpentofuDeprecatedIndexRule return a new rule +func NewOpentofuDeprecatedIndexRule() *OpentofuDeprecatedIndexRule { + return &OpentofuDeprecatedIndexRule{} } // Name returns the rule name -func (r *TerraformDeprecatedIndexRule) Name() string { - return "terraform_deprecated_index" +func (r *OpentofuDeprecatedIndexRule) Name() string { + return "opentofu_deprecated_index" } // Enabled returns whether the rule is enabled by default -func (r *TerraformDeprecatedIndexRule) Enabled() bool { +func (r *OpentofuDeprecatedIndexRule) Enabled() bool { return true } // Severity returns the rule severity -func (r *TerraformDeprecatedIndexRule) Severity() tflint.Severity { +func (r *OpentofuDeprecatedIndexRule) Severity() tflint.Severity { return tflint.WARNING } // Link returns the rule reference link -func (r *TerraformDeprecatedIndexRule) Link() string { +func (r *OpentofuDeprecatedIndexRule) Link() string { return project.ReferenceLink(r.Name()) } // Check walks all expressions and emit issues if deprecated index syntax is found -func (r *TerraformDeprecatedIndexRule) Check(runner tflint.Runner) error { +func (r *OpentofuDeprecatedIndexRule) Check(runner tflint.Runner) error { path, err := runner.GetModulePath() if err != nil { return err @@ -99,7 +99,7 @@ func (r *TerraformDeprecatedIndexRule) Check(runner tflint.Runner) error { return nil } -func (r *TerraformDeprecatedIndexRule) checkLegacyTraversalIndex(runner tflint.Runner, traversal hcl.Traversal, file []byte) hcl.Diagnostics { +func (r *OpentofuDeprecatedIndexRule) checkLegacyTraversalIndex(runner tflint.Runner, traversal hcl.Traversal, file []byte) hcl.Diagnostics { for _, t := range traversal { if tn, ok := t.(hcl.TraverseIndex); ok { if strings.HasPrefix(string(t.SourceRange().SliceBytes(file)), ".") { @@ -125,7 +125,7 @@ func (r *TerraformDeprecatedIndexRule) checkLegacyTraversalIndex(runner tflint.R return nil } -func (r *TerraformDeprecatedIndexRule) checkJSONExpression(runner tflint.Runner, e hcl.Expression, file []byte) hcl.Diagnostics { +func (r *OpentofuDeprecatedIndexRule) checkJSONExpression(runner tflint.Runner, e hcl.Expression, file []byte) hcl.Diagnostics { var diags hcl.Diagnostics for _, v := range e.Variables() { diff --git a/rules/terraform_deprecated_index_test.go b/rules/opentofu_deprecated_index_test.go similarity index 92% rename from rules/terraform_deprecated_index_test.go rename to rules/opentofu_deprecated_index_test.go index 6765f3e..d067203 100644 --- a/rules/terraform_deprecated_index_test.go +++ b/rules/opentofu_deprecated_index_test.go @@ -7,7 +7,7 @@ import ( "github.com/terraform-linters/tflint-plugin-sdk/helper" ) -func Test_TerraformDeprecatedIndexRule(t *testing.T) { +func Test_OpentofuDeprecatedIndexRule(t *testing.T) { cases := []struct { Name string Content string @@ -25,7 +25,7 @@ locals { `, Expected: helper.Issues{ { - Rule: NewTerraformDeprecatedIndexRule(), + Rule: NewOpentofuDeprecatedIndexRule(), Message: "List items should be accessed using square brackets", Range: hcl.Range{ Filename: "config.tf", @@ -57,7 +57,7 @@ locals { `, Expected: helper.Issues{ { - Rule: NewTerraformDeprecatedIndexRule(), + Rule: NewOpentofuDeprecatedIndexRule(), Message: "List items should be accessed using square brackets", Range: hcl.Range{ Filename: "config.tf", @@ -124,7 +124,7 @@ EOF `, Expected: helper.Issues{ { - Rule: NewTerraformDeprecatedIndexRule(), + Rule: NewOpentofuDeprecatedIndexRule(), Message: "List items should be accessed using square brackets", Range: hcl.Range{ Filename: "config.tf", @@ -159,7 +159,7 @@ locals { `, Expected: helper.Issues{ { - Rule: NewTerraformDeprecatedIndexRule(), + Rule: NewOpentofuDeprecatedIndexRule(), Message: "List items should be accessed using square brackets", Range: hcl.Range{ Filename: "config.tf", @@ -174,7 +174,7 @@ locals { }, }, { - Rule: NewTerraformDeprecatedIndexRule(), + Rule: NewOpentofuDeprecatedIndexRule(), Message: "List items should be accessed using square brackets", Range: hcl.Range{ Filename: "config.tf", @@ -206,7 +206,7 @@ locals { `, Expected: helper.Issues{ { - Rule: NewTerraformDeprecatedIndexRule(), + Rule: NewOpentofuDeprecatedIndexRule(), Message: "List items should be accessed using square brackets", Range: hcl.Range{ Filename: "config.tf", @@ -240,7 +240,7 @@ locals { }`, Expected: helper.Issues{ { - Rule: NewTerraformDeprecatedIndexRule(), + Rule: NewOpentofuDeprecatedIndexRule(), Message: "List items should be accessed using square brackets", Range: hcl.Range{ Filename: "config.tf.json", @@ -289,7 +289,7 @@ locals { }, } - rule := NewTerraformDeprecatedIndexRule() + rule := NewOpentofuDeprecatedIndexRule() for _, tc := range cases { t.Run(tc.Name, func(t *testing.T) { diff --git a/rules/terraform_deprecated_interpolation.go b/rules/opentofu_deprecated_interpolation.go similarity index 80% rename from rules/terraform_deprecated_interpolation.go rename to rules/opentofu_deprecated_interpolation.go index 14a3d65..bec9cab 100644 --- a/rules/terraform_deprecated_interpolation.go +++ b/rules/opentofu_deprecated_interpolation.go @@ -1,46 +1,46 @@ package rules import ( + "github.com/diofeher/tflint-ruleset-opentofu/project" "github.com/hashicorp/hcl/v2" "github.com/hashicorp/hcl/v2/hclsyntax" "github.com/terraform-linters/tflint-plugin-sdk/tflint" - "github.com/terraform-linters/tflint-ruleset-terraform/project" ) -// TerraformDeprecatedInterpolationRule warns of deprecated interpolation in Terraform v0.11 or earlier. -type TerraformDeprecatedInterpolationRule struct { +// OpentofuDeprecatedInterpolationRule warns of deprecated interpolation in Opentofu v0.11 or earlier. +type OpentofuDeprecatedInterpolationRule struct { tflint.DefaultRule } -// NewTerraformDeprecatedInterpolationRule return a new rule -func NewTerraformDeprecatedInterpolationRule() *TerraformDeprecatedInterpolationRule { - return &TerraformDeprecatedInterpolationRule{} +// NewOpentofuDeprecatedInterpolationRule return a new rule +func NewOpentofuDeprecatedInterpolationRule() *OpentofuDeprecatedInterpolationRule { + return &OpentofuDeprecatedInterpolationRule{} } // Name returns the rule name -func (r *TerraformDeprecatedInterpolationRule) Name() string { - return "terraform_deprecated_interpolation" +func (r *OpentofuDeprecatedInterpolationRule) Name() string { + return "opentofu_deprecated_interpolation" } // Enabled returns whether the rule is enabled by default -func (r *TerraformDeprecatedInterpolationRule) Enabled() bool { +func (r *OpentofuDeprecatedInterpolationRule) Enabled() bool { return true } // Severity returns the rule severity -func (r *TerraformDeprecatedInterpolationRule) Severity() tflint.Severity { +func (r *OpentofuDeprecatedInterpolationRule) Severity() tflint.Severity { return tflint.WARNING } // Link returns the rule reference link -func (r *TerraformDeprecatedInterpolationRule) Link() string { +func (r *OpentofuDeprecatedInterpolationRule) Link() string { return project.ReferenceLink(r.Name()) } // Check emits issues on the deprecated interpolation syntax. -// This logic is equivalent to the warning logic implemented in Terraform. +// This logic is equivalent to the warning logic implemented in Opentofu. // See https://github.com/hashicorp/terraform/blob/2ce03abe480c3f40d04bd0f289762721ea280848/configs/compat_shim.go#L144-L156 -func (r *TerraformDeprecatedInterpolationRule) Check(runner tflint.Runner) error { +func (r *OpentofuDeprecatedInterpolationRule) Check(runner tflint.Runner) error { path, err := runner.GetModulePath() if err != nil { return err @@ -65,7 +65,7 @@ func (r *TerraformDeprecatedInterpolationRule) Check(runner tflint.Runner) error type terraformDeprecatedInterpolationWalker struct { runner tflint.Runner - rule *TerraformDeprecatedInterpolationRule + rule *OpentofuDeprecatedInterpolationRule contextStack []terraformDeprecatedInterpolationContext } @@ -91,7 +91,7 @@ func (w *terraformDeprecatedInterpolationWalker) Enter(expr hcl.Expression) hcl. // so we don't need to do anything further to distinguish that // situation. ("normal" templates are *hclsyntax.TemplateExpr.) - const message = "Interpolation-only expressions are deprecated in Terraform v0.12.14" + const message = "Interpolation-only expressions are deprecated in Opentofu v0.12.14" switch w.currentContext() { case terraformDeprecatedInterpolationContextObjKey: // This case requires a different autofix strategy is needed diff --git a/rules/terraform_deprecated_interpolation_test.go b/rules/opentofu_deprecated_interpolation_test.go similarity index 86% rename from rules/terraform_deprecated_interpolation_test.go rename to rules/opentofu_deprecated_interpolation_test.go index 08e8cd3..520283d 100644 --- a/rules/terraform_deprecated_interpolation_test.go +++ b/rules/opentofu_deprecated_interpolation_test.go @@ -7,7 +7,7 @@ import ( "github.com/terraform-linters/tflint-plugin-sdk/helper" ) -func Test_TerraformDeprecatedInterpolationRule(t *testing.T) { +func Test_OpentofuDeprecatedInterpolationRule(t *testing.T) { cases := []struct { Name string Content string @@ -22,8 +22,8 @@ resource "null_resource" "a" { }`, Expected: helper.Issues{ { - Rule: NewTerraformDeprecatedInterpolationRule(), - Message: "Interpolation-only expressions are deprecated in Terraform v0.12.14", + Rule: NewOpentofuDeprecatedInterpolationRule(), + Message: "Interpolation-only expressions are deprecated in Opentofu v0.12.14", Range: hcl.Range{ Filename: "config.tf", Start: hcl.Pos{Line: 3, Column: 14}, @@ -44,8 +44,8 @@ provider "null" { }`, Expected: helper.Issues{ { - Rule: NewTerraformDeprecatedInterpolationRule(), - Message: "Interpolation-only expressions are deprecated in Terraform v0.12.14", + Rule: NewOpentofuDeprecatedInterpolationRule(), + Message: "Interpolation-only expressions are deprecated in Opentofu v0.12.14", Range: hcl.Range{ Filename: "config.tf", Start: hcl.Pos{Line: 3, Column: 9}, @@ -66,8 +66,8 @@ locals { }`, Expected: helper.Issues{ { - Rule: NewTerraformDeprecatedInterpolationRule(), - Message: "Interpolation-only expressions are deprecated in Terraform v0.12.14", + Rule: NewOpentofuDeprecatedInterpolationRule(), + Message: "Interpolation-only expressions are deprecated in Opentofu v0.12.14", Range: hcl.Range{ Filename: "config.tf", Start: hcl.Pos{Line: 3, Column: 9}, @@ -90,8 +90,8 @@ resource "null_resource" "a" { }`, Expected: helper.Issues{ { - Rule: NewTerraformDeprecatedInterpolationRule(), - Message: "Interpolation-only expressions are deprecated in Terraform v0.12.14", + Rule: NewOpentofuDeprecatedInterpolationRule(), + Message: "Interpolation-only expressions are deprecated in Opentofu v0.12.14", Range: hcl.Range{ Filename: "config.tf", Start: hcl.Pos{Line: 4, Column: 14}, @@ -122,8 +122,8 @@ resource "null_resource" "a" { }`, Expected: helper.Issues{ { - Rule: NewTerraformDeprecatedInterpolationRule(), - Message: "Interpolation-only expressions are deprecated in Terraform v0.12.14", + Rule: NewOpentofuDeprecatedInterpolationRule(), + Message: "Interpolation-only expressions are deprecated in Opentofu v0.12.14", Range: hcl.Range{ Filename: "config.tf", Start: hcl.Pos{Line: 3, Column: 15}, @@ -152,8 +152,8 @@ resource "null_resource" "a" { }`, Expected: helper.Issues{ { - Rule: NewTerraformDeprecatedInterpolationRule(), - Message: "Interpolation-only expressions are deprecated in Terraform v0.12.14", + Rule: NewOpentofuDeprecatedInterpolationRule(), + Message: "Interpolation-only expressions are deprecated in Opentofu v0.12.14", Range: hcl.Range{ Filename: "config.tf", Start: hcl.Pos{Line: 3, Column: 14}, @@ -161,8 +161,8 @@ resource "null_resource" "a" { }, }, { - Rule: NewTerraformDeprecatedInterpolationRule(), - Message: "Interpolation-only expressions are deprecated in Terraform v0.12.14", + Rule: NewOpentofuDeprecatedInterpolationRule(), + Message: "Interpolation-only expressions are deprecated in Opentofu v0.12.14", Range: hcl.Range{ Filename: "config.tf", Start: hcl.Pos{Line: 3, Column: 17}, @@ -185,8 +185,8 @@ resource "null_resource" "a" { }`, Expected: helper.Issues{ { - Rule: NewTerraformDeprecatedInterpolationRule(), - Message: "Interpolation-only expressions are deprecated in Terraform v0.12.14", + Rule: NewOpentofuDeprecatedInterpolationRule(), + Message: "Interpolation-only expressions are deprecated in Opentofu v0.12.14", Range: hcl.Range{ Filename: "config.tf", Start: hcl.Pos{Line: 4, Column: 5}, @@ -211,8 +211,8 @@ resource "null_resource" "a" { }`, Expected: helper.Issues{ { - Rule: NewTerraformDeprecatedInterpolationRule(), - Message: "Interpolation-only expressions are deprecated in Terraform v0.12.14", + Rule: NewOpentofuDeprecatedInterpolationRule(), + Message: "Interpolation-only expressions are deprecated in Opentofu v0.12.14", Range: hcl.Range{ Filename: "config.tf", Start: hcl.Pos{Line: 4, Column: 11}, @@ -229,7 +229,7 @@ resource "null_resource" "a" { }, } - rule := NewTerraformDeprecatedInterpolationRule() + rule := NewOpentofuDeprecatedInterpolationRule() for _, tc := range cases { t.Run(tc.Name, func(t *testing.T) { diff --git a/rules/terraform_deprecated_lookup.go b/rules/opentofu_deprecated_lookup.go similarity index 66% rename from rules/terraform_deprecated_lookup.go rename to rules/opentofu_deprecated_lookup.go index 0864810..058ab36 100644 --- a/rules/terraform_deprecated_lookup.go +++ b/rules/opentofu_deprecated_lookup.go @@ -1,44 +1,44 @@ package rules import ( + "github.com/diofeher/tflint-ruleset-opentofu/project" "github.com/hashicorp/hcl/v2" "github.com/hashicorp/hcl/v2/hclsyntax" "github.com/terraform-linters/tflint-plugin-sdk/tflint" - "github.com/terraform-linters/tflint-ruleset-terraform/project" ) -// TerraformDeprecatedLookupRule warns about usage of the legacy dot syntax for indexes (foo.0) -type TerraformDeprecatedLookupRule struct { +// OpentofuDeprecatedLookupRule warns about usage of the legacy dot syntax for indexes (foo.0) +type OpentofuDeprecatedLookupRule struct { tflint.DefaultRule } -// NewTerraformDeprecatedIndexRule return a new rule -func NewTerraformDeprecatedLookupRule() *TerraformDeprecatedLookupRule { - return &TerraformDeprecatedLookupRule{} +// NewOpentofuDeprecatedIndexRule return a new rule +func NewOpentofuDeprecatedLookupRule() *OpentofuDeprecatedLookupRule { + return &OpentofuDeprecatedLookupRule{} } // Name returns the rule name -func (r *TerraformDeprecatedLookupRule) Name() string { - return "terraform_deprecated_lookup" +func (r *OpentofuDeprecatedLookupRule) Name() string { + return "opentofu_deprecated_lookup" } // Enabled returns whether the rule is enabled by default -func (r *TerraformDeprecatedLookupRule) Enabled() bool { +func (r *OpentofuDeprecatedLookupRule) Enabled() bool { return true } // Severity returns the rule severity -func (r *TerraformDeprecatedLookupRule) Severity() tflint.Severity { +func (r *OpentofuDeprecatedLookupRule) Severity() tflint.Severity { return tflint.WARNING } // Link returns the rule reference link -func (r *TerraformDeprecatedLookupRule) Link() string { +func (r *OpentofuDeprecatedLookupRule) Link() string { return project.ReferenceLink(r.Name()) } // Check walks all expressions and emit issues if deprecated index syntax is found -func (r *TerraformDeprecatedLookupRule) Check(runner tflint.Runner) error { +func (r *OpentofuDeprecatedLookupRule) Check(runner tflint.Runner) error { path, err := runner.GetModulePath() if err != nil { return err diff --git a/rules/terraform_deprecated_lookup_test.go b/rules/opentofu_deprecated_lookup_test.go similarity index 88% rename from rules/terraform_deprecated_lookup_test.go rename to rules/opentofu_deprecated_lookup_test.go index 23e26da..9c63a08 100644 --- a/rules/terraform_deprecated_lookup_test.go +++ b/rules/opentofu_deprecated_lookup_test.go @@ -7,7 +7,7 @@ import ( "github.com/terraform-linters/tflint-plugin-sdk/helper" ) -func Test_TerraformDeprecatedLookupRule(t *testing.T) { +func Test_OpentofuDeprecatedLookupRule(t *testing.T) { cases := []struct { Name string Content string @@ -24,7 +24,7 @@ locals { `, Expected: helper.Issues{ { - Rule: NewTerraformDeprecatedLookupRule(), + Rule: NewOpentofuDeprecatedLookupRule(), Message: "Lookup with 2 arguments is deprecated", Range: hcl.Range{ Filename: "config.tf", @@ -56,7 +56,7 @@ locals { `, Expected: helper.Issues{ { - Rule: NewTerraformDeprecatedLookupRule(), + Rule: NewOpentofuDeprecatedLookupRule(), Message: "Lookup with 2 arguments is deprecated", Range: hcl.Range{ Filename: "config.tf", @@ -71,7 +71,7 @@ locals { }, }, { - Rule: NewTerraformDeprecatedLookupRule(), + Rule: NewOpentofuDeprecatedLookupRule(), Message: "Lookup with 2 arguments is deprecated", Range: hcl.Range{ Filename: "config.tf", @@ -95,7 +95,7 @@ locals { }, } - rule := NewTerraformDeprecatedLookupRule() + rule := NewOpentofuDeprecatedLookupRule() for _, tc := range cases { t.Run(tc.Name, func(t *testing.T) { diff --git a/rules/terraform_documented_outputs.go b/rules/opentofu_documented_outputs.go similarity index 70% rename from rules/terraform_documented_outputs.go rename to rules/opentofu_documented_outputs.go index c5521e4..f09f6c6 100644 --- a/rules/terraform_documented_outputs.go +++ b/rules/opentofu_documented_outputs.go @@ -3,44 +3,44 @@ package rules import ( "fmt" + "github.com/diofeher/tflint-ruleset-opentofu/project" "github.com/hashicorp/hcl/v2/gohcl" "github.com/terraform-linters/tflint-plugin-sdk/hclext" "github.com/terraform-linters/tflint-plugin-sdk/tflint" - "github.com/terraform-linters/tflint-ruleset-terraform/project" ) -// TerraformDocumentedOutputsRule checks whether outputs have descriptions -type TerraformDocumentedOutputsRule struct { +// OpentofuDocumentedOutputsRule checks whether outputs have descriptions +type OpentofuDocumentedOutputsRule struct { tflint.DefaultRule } -// NewTerraformDocumentedOutputsRule returns a new rule -func NewTerraformDocumentedOutputsRule() *TerraformDocumentedOutputsRule { - return &TerraformDocumentedOutputsRule{} +// NewOpentofuDocumentedOutputsRule returns a new rule +func NewOpentofuDocumentedOutputsRule() *OpentofuDocumentedOutputsRule { + return &OpentofuDocumentedOutputsRule{} } // Name returns the rule name -func (r *TerraformDocumentedOutputsRule) Name() string { - return "terraform_documented_outputs" +func (r *OpentofuDocumentedOutputsRule) Name() string { + return "opentofu_documented_outputs" } // Enabled returns whether the rule is enabled by default -func (r *TerraformDocumentedOutputsRule) Enabled() bool { +func (r *OpentofuDocumentedOutputsRule) Enabled() bool { return true } // Severity returns the rule severity -func (r *TerraformDocumentedOutputsRule) Severity() tflint.Severity { +func (r *OpentofuDocumentedOutputsRule) Severity() tflint.Severity { return tflint.NOTICE } // Link returns the rule reference link -func (r *TerraformDocumentedOutputsRule) Link() string { +func (r *OpentofuDocumentedOutputsRule) Link() string { return project.ReferenceLink(r.Name()) } // Check checks whether outputs have descriptions -func (r *TerraformDocumentedOutputsRule) Check(runner tflint.Runner) error { +func (r *OpentofuDocumentedOutputsRule) Check(runner tflint.Runner) error { path, err := runner.GetModulePath() if err != nil { return err diff --git a/rules/terraform_documented_outputs_test.go b/rules/opentofu_documented_outputs_test.go similarity index 87% rename from rules/terraform_documented_outputs_test.go rename to rules/opentofu_documented_outputs_test.go index b336a49..545097f 100644 --- a/rules/terraform_documented_outputs_test.go +++ b/rules/opentofu_documented_outputs_test.go @@ -7,7 +7,7 @@ import ( "github.com/terraform-linters/tflint-plugin-sdk/helper" ) -func Test_TerraformDocumentedOutputsRule(t *testing.T) { +func Test_OpentofuDocumentedOutputsRule(t *testing.T) { cases := []struct { Name string Content string @@ -21,7 +21,7 @@ output "endpoint" { }`, Expected: helper.Issues{ { - Rule: NewTerraformDocumentedOutputsRule(), + Rule: NewOpentofuDocumentedOutputsRule(), Message: "`endpoint` output has no description", Range: hcl.Range{ Filename: "outputs.tf", @@ -40,7 +40,7 @@ output "endpoint" { }`, Expected: helper.Issues{ { - Rule: NewTerraformDocumentedOutputsRule(), + Rule: NewOpentofuDocumentedOutputsRule(), Message: "`endpoint` output has no description", Range: hcl.Range{ Filename: "outputs.tf", @@ -61,7 +61,7 @@ output "endpoint" { }, } - rule := NewTerraformDocumentedOutputsRule() + rule := NewOpentofuDocumentedOutputsRule() for _, tc := range cases { t.Run(tc.Name, func(t *testing.T) { diff --git a/rules/terraform_documented_variables.go b/rules/opentofu_documented_variables.go similarity index 69% rename from rules/terraform_documented_variables.go rename to rules/opentofu_documented_variables.go index 95c7c3f..e213523 100644 --- a/rules/terraform_documented_variables.go +++ b/rules/opentofu_documented_variables.go @@ -3,44 +3,44 @@ package rules import ( "fmt" + "github.com/diofeher/tflint-ruleset-opentofu/project" "github.com/hashicorp/hcl/v2/gohcl" "github.com/terraform-linters/tflint-plugin-sdk/hclext" "github.com/terraform-linters/tflint-plugin-sdk/tflint" - "github.com/terraform-linters/tflint-ruleset-terraform/project" ) -// TerraformDocumentedVariablesRule checks whether variables have descriptions -type TerraformDocumentedVariablesRule struct { +// OpentofuDocumentedVariablesRule checks whether variables have descriptions +type OpentofuDocumentedVariablesRule struct { tflint.DefaultRule } -// NewTerraformDocumentedVariablesRule returns a new rule -func NewTerraformDocumentedVariablesRule() *TerraformDocumentedVariablesRule { - return &TerraformDocumentedVariablesRule{} +// NewOpentofuDocumentedVariablesRule returns a new rule +func NewOpentofuDocumentedVariablesRule() *OpentofuDocumentedVariablesRule { + return &OpentofuDocumentedVariablesRule{} } // Name returns the rule name -func (r *TerraformDocumentedVariablesRule) Name() string { - return "terraform_documented_variables" +func (r *OpentofuDocumentedVariablesRule) Name() string { + return "opentofu_documented_variables" } // Enabled returns whether the rule is enabled by default -func (r *TerraformDocumentedVariablesRule) Enabled() bool { +func (r *OpentofuDocumentedVariablesRule) Enabled() bool { return true } // Severity returns the rule severity -func (r *TerraformDocumentedVariablesRule) Severity() tflint.Severity { +func (r *OpentofuDocumentedVariablesRule) Severity() tflint.Severity { return tflint.NOTICE } // Link returns the rule reference link -func (r *TerraformDocumentedVariablesRule) Link() string { +func (r *OpentofuDocumentedVariablesRule) Link() string { return project.ReferenceLink(r.Name()) } // Check checks whether variables have descriptions -func (r *TerraformDocumentedVariablesRule) Check(runner tflint.Runner) error { +func (r *OpentofuDocumentedVariablesRule) Check(runner tflint.Runner) error { path, err := runner.GetModulePath() if err != nil { return err diff --git a/rules/terraform_documented_variables_test.go b/rules/opentofu_documented_variables_test.go similarity index 87% rename from rules/terraform_documented_variables_test.go rename to rules/opentofu_documented_variables_test.go index 7ee5aa7..55bdc25 100644 --- a/rules/terraform_documented_variables_test.go +++ b/rules/opentofu_documented_variables_test.go @@ -7,7 +7,7 @@ import ( "github.com/terraform-linters/tflint-plugin-sdk/helper" ) -func Test_TerraformDocumentedVariablesRule(t *testing.T) { +func Test_OpentofuDocumentedVariablesRule(t *testing.T) { cases := []struct { Name string Content string @@ -21,7 +21,7 @@ variable "no_description" { }`, Expected: helper.Issues{ { - Rule: NewTerraformDocumentedVariablesRule(), + Rule: NewOpentofuDocumentedVariablesRule(), Message: "`no_description` variable has no description", Range: hcl.Range{ Filename: "variables.tf", @@ -39,7 +39,7 @@ variable "empty_description" { }`, Expected: helper.Issues{ { - Rule: NewTerraformDocumentedVariablesRule(), + Rule: NewOpentofuDocumentedVariablesRule(), Message: "`empty_description` variable has no description", Range: hcl.Range{ Filename: "variables.tf", @@ -59,7 +59,7 @@ variable "with_description" { }, } - rule := NewTerraformDocumentedVariablesRule() + rule := NewOpentofuDocumentedVariablesRule() for _, tc := range cases { t.Run(tc.Name, func(t *testing.T) { diff --git a/rules/terraform_empty_list_equality.go b/rules/opentofu_empty_list_equality.go similarity index 71% rename from rules/terraform_empty_list_equality.go rename to rules/opentofu_empty_list_equality.go index 0d37c71..3505324 100644 --- a/rules/terraform_empty_list_equality.go +++ b/rules/opentofu_empty_list_equality.go @@ -1,44 +1,44 @@ package rules import ( + "github.com/diofeher/tflint-ruleset-opentofu/project" "github.com/hashicorp/hcl/v2" "github.com/hashicorp/hcl/v2/hclsyntax" "github.com/terraform-linters/tflint-plugin-sdk/tflint" - "github.com/terraform-linters/tflint-ruleset-terraform/project" ) -// TerraformEmptyListEqualityRule checks whether is there a comparison with an empty list -type TerraformEmptyListEqualityRule struct { +// OpentofuEmptyListEqualityRule checks whether is there a comparison with an empty list +type OpentofuEmptyListEqualityRule struct { tflint.DefaultRule } -// NewTerraformCommentSyntaxRule returns a new rule -func NewTerraformEmptyListEqualityRule() *TerraformEmptyListEqualityRule { - return &TerraformEmptyListEqualityRule{} +// NewOpentofuCommentSyntaxRule returns a new rule +func NewOpentofuEmptyListEqualityRule() *OpentofuEmptyListEqualityRule { + return &OpentofuEmptyListEqualityRule{} } // Name returns the rule name -func (r *TerraformEmptyListEqualityRule) Name() string { - return "terraform_empty_list_equality" +func (r *OpentofuEmptyListEqualityRule) Name() string { + return "opentofu_empty_list_equality" } // Enabled returns whether the rule is enabled by default -func (r *TerraformEmptyListEqualityRule) Enabled() bool { +func (r *OpentofuEmptyListEqualityRule) Enabled() bool { return true } // Severity returns the rule severity -func (r *TerraformEmptyListEqualityRule) Severity() tflint.Severity { +func (r *OpentofuEmptyListEqualityRule) Severity() tflint.Severity { return tflint.WARNING } // Link returns the rule reference link -func (r *TerraformEmptyListEqualityRule) Link() string { +func (r *OpentofuEmptyListEqualityRule) Link() string { return project.ReferenceLink(r.Name()) } // Check checks whether the list is being compared with static empty list -func (r *TerraformEmptyListEqualityRule) Check(runner tflint.Runner) error { +func (r *OpentofuEmptyListEqualityRule) Check(runner tflint.Runner) error { path, err := runner.GetModulePath() if err != nil { return err @@ -56,7 +56,7 @@ func (r *TerraformEmptyListEqualityRule) Check(runner tflint.Runner) error { } // checkEmptyList visits all blocks that can contain expressions and checks for comparisons with static empty list -func (r *TerraformEmptyListEqualityRule) checkEmptyList(runner tflint.Runner) hcl.Diagnostics { +func (r *OpentofuEmptyListEqualityRule) checkEmptyList(runner tflint.Runner) hcl.Diagnostics { return runner.WalkExpressions(tflint.ExprWalkFunc(func(expr hcl.Expression) hcl.Diagnostics { if binaryOpExpr, ok := expr.(*hclsyntax.BinaryOpExpr); ok && (binaryOpExpr.Op == hclsyntax.OpEqual || binaryOpExpr.Op == hclsyntax.OpNotEqual) { if tupleConsExpr, ok := binaryOpExpr.LHS.(*hclsyntax.TupleConsExpr); ok && len(tupleConsExpr.Exprs) == 0 { @@ -86,7 +86,7 @@ func (r *TerraformEmptyListEqualityRule) checkEmptyList(runner tflint.Runner) hc } // emitIssue emits issue for comparison with static empty list -func (r *TerraformEmptyListEqualityRule) emitIssue(binaryOpExpr *hclsyntax.BinaryOpExpr, hs hcl.Expression, runner tflint.Runner) error { +func (r *OpentofuEmptyListEqualityRule) emitIssue(binaryOpExpr *hclsyntax.BinaryOpExpr, hs hcl.Expression, runner tflint.Runner) error { var opStr string if binaryOpExpr.Op == hclsyntax.OpEqual { opStr = "==" diff --git a/rules/terraform_empty_list_equality_test.go b/rules/opentofu_empty_list_equality_test.go similarity index 91% rename from rules/terraform_empty_list_equality_test.go rename to rules/opentofu_empty_list_equality_test.go index 7aa6942..c02d07b 100644 --- a/rules/terraform_empty_list_equality_test.go +++ b/rules/opentofu_empty_list_equality_test.go @@ -7,7 +7,7 @@ import ( "github.com/terraform-linters/tflint-plugin-sdk/helper" ) -func Test_TerraformEmptyListEqualityRule(t *testing.T) { +func Test_OpentofuEmptyListEqualityRule(t *testing.T) { cases := []struct { Name string Content string @@ -23,7 +23,7 @@ resource "aws_db_instance" "mysql" { }`, Expected: helper.Issues{ { - Rule: NewTerraformEmptyListEqualityRule(), + Rule: NewOpentofuEmptyListEqualityRule(), Message: "Comparing a collection with an empty list is invalid. To detect an empty collection, check its length.", Range: hcl.Range{ Filename: "resource.tf", @@ -47,7 +47,7 @@ resource "aws_db_instance" "mysql" { }`, Expected: helper.Issues{ { - Rule: NewTerraformEmptyListEqualityRule(), + Rule: NewOpentofuEmptyListEqualityRule(), Message: "Comparing a collection with an empty list is invalid. To detect an empty collection, check its length.", Range: hcl.Range{ Filename: "resource.tf", @@ -56,7 +56,7 @@ resource "aws_db_instance" "mysql" { }, }, { - Rule: NewTerraformEmptyListEqualityRule(), + Rule: NewOpentofuEmptyListEqualityRule(), Message: "Comparing a collection with an empty list is invalid. To detect an empty collection, check its length.", Range: hcl.Range{ Filename: "resource.tf", @@ -80,7 +80,7 @@ resource "aws_db_instance" "mysql" { }`, Expected: helper.Issues{ { - Rule: NewTerraformEmptyListEqualityRule(), + Rule: NewOpentofuEmptyListEqualityRule(), Message: "Comparing a collection with an empty list is invalid. To detect an empty collection, check its length.", Range: hcl.Range{ Filename: "resource.tf", @@ -107,7 +107,7 @@ resource "aws_db_instance" "mysql" { }`, Expected: helper.Issues{ { - Rule: NewTerraformEmptyListEqualityRule(), + Rule: NewOpentofuEmptyListEqualityRule(), Message: "Comparing a collection with an empty list is invalid. To detect an empty collection, check its length.", Range: hcl.Range{ Filename: "resource.tf", @@ -146,7 +146,7 @@ resource "aws_db_instance" "mysql" { }`, Expected: helper.Issues{ { - Rule: NewTerraformEmptyListEqualityRule(), + Rule: NewOpentofuEmptyListEqualityRule(), Message: "Comparing a collection with an empty list is invalid. To detect an empty collection, check its length.", Range: hcl.Range{ Filename: "resource.tf", @@ -155,7 +155,7 @@ resource "aws_db_instance" "mysql" { }, }, { - Rule: NewTerraformEmptyListEqualityRule(), + Rule: NewOpentofuEmptyListEqualityRule(), Message: "Comparing a collection with an empty list is invalid. To detect an empty collection, check its length.", Range: hcl.Range{ Filename: "resource.tf", @@ -172,7 +172,7 @@ resource "aws_db_instance" "mysql" { }, } - rule := NewTerraformEmptyListEqualityRule() + rule := NewOpentofuEmptyListEqualityRule() for _, tc := range cases { t.Run(tc.Name, func(t *testing.T) { diff --git a/rules/terraform_json_syntax.go b/rules/opentofu_json_syntax.go similarity index 86% rename from rules/terraform_json_syntax.go rename to rules/opentofu_json_syntax.go index d43c503..a9f80b1 100644 --- a/rules/terraform_json_syntax.go +++ b/rules/opentofu_json_syntax.go @@ -4,10 +4,10 @@ import ( stdjson "encoding/json" "strings" + "github.com/diofeher/tflint-ruleset-opentofu/project" "github.com/hashicorp/hcl/v2" "github.com/hashicorp/hcl/v2/json" "github.com/terraform-linters/tflint-plugin-sdk/tflint" - "github.com/terraform-linters/tflint-ruleset-terraform/project" ) // deepMerge recursively merges src into dst @@ -80,38 +80,38 @@ func canMergeValues(values []any) bool { return true } -// TerraformJSONSyntaxRule checks whether JSON configuration uses the official syntax -type TerraformJSONSyntaxRule struct { +// OpentofuJSONSyntaxRule checks whether JSON configuration uses the official syntax +type OpentofuJSONSyntaxRule struct { tflint.DefaultRule } -// NewTerraformJSONSyntaxRule returns a new rule -func NewTerraformJSONSyntaxRule() *TerraformJSONSyntaxRule { - return &TerraformJSONSyntaxRule{} +// NewOpentofuJSONSyntaxRule returns a new rule +func NewOpentofuJSONSyntaxRule() *OpentofuJSONSyntaxRule { + return &OpentofuJSONSyntaxRule{} } // Name returns the rule name -func (r *TerraformJSONSyntaxRule) Name() string { - return "terraform_json_syntax" +func (r *OpentofuJSONSyntaxRule) Name() string { + return "opentofu_json_syntax" } // Enabled returns whether the rule is enabled by default -func (r *TerraformJSONSyntaxRule) Enabled() bool { +func (r *OpentofuJSONSyntaxRule) Enabled() bool { return true } // Severity returns the rule severity -func (r *TerraformJSONSyntaxRule) Severity() tflint.Severity { +func (r *OpentofuJSONSyntaxRule) Severity() tflint.Severity { return tflint.WARNING } // Link returns the rule reference link -func (r *TerraformJSONSyntaxRule) Link() string { +func (r *OpentofuJSONSyntaxRule) Link() string { return project.ReferenceLink(r.Name()) } // Check checks whether JSON configurations use object syntax at root -func (r *TerraformJSONSyntaxRule) Check(runner tflint.Runner) error { +func (r *OpentofuJSONSyntaxRule) Check(runner tflint.Runner) error { path, err := runner.GetModulePath() if err != nil { return err @@ -134,7 +134,7 @@ func (r *TerraformJSONSyntaxRule) Check(runner tflint.Runner) error { return nil } -func (r *TerraformJSONSyntaxRule) checkJSONSyntax(runner tflint.Runner, filename string, file *hcl.File) error { +func (r *OpentofuJSONSyntaxRule) checkJSONSyntax(runner tflint.Runner, filename string, file *hcl.File) error { if !strings.HasSuffix(filename, ".tf.json") { return nil } diff --git a/rules/terraform_json_syntax_test.go b/rules/opentofu_json_syntax_test.go similarity index 93% rename from rules/terraform_json_syntax_test.go rename to rules/opentofu_json_syntax_test.go index 79e3775..0d65ff0 100644 --- a/rules/terraform_json_syntax_test.go +++ b/rules/opentofu_json_syntax_test.go @@ -7,7 +7,7 @@ import ( "github.com/terraform-linters/tflint-plugin-sdk/helper" ) -func Test_TerraformJSONSyntaxRule(t *testing.T) { +func Test_OpentofuJSONSyntaxRule(t *testing.T) { for _, tc := range []struct { name string content string @@ -33,7 +33,7 @@ func Test_TerraformJSONSyntaxRule(t *testing.T) { filename: "main.tf.json", expected: helper.Issues{ { - Rule: NewTerraformJSONSyntaxRule(), + Rule: NewOpentofuJSONSyntaxRule(), Message: "JSON configuration uses array syntax at root, expected object", Range: hcl.Range{ Filename: "main.tf.json", @@ -85,7 +85,7 @@ func Test_TerraformJSONSyntaxRule(t *testing.T) { filename: "config.tf.json", expected: helper.Issues{ { - Rule: NewTerraformJSONSyntaxRule(), + Rule: NewOpentofuJSONSyntaxRule(), Message: "JSON configuration uses array syntax at root, expected object", Range: hcl.Range{ Filename: "config.tf.json", @@ -119,7 +119,7 @@ func Test_TerraformJSONSyntaxRule(t *testing.T) { filename: "multi.tf.json", expected: helper.Issues{ { - Rule: NewTerraformJSONSyntaxRule(), + Rule: NewOpentofuJSONSyntaxRule(), Message: "JSON configuration uses array syntax at root, expected object", Range: hcl.Range{ Filename: "multi.tf.json", @@ -151,7 +151,7 @@ func Test_TerraformJSONSyntaxRule(t *testing.T) { filename: "imports.tf.json", expected: helper.Issues{ { - Rule: NewTerraformJSONSyntaxRule(), + Rule: NewOpentofuJSONSyntaxRule(), Message: "JSON configuration uses array syntax at root, expected object", Range: hcl.Range{ Filename: "imports.tf.json", @@ -176,7 +176,7 @@ func Test_TerraformJSONSyntaxRule(t *testing.T) { }, } { t.Run(tc.name, func(t *testing.T) { - rule := NewTerraformJSONSyntaxRule() + rule := NewOpentofuJSONSyntaxRule() runner := helper.TestRunner(t, map[string]string{tc.filename: tc.content}) if err := rule.Check(runner); err != nil { diff --git a/rules/terraform_map_duplicate_keys.go b/rules/opentofu_map_duplicate_keys.go similarity index 81% rename from rules/terraform_map_duplicate_keys.go rename to rules/opentofu_map_duplicate_keys.go index 9027ce7..3ace126 100644 --- a/rules/terraform_map_duplicate_keys.go +++ b/rules/opentofu_map_duplicate_keys.go @@ -3,41 +3,41 @@ package rules import ( "fmt" + "github.com/diofeher/tflint-ruleset-opentofu/project" "github.com/hashicorp/hcl/v2" "github.com/hashicorp/hcl/v2/hclsyntax" "github.com/terraform-linters/tflint-plugin-sdk/logger" "github.com/terraform-linters/tflint-plugin-sdk/tflint" - "github.com/terraform-linters/tflint-ruleset-terraform/project" "github.com/zclconf/go-cty/cty" "github.com/zclconf/go-cty/cty/convert" ) // This rule checks for map literals with duplicate keys -type TerraformMapDuplicateKeysRule struct { +type OpentofuMapDuplicateKeysRule struct { tflint.DefaultRule } -func NewTerraformMapDuplicateKeysRule() *TerraformMapDuplicateKeysRule { - return &TerraformMapDuplicateKeysRule{} +func NewOpentofuMapDuplicateKeysRule() *OpentofuMapDuplicateKeysRule { + return &OpentofuMapDuplicateKeysRule{} } -func (r *TerraformMapDuplicateKeysRule) Name() string { - return "terraform_map_duplicate_keys" +func (r *OpentofuMapDuplicateKeysRule) Name() string { + return "opentofu_map_duplicate_keys" } -func (r *TerraformMapDuplicateKeysRule) Enabled() bool { +func (r *OpentofuMapDuplicateKeysRule) Enabled() bool { return true } -func (r *TerraformMapDuplicateKeysRule) Severity() tflint.Severity { +func (r *OpentofuMapDuplicateKeysRule) Severity() tflint.Severity { return tflint.WARNING } -func (r *TerraformMapDuplicateKeysRule) Link() string { +func (r *OpentofuMapDuplicateKeysRule) Link() string { return project.ReferenceLink(r.Name()) } -func (r *TerraformMapDuplicateKeysRule) Check(runner tflint.Runner) error { +func (r *OpentofuMapDuplicateKeysRule) Check(runner tflint.Runner) error { path, err := runner.GetModulePath() if err != nil { return err @@ -57,7 +57,7 @@ func (r *TerraformMapDuplicateKeysRule) Check(runner tflint.Runner) error { return nil } -func (r *TerraformMapDuplicateKeysRule) checkObjectConsExpr(e hcl.Expression, runner tflint.Runner) hcl.Diagnostics { +func (r *OpentofuMapDuplicateKeysRule) checkObjectConsExpr(e hcl.Expression, runner tflint.Runner) hcl.Diagnostics { objExpr, ok := e.(*hclsyntax.ObjectConsExpr) if !ok { return nil diff --git a/rules/terraform_map_duplicate_keys_test.go b/rules/opentofu_map_duplicate_keys_test.go similarity index 91% rename from rules/terraform_map_duplicate_keys_test.go rename to rules/opentofu_map_duplicate_keys_test.go index e12ef0a..8c160ae 100644 --- a/rules/terraform_map_duplicate_keys_test.go +++ b/rules/opentofu_map_duplicate_keys_test.go @@ -7,7 +7,7 @@ import ( "github.com/terraform-linters/tflint-plugin-sdk/helper" ) -func Test_TerraformMapDuplicateKeys(t *testing.T) { +func Test_OpentofuMapDuplicateKeys(t *testing.T) { cases := []struct { Name string Content string @@ -37,7 +37,7 @@ resource "null_resource" "test" { }`, Expected: helper.Issues{ { - Rule: NewTerraformMapDuplicateKeysRule(), + Rule: NewOpentofuMapDuplicateKeysRule(), Message: `Duplicate key: "a", first defined at module.tf:4,9-10`, Range: hcl.Range{ Filename: "module.tf", @@ -58,7 +58,7 @@ resource "null_resource" "test" { }`, Expected: helper.Issues{ { - Rule: NewTerraformMapDuplicateKeysRule(), + Rule: NewOpentofuMapDuplicateKeysRule(), Message: `Duplicate key: "a", first defined at module.tf:4,9-10`, Range: hcl.Range{ Filename: "module.tf", @@ -84,7 +84,7 @@ resource "null_resource" "test" { }`, Expected: helper.Issues{ { - Rule: NewTerraformMapDuplicateKeysRule(), + Rule: NewOpentofuMapDuplicateKeysRule(), Message: `Duplicate key: "b", first defined at module.tf:9,4-11`, Range: hcl.Range{ Filename: "module.tf", @@ -121,7 +121,7 @@ resource "null_resource" "test" { }`, Expected: helper.Issues{ { - Rule: NewTerraformMapDuplicateKeysRule(), + Rule: NewOpentofuMapDuplicateKeysRule(), Message: `Duplicate key: "a", first defined at module.tf:4,4-5`, Range: hcl.Range{ Filename: "module.tf", @@ -130,7 +130,7 @@ resource "null_resource" "test" { }, }, { - Rule: NewTerraformMapDuplicateKeysRule(), + Rule: NewOpentofuMapDuplicateKeysRule(), Message: `Duplicate key: "a", first defined at module.tf:4,4-5`, Range: hcl.Range{ Filename: "module.tf", @@ -183,7 +183,7 @@ resource "null_resource" "test" { }`, Expected: helper.Issues{ { - Rule: NewTerraformMapDuplicateKeysRule(), + Rule: NewOpentofuMapDuplicateKeysRule(), Message: `Duplicate key: "1", first defined at module.tf:4,5-6`, Range: hcl.Range{ Filename: "module.tf", @@ -207,7 +207,7 @@ resource "null_resource" "test" { }, } - rule := NewTerraformMapDuplicateKeysRule() + rule := NewOpentofuMapDuplicateKeysRule() for _, tc := range cases { t.Run(tc.Name, func(t *testing.T) { diff --git a/rules/terraform_module_pinned_source.go b/rules/opentofu_module_pinned_source.go similarity index 77% rename from rules/terraform_module_pinned_source.go rename to rules/opentofu_module_pinned_source.go index 24a5c06..a2e5a0e 100644 --- a/rules/terraform_module_pinned_source.go +++ b/rules/opentofu_module_pinned_source.go @@ -7,14 +7,14 @@ import ( "strings" "github.com/Masterminds/semver/v3" + "github.com/diofeher/tflint-ruleset-opentofu/opentofu" + "github.com/diofeher/tflint-ruleset-opentofu/project" "github.com/hashicorp/go-getter" "github.com/terraform-linters/tflint-plugin-sdk/tflint" - "github.com/terraform-linters/tflint-ruleset-terraform/project" - "github.com/terraform-linters/tflint-ruleset-terraform/terraform" ) -// TerraformModulePinnedSourceRule checks unpinned or default version module source -type TerraformModulePinnedSourceRule struct { +// OpentofuModulePinnedSourceRule checks unpinned or default version module source +type OpentofuModulePinnedSourceRule struct { tflint.DefaultRule attributeName string @@ -25,37 +25,37 @@ type terraformModulePinnedSourceRuleConfig struct { DefaultBranches []string `hclext:"default_branches,optional"` } -// NewTerraformModulePinnedSourceRule returns new rule with default attributes -func NewTerraformModulePinnedSourceRule() *TerraformModulePinnedSourceRule { - return &TerraformModulePinnedSourceRule{ +// NewOpentofuModulePinnedSourceRule returns new rule with default attributes +func NewOpentofuModulePinnedSourceRule() *OpentofuModulePinnedSourceRule { + return &OpentofuModulePinnedSourceRule{ attributeName: "source", } } // Name returns the rule name -func (r *TerraformModulePinnedSourceRule) Name() string { - return "terraform_module_pinned_source" +func (r *OpentofuModulePinnedSourceRule) Name() string { + return "opentofu_module_pinned_source" } // Enabled returns whether the rule is enabled by default -func (r *TerraformModulePinnedSourceRule) Enabled() bool { +func (r *OpentofuModulePinnedSourceRule) Enabled() bool { return true } // Severity returns the rule severity -func (r *TerraformModulePinnedSourceRule) Severity() tflint.Severity { +func (r *OpentofuModulePinnedSourceRule) Severity() tflint.Severity { return tflint.WARNING } // Link returns the rule reference link -func (r *TerraformModulePinnedSourceRule) Link() string { +func (r *OpentofuModulePinnedSourceRule) Link() string { return project.ReferenceLink(r.Name()) } // Check checks if module source version is pinned // Note that this rule is valid only for Git or Mercurial source -func (r *TerraformModulePinnedSourceRule) Check(rr tflint.Runner) error { - runner := rr.(*terraform.Runner) +func (r *OpentofuModulePinnedSourceRule) Check(rr tflint.Runner) error { + runner := rr.(*opentofu.Runner) path, err := runner.GetModulePath() if err != nil { @@ -86,7 +86,7 @@ func (r *TerraformModulePinnedSourceRule) Check(rr tflint.Runner) error { return nil } -func (r *TerraformModulePinnedSourceRule) checkModule(runner tflint.Runner, module *terraform.ModuleCall, config terraformModulePinnedSourceRuleConfig) error { +func (r *OpentofuModulePinnedSourceRule) checkModule(runner tflint.Runner, module *opentofu.ModuleCall, config terraformModulePinnedSourceRuleConfig) error { // Extract query parameters from the original source before calling getter.Detect() // because go-getter may URL-encode them when there's a subdirectory path originalQuery := url.Values{} @@ -162,7 +162,7 @@ func (r *TerraformModulePinnedSourceRule) checkModule(runner tflint.Runner, modu ) } -func (r *TerraformModulePinnedSourceRule) checkRevision(runner tflint.Runner, module *terraform.ModuleCall, config terraformModulePinnedSourceRuleConfig, key string, value string) error { +func (r *OpentofuModulePinnedSourceRule) checkRevision(runner tflint.Runner, module *opentofu.ModuleCall, config terraformModulePinnedSourceRuleConfig, key string, value string) error { switch config.Style { // The "flexible" style requires a revision that is not a default branch case "flexible": diff --git a/rules/terraform_module_pinned_source_test.go b/rules/opentofu_module_pinned_source_test.go similarity index 89% rename from rules/terraform_module_pinned_source_test.go rename to rules/opentofu_module_pinned_source_test.go index 100f703..654bfe5 100644 --- a/rules/terraform_module_pinned_source_test.go +++ b/rules/opentofu_module_pinned_source_test.go @@ -7,7 +7,7 @@ import ( "github.com/terraform-linters/tflint-plugin-sdk/helper" ) -func Test_TerraformModulePinnedSource(t *testing.T) { +func Test_OpentofuModulePinnedSource(t *testing.T) { cases := []struct { Name string Content string @@ -30,7 +30,7 @@ module "unpinned" { }`, Expected: helper.Issues{ { - Rule: NewTerraformModulePinnedSourceRule(), + Rule: NewOpentofuModulePinnedSourceRule(), Message: "Module source \"git://hashicorp.com/consul.git\" is not pinned", Range: hcl.Range{ Filename: "module.tf", @@ -48,7 +48,7 @@ module "default_git" { }`, Expected: helper.Issues{ { - Rule: NewTerraformModulePinnedSourceRule(), + Rule: NewOpentofuModulePinnedSourceRule(), Message: "Module source \"git://hashicorp.com/consul.git?ref=master\" uses a default branch as ref (master)", Range: hcl.Range{ Filename: "module.tf", @@ -74,7 +74,7 @@ module "unpinned" { }`, Expected: helper.Issues{ { - Rule: NewTerraformModulePinnedSourceRule(), + Rule: NewOpentofuModulePinnedSourceRule(), Message: "Module source \"git://hashicorp.com/consul.git/subdirectory\" is not pinned", Range: hcl.Range{ Filename: "module.tf", @@ -100,7 +100,7 @@ module "invalid" { }`, Expected: helper.Issues{ { - Rule: NewTerraformModulePinnedSourceRule(), + Rule: NewOpentofuModulePinnedSourceRule(), Message: `Module source "git://#{}.com" is not a valid URL`, Range: hcl.Range{ Filename: "module.tf", @@ -117,13 +117,13 @@ module "pinned_git" { source = "git://hashicorp.com/consul.git?ref=pinned" }`, Config: ` -rule "terraform_module_pinned_source" { +rule "opentofu_module_pinned_source" { enabled = true style = "semver" }`, Expected: helper.Issues{ { - Rule: NewTerraformModulePinnedSourceRule(), + Rule: NewOpentofuModulePinnedSourceRule(), Message: "Module source \"git://hashicorp.com/consul.git?ref=pinned\" uses a ref which is not a semantic version string", Range: hcl.Range{ Filename: "module.tf", @@ -140,7 +140,7 @@ module "pinned_git" { source = "git://hashicorp.com/consul.git?ref=v1.2.3" }`, Config: ` -rule "terraform_module_pinned_source" { +rule "opentofu_module_pinned_source" { enabled = true style = "semver" }`, @@ -153,7 +153,7 @@ module "pinned_git" { source = "git://hashicorp.com/consul.git?ref=1.2.3" }`, Config: ` -rule "terraform_module_pinned_source" { +rule "opentofu_module_pinned_source" { enabled = true style = "semver" }`, @@ -167,7 +167,7 @@ module "unpinned" { }`, Expected: helper.Issues{ { - Rule: NewTerraformModulePinnedSourceRule(), + Rule: NewOpentofuModulePinnedSourceRule(), Message: "Module source \"github.com/hashicorp/consul\" is not pinned", Range: hcl.Range{ Filename: "module.tf", @@ -185,7 +185,7 @@ module "unpinned" { }`, Expected: helper.Issues{ { - Rule: NewTerraformModulePinnedSourceRule(), + Rule: NewOpentofuModulePinnedSourceRule(), Message: "Module source \"git@github.com:hashicorp/consul.git\" is not pinned", Range: hcl.Range{ Filename: "module.tf", @@ -203,7 +203,7 @@ module "default_git" { }`, Expected: helper.Issues{ { - Rule: NewTerraformModulePinnedSourceRule(), + Rule: NewOpentofuModulePinnedSourceRule(), Message: "Module source \"github.com/hashicorp/consul.git?ref=master\" uses a default branch as ref (master)", Range: hcl.Range{ Filename: "module.tf", @@ -229,7 +229,7 @@ module "unpinned" { }`, Expected: helper.Issues{ { - Rule: NewTerraformModulePinnedSourceRule(), + Rule: NewOpentofuModulePinnedSourceRule(), Message: "Module source \"github.com/hashicorp/consul.git/subdirectory\" is not pinned", Range: hcl.Range{ Filename: "module.tf", @@ -255,7 +255,7 @@ module "default_git" { }`, Expected: helper.Issues{ { - Rule: NewTerraformModulePinnedSourceRule(), + Rule: NewOpentofuModulePinnedSourceRule(), Message: "Module source \"github.com/hashicorp/consul.git/subdirectory?ref=master\" uses a default branch as ref (master)", Range: hcl.Range{ Filename: "module.tf", @@ -273,7 +273,7 @@ module "unpinned" { }`, Expected: helper.Issues{ { - Rule: NewTerraformModulePinnedSourceRule(), + Rule: NewOpentofuModulePinnedSourceRule(), Message: "Module source \"github.com/hashicorp/consul.git/directory/subdirectory\" is not pinned", Range: hcl.Range{ Filename: "module.tf", @@ -306,13 +306,13 @@ module "pinned_git" { source = "github.com/hashicorp/consul.git?ref=pinned" }`, Config: ` -rule "terraform_module_pinned_source" { +rule "opentofu_module_pinned_source" { enabled = true style = "semver" }`, Expected: helper.Issues{ { - Rule: NewTerraformModulePinnedSourceRule(), + Rule: NewOpentofuModulePinnedSourceRule(), Message: "Module source \"github.com/hashicorp/consul.git?ref=pinned\" uses a ref which is not a semantic version string", Range: hcl.Range{ Filename: "module.tf", @@ -329,7 +329,7 @@ module "pinned_git" { source = "github.com/hashicorp/consul.git?ref=v1.2.3" }`, Config: ` -rule "terraform_module_pinned_source" { +rule "opentofu_module_pinned_source" { enabled = true style = "semver" }`, @@ -343,7 +343,7 @@ module "unpinned" { }`, Expected: helper.Issues{ { - Rule: NewTerraformModulePinnedSourceRule(), + Rule: NewOpentofuModulePinnedSourceRule(), Message: "Module source \"bitbucket.org/hashicorp/tf-test-git\" is not pinned", Range: hcl.Range{ Filename: "module.tf", @@ -361,7 +361,7 @@ module "default_git" { }`, Expected: helper.Issues{ { - Rule: NewTerraformModulePinnedSourceRule(), + Rule: NewOpentofuModulePinnedSourceRule(), Message: "Module source \"bitbucket.org/hashicorp/tf-test-git.git?ref=master\" uses a default branch as ref (master)", Range: hcl.Range{ Filename: "module.tf", @@ -386,13 +386,13 @@ module "pinned_git" { source = "bitbucket.org/hashicorp/tf-test-git.git?ref=pinned" }`, Config: ` -rule "terraform_module_pinned_source" { +rule "opentofu_module_pinned_source" { enabled = true style = "semver" }`, Expected: helper.Issues{ { - Rule: NewTerraformModulePinnedSourceRule(), + Rule: NewOpentofuModulePinnedSourceRule(), Message: "Module source \"bitbucket.org/hashicorp/tf-test-git.git?ref=pinned\" uses a ref which is not a semantic version string", Range: hcl.Range{ Filename: "module.tf", @@ -409,7 +409,7 @@ module "pinned_git" { source = "bitbucket.org/hashicorp/tf-test-git.git?ref=v1.2.3" }`, Config: ` -rule "terraform_module_pinned_source" { +rule "opentofu_module_pinned_source" { enabled = true style = "semver" }`, @@ -424,7 +424,7 @@ module "unpinned_generic_git_https" { `, Expected: helper.Issues{ { - Rule: NewTerraformModulePinnedSourceRule(), + Rule: NewOpentofuModulePinnedSourceRule(), Message: "Module source \"git::https://hashicorp.com/consul.git\" is not pinned", Range: hcl.Range{ Filename: "module.tf", @@ -443,7 +443,7 @@ module "unpinned_generic_git_ssh" { `, Expected: helper.Issues{ { - Rule: NewTerraformModulePinnedSourceRule(), + Rule: NewOpentofuModulePinnedSourceRule(), Message: "Module source \"git::ssh://git@github.com/owner/repo.git\" is not pinned", Range: hcl.Range{ Filename: "module.tf", @@ -462,7 +462,7 @@ module "default_generic_git_https" { `, Expected: helper.Issues{ { - Rule: NewTerraformModulePinnedSourceRule(), + Rule: NewOpentofuModulePinnedSourceRule(), Message: "Module source \"git::https://hashicorp.com/consul.git?ref=master\" uses a default branch as ref (master)", Range: hcl.Range{ Filename: "module.tf", @@ -481,7 +481,7 @@ module "default_generic_git_ssh" { `, Expected: helper.Issues{ { - Rule: NewTerraformModulePinnedSourceRule(), + Rule: NewOpentofuModulePinnedSourceRule(), Message: "Module source \"git::ssh://git@github.com/owner/repo.git?ref=master\" uses a default branch as ref (master)", Range: hcl.Range{ Filename: "module.tf", @@ -516,13 +516,13 @@ module "pinned_git" { source = "github.com/hashicorp/consul.git?ref=foo" }`, Config: ` -rule "terraform_module_pinned_source" { +rule "opentofu_module_pinned_source" { enabled = true default_branches = ["foo"] }`, Expected: helper.Issues{ { - Rule: NewTerraformModulePinnedSourceRule(), + Rule: NewOpentofuModulePinnedSourceRule(), Message: "Module source \"github.com/hashicorp/consul.git?ref=foo\" uses a default branch as ref (foo)", Range: hcl.Range{ Filename: "module.tf", @@ -540,7 +540,7 @@ module "default_mercurial" { }`, Expected: helper.Issues{ { - Rule: NewTerraformModulePinnedSourceRule(), + Rule: NewOpentofuModulePinnedSourceRule(), Message: "Module source \"hg::http://hashicorp.com/consul.hg\" is not pinned", Range: hcl.Range{ Filename: "module.tf", @@ -558,7 +558,7 @@ module "default_mercurial" { }`, Expected: helper.Issues{ { - Rule: NewTerraformModulePinnedSourceRule(), + Rule: NewOpentofuModulePinnedSourceRule(), Message: "Module source \"hg::http://hashicorp.com/consul.hg?rev=default\" uses a default branch as rev (default)", Range: hcl.Range{ Filename: "module.tf", @@ -583,13 +583,13 @@ module "unpinned" { source = "git://hashicorp.com/consul.git" }`, Config: ` -rule "terraform_module_pinned_source" { +rule "opentofu_module_pinned_source" { enabled = true style = "flexible" }`, Expected: helper.Issues{ { - Rule: NewTerraformModulePinnedSourceRule(), + Rule: NewOpentofuModulePinnedSourceRule(), Message: "Module source \"git://hashicorp.com/consul.git\" is not pinned", Range: hcl.Range{ Filename: "module.tf", @@ -601,7 +601,7 @@ rule "terraform_module_pinned_source" { }, } - rule := NewTerraformModulePinnedSourceRule() + rule := NewOpentofuModulePinnedSourceRule() for _, tc := range cases { t.Run(tc.Name, func(t *testing.T) { diff --git a/rules/terraform_module_shallow_clone.go b/rules/opentofu_module_shallow_clone.go similarity index 75% rename from rules/terraform_module_shallow_clone.go rename to rules/opentofu_module_shallow_clone.go index 998f05e..d3fe8c2 100644 --- a/rules/terraform_module_shallow_clone.go +++ b/rules/opentofu_module_shallow_clone.go @@ -7,52 +7,52 @@ import ( "regexp" "strings" + "github.com/diofeher/tflint-ruleset-opentofu/opentofu" + "github.com/diofeher/tflint-ruleset-opentofu/project" "github.com/hashicorp/go-getter" "github.com/hashicorp/hcl/v2" "github.com/terraform-linters/tflint-plugin-sdk/tflint" - "github.com/terraform-linters/tflint-ruleset-terraform/project" - "github.com/terraform-linters/tflint-ruleset-terraform/terraform" ) var gitCommitRegex = regexp.MustCompile("^[a-f0-9]{4,64}$") -// TerraformModuleShallowCloneRule checks that Git-hosted Terraform modules use shallow cloning -type TerraformModuleShallowCloneRule struct { +// OpentofuModuleShallowCloneRule checks that Git-hosted Opentofu modules use shallow cloning +type OpentofuModuleShallowCloneRule struct { tflint.DefaultRule attributeName string } -// NewTerraformModuleShallowCloneRule returns new rule with default attributes -func NewTerraformModuleShallowCloneRule() *TerraformModuleShallowCloneRule { - return &TerraformModuleShallowCloneRule{ +// NewOpentofuModuleShallowCloneRule returns new rule with default attributes +func NewOpentofuModuleShallowCloneRule() *OpentofuModuleShallowCloneRule { + return &OpentofuModuleShallowCloneRule{ attributeName: "source", } } // Name returns the rule name -func (r *TerraformModuleShallowCloneRule) Name() string { - return "terraform_module_shallow_clone" +func (r *OpentofuModuleShallowCloneRule) Name() string { + return "opentofu_module_shallow_clone" } // Enabled returns whether the rule is enabled by default -func (r *TerraformModuleShallowCloneRule) Enabled() bool { +func (r *OpentofuModuleShallowCloneRule) Enabled() bool { return false } // Severity returns the rule severity -func (r *TerraformModuleShallowCloneRule) Severity() tflint.Severity { +func (r *OpentofuModuleShallowCloneRule) Severity() tflint.Severity { return tflint.WARNING } // Link returns the rule reference link -func (r *TerraformModuleShallowCloneRule) Link() string { +func (r *OpentofuModuleShallowCloneRule) Link() string { return project.ReferenceLink(r.Name()) } -// Check checks if Git-hosted Terraform modules use shallow cloning -func (r *TerraformModuleShallowCloneRule) Check(rr tflint.Runner) error { - runner := rr.(*terraform.Runner) +// Check checks if Git-hosted Opentofu modules use shallow cloning +func (r *OpentofuModuleShallowCloneRule) Check(rr tflint.Runner) error { + runner := rr.(*opentofu.Runner) path, err := runner.GetModulePath() if err != nil { @@ -77,7 +77,7 @@ func (r *TerraformModuleShallowCloneRule) Check(rr tflint.Runner) error { return nil } -func (r *TerraformModuleShallowCloneRule) checkModule(runner tflint.Runner, module *terraform.ModuleCall) error { +func (r *OpentofuModuleShallowCloneRule) checkModule(runner tflint.Runner, module *opentofu.ModuleCall) error { filename := module.DefRange.Filename source, err := getter.Detect(module.Source, filepath.Dir(filename), []getter.Detector{ // https://github.com/hashicorp/terraform/blob/51b0aee36cc2145f45f5b04051a01eb6eb7be8bf/internal/getmodules/getter.go#L30-L52 diff --git a/rules/terraform_module_shallow_clone_test.go b/rules/opentofu_module_shallow_clone_test.go similarity index 93% rename from rules/terraform_module_shallow_clone_test.go rename to rules/opentofu_module_shallow_clone_test.go index a65db80..771423a 100644 --- a/rules/terraform_module_shallow_clone_test.go +++ b/rules/opentofu_module_shallow_clone_test.go @@ -7,7 +7,7 @@ import ( "github.com/terraform-linters/tflint-plugin-sdk/helper" ) -func Test_TerraformModuleShallowClone(t *testing.T) { +func Test_OpentofuModuleShallowClone(t *testing.T) { cases := []struct { Name string Content string @@ -95,7 +95,7 @@ module "ssh_pinned" { }`, Expected: helper.Issues{ { - Rule: NewTerraformModuleShallowCloneRule(), + Rule: NewOpentofuModuleShallowCloneRule(), Message: `Module source "git::ssh://git@github.com/hashicorp/consul.git?ref=v1.0.0" should enable shallow cloning by adding "depth=1" parameter`, Range: hcl.Range{ Filename: "module.tf", @@ -117,7 +117,7 @@ module "https_pinned" { }`, Expected: helper.Issues{ { - Rule: NewTerraformModuleShallowCloneRule(), + Rule: NewOpentofuModuleShallowCloneRule(), Message: `Module source "git::https://github.com/hashicorp/consul.git?ref=v1.0.0" should enable shallow cloning by adding "depth=1" parameter`, Range: hcl.Range{ Filename: "module.tf", @@ -139,7 +139,7 @@ module "github_ssh" { }`, Expected: helper.Issues{ { - Rule: NewTerraformModuleShallowCloneRule(), + Rule: NewOpentofuModuleShallowCloneRule(), Message: `Module source "git@github.com:hashicorp/consul.git?ref=v1.0.0" should enable shallow cloning by adding "depth=1" parameter`, Range: hcl.Range{ Filename: "module.tf", @@ -161,7 +161,7 @@ module "github_https" { }`, Expected: helper.Issues{ { - Rule: NewTerraformModuleShallowCloneRule(), + Rule: NewOpentofuModuleShallowCloneRule(), Message: `Module source "github.com/hashicorp/consul?ref=v1.0.0" should enable shallow cloning by adding "depth=1" parameter`, Range: hcl.Range{ Filename: "module.tf", @@ -183,7 +183,7 @@ module "bitbucket" { }`, Expected: helper.Issues{ { - Rule: NewTerraformModuleShallowCloneRule(), + Rule: NewOpentofuModuleShallowCloneRule(), Message: `Module source "bitbucket.org/hashicorp/tf-test-git?ref=v1.0.0" should enable shallow cloning by adding "depth=1" parameter`, Range: hcl.Range{ Filename: "module.tf", @@ -205,7 +205,7 @@ module "short_branch_name" { }`, Expected: helper.Issues{ { - Rule: NewTerraformModuleShallowCloneRule(), + Rule: NewOpentofuModuleShallowCloneRule(), Message: `Module source "github.com/hashicorp/consul?ref=beta" should enable shallow cloning by adding "depth=1" parameter`, Range: hcl.Range{ Filename: "module.tf", @@ -221,7 +221,7 @@ module "short_branch_name" { }, } - rule := NewTerraformModuleShallowCloneRule() + rule := NewOpentofuModuleShallowCloneRule() for _, tc := range cases { t.Run(tc.Name, func(t *testing.T) { diff --git a/rules/terraform_module_version.go b/rules/opentofu_module_version.go similarity index 61% rename from rules/terraform_module_version.go rename to rules/opentofu_module_version.go index 5c82465..438639c 100644 --- a/rules/terraform_module_version.go +++ b/rules/opentofu_module_version.go @@ -4,55 +4,55 @@ import ( "fmt" "regexp" - tfaddr "github.com/hashicorp/terraform-registry-address" + "github.com/diofeher/tflint-ruleset-opentofu/opentofu" + "github.com/diofeher/tflint-ruleset-opentofu/project" + tfaddr "github.com/opentofu/registry-address" "github.com/terraform-linters/tflint-plugin-sdk/tflint" - "github.com/terraform-linters/tflint-ruleset-terraform/project" - "github.com/terraform-linters/tflint-ruleset-terraform/terraform" ) // SemVer regexp with optional leading = // https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string var exactVersionRegexp = regexp.MustCompile(`^=?\s*` + `(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)(?:-(?P(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$`) -// TerraformModuleVersionRule checks that Terraform modules sourced from a registry specify a version -type TerraformModuleVersionRule struct { +// OpentofuModuleVersionRule checks that Opentofu modules sourced from a registry specify a version +type OpentofuModuleVersionRule struct { tflint.DefaultRule } -// TerraformModuleVersionRuleConfig is the config structure for the TerraformModuleVersionRule rule -type TerraformModuleVersionRuleConfig struct { +// OpentofuModuleVersionRuleConfig is the config structure for the OpentofuModuleVersionRule rule +type OpentofuModuleVersionRuleConfig struct { Exact bool `hclext:"exact,optional"` } -// NewTerraformModuleVersionRule returns a new rule -func NewTerraformModuleVersionRule() *TerraformModuleVersionRule { - return &TerraformModuleVersionRule{} +// NewOpentofuModuleVersionRule returns a new rule +func NewOpentofuModuleVersionRule() *OpentofuModuleVersionRule { + return &OpentofuModuleVersionRule{} } // Name returns the rule name -func (r *TerraformModuleVersionRule) Name() string { - return "terraform_module_version" +func (r *OpentofuModuleVersionRule) Name() string { + return "opentofu_module_version" } // Enabled returns whether the rule is enabled by default -func (r *TerraformModuleVersionRule) Enabled() bool { +func (r *OpentofuModuleVersionRule) Enabled() bool { return true } // Severity returns the rule severity -func (r *TerraformModuleVersionRule) Severity() tflint.Severity { +func (r *OpentofuModuleVersionRule) Severity() tflint.Severity { return tflint.WARNING } // Link returns the rule reference link -func (r *TerraformModuleVersionRule) Link() string { +func (r *OpentofuModuleVersionRule) Link() string { return project.ReferenceLink(r.Name()) } -// Check checks whether module source attributes resolve to a Terraform registry +// Check checks whether module source attributes resolve to a Opentofu registry // If they do, it checks a version (or range) is set -func (r *TerraformModuleVersionRule) Check(rr tflint.Runner) error { - runner := rr.(*terraform.Runner) +func (r *OpentofuModuleVersionRule) Check(rr tflint.Runner) error { + runner := rr.(*opentofu.Runner) path, err := runner.GetModulePath() if err != nil { @@ -63,7 +63,7 @@ func (r *TerraformModuleVersionRule) Check(rr tflint.Runner) error { return nil } - config := TerraformModuleVersionRuleConfig{} + config := OpentofuModuleVersionRuleConfig{} if err := runner.DecodeRuleConfig(r.Name(), &config); err != nil { return err } @@ -82,7 +82,7 @@ func (r *TerraformModuleVersionRule) Check(rr tflint.Runner) error { return nil } -func (r *TerraformModuleVersionRule) checkModule(runner tflint.Runner, module *terraform.ModuleCall, config TerraformModuleVersionRuleConfig) error { +func (r *OpentofuModuleVersionRule) checkModule(runner tflint.Runner, module *opentofu.ModuleCall, config OpentofuModuleVersionRuleConfig) error { _, err := tfaddr.ParseModuleSource(module.Source) if err != nil { // If parsing fails, the source does not expect to specify a version, @@ -94,7 +94,7 @@ func (r *TerraformModuleVersionRule) checkModule(runner tflint.Runner, module *t return r.checkVersion(runner, module, config) } -func (r *TerraformModuleVersionRule) checkVersion(runner tflint.Runner, module *terraform.ModuleCall, config TerraformModuleVersionRuleConfig) error { +func (r *OpentofuModuleVersionRule) checkVersion(runner tflint.Runner, module *opentofu.ModuleCall, config OpentofuModuleVersionRuleConfig) error { if module.Version == nil { return runner.EmitIssue( r, diff --git a/rules/terraform_module_version_test.go b/rules/opentofu_module_version_test.go similarity index 84% rename from rules/terraform_module_version_test.go rename to rules/opentofu_module_version_test.go index 00da6f0..29b71a4 100644 --- a/rules/terraform_module_version_test.go +++ b/rules/opentofu_module_version_test.go @@ -8,7 +8,7 @@ import ( "github.com/terraform-linters/tflint-plugin-sdk/helper" ) -func TestTerraformModuleVersion_Registry(t *testing.T) { +func TestOpentofuModuleVersion_Registry(t *testing.T) { cases := []struct { Name string Content string @@ -95,7 +95,7 @@ module "m" { }`, Expected: helper.Issues{ { - Rule: NewTerraformModuleVersionRule(), + Rule: NewOpentofuModuleVersionRule(), Message: `module "m" should specify a version`, Range: hcl.Range{ Filename: "module.tf", @@ -112,7 +112,7 @@ module "m" { source = "ns/name/provider" version = "1.0.0" }`, - Config: testTerraformModuleVersionExactConfig, + Config: testOpentofuModuleVersionExactConfig, Expected: helper.Issues{}, }, { @@ -122,10 +122,10 @@ module "m" { source = "ns/name/provider" version = "1.0.0, 1.0.1" }`, - Config: testTerraformModuleVersionExactConfig, + Config: testOpentofuModuleVersionExactConfig, Expected: helper.Issues{ { - Rule: NewTerraformModuleVersionRule(), + Rule: NewOpentofuModuleVersionRule(), Message: `module "m" should specify an exact version, but multiple constraints were found`, Range: hcl.Range{ Filename: "module.tf", @@ -142,10 +142,10 @@ module "m" { source = "ns/name/provider" version = "~> 1.0.0" }`, - Config: testTerraformModuleVersionExactConfig, + Config: testOpentofuModuleVersionExactConfig, Expected: helper.Issues{ { - Rule: NewTerraformModuleVersionRule(), + Rule: NewOpentofuModuleVersionRule(), Message: `module "m" should specify an exact version, but a range was found`, Range: hcl.Range{ Filename: "module.tf", @@ -162,10 +162,10 @@ module "m" { source = "ns/name/provider" version = "1.0" }`, - Config: testTerraformModuleVersionExactConfig, + Config: testOpentofuModuleVersionExactConfig, Expected: helper.Issues{ { - Rule: NewTerraformModuleVersionRule(), + Rule: NewOpentofuModuleVersionRule(), Message: `module "m" should specify an exact version, but a range was found`, Range: hcl.Range{ Filename: "module.tf", @@ -177,7 +177,7 @@ module "m" { }, } - rule := NewTerraformModuleVersionRule() + rule := NewOpentofuModuleVersionRule() for _, tc := range cases { t.Run(tc.Name, func(t *testing.T) { @@ -192,7 +192,7 @@ module "m" { } } -func TestTerraformModuleVersion_NonRegistry(t *testing.T) { +func TestOpentofuModuleVersion_NonRegistry(t *testing.T) { cases := []struct { Name string Source string @@ -215,11 +215,11 @@ func TestTerraformModuleVersion_NonRegistry(t *testing.T) { }, } - rule := NewTerraformModuleVersionRule() + rule := NewOpentofuModuleVersionRule() for _, tc := range cases { t.Run(tc.Name, func(t *testing.T) { - content := fmt.Sprintf(testTerraformModuleVersionNonRegistrySource, tc.Source) + content := fmt.Sprintf(testOpentofuModuleVersionNonRegistrySource, tc.Source) runner := testRunner(t, map[string]string{"module.tf": content}) if err := rule.Check(runner); err != nil { @@ -231,14 +231,14 @@ func TestTerraformModuleVersion_NonRegistry(t *testing.T) { } } -const testTerraformModuleVersionExactConfig = ` -rule "terraform_module_version" { +const testOpentofuModuleVersionExactConfig = ` +rule "opentofu_module_version" { enabled = true exact = true } ` -const testTerraformModuleVersionNonRegistrySource = ` +const testOpentofuModuleVersionNonRegistrySource = ` module "m" { source = "%s" } diff --git a/rules/terraform_naming_convention.go b/rules/opentofu_naming_convention.go similarity index 90% rename from rules/terraform_naming_convention.go rename to rules/opentofu_naming_convention.go index 368e791..848d379 100644 --- a/rules/terraform_naming_convention.go +++ b/rules/opentofu_naming_convention.go @@ -5,15 +5,15 @@ import ( "regexp" "strings" + "github.com/diofeher/tflint-ruleset-opentofu/opentofu" + "github.com/diofeher/tflint-ruleset-opentofu/project" "github.com/hashicorp/hcl/v2" "github.com/terraform-linters/tflint-plugin-sdk/hclext" "github.com/terraform-linters/tflint-plugin-sdk/tflint" - "github.com/terraform-linters/tflint-ruleset-terraform/project" - "github.com/terraform-linters/tflint-ruleset-terraform/terraform" ) -// TerraformNamingConventionRule checks whether blocks follow naming convention -type TerraformNamingConventionRule struct { +// OpentofuNamingConventionRule checks whether blocks follow naming convention +type OpentofuNamingConventionRule struct { tflint.DefaultRule } @@ -51,34 +51,34 @@ type NameValidator struct { Regexp *regexp.Regexp } -// NewTerraformNamingConventionRule returns new rule with default attributes -func NewTerraformNamingConventionRule() *TerraformNamingConventionRule { - return &TerraformNamingConventionRule{} +// NewOpentofuNamingConventionRule returns new rule with default attributes +func NewOpentofuNamingConventionRule() *OpentofuNamingConventionRule { + return &OpentofuNamingConventionRule{} } // Name returns the rule name -func (r *TerraformNamingConventionRule) Name() string { - return "terraform_naming_convention" +func (r *OpentofuNamingConventionRule) Name() string { + return "opentofu_naming_convention" } // Enabled returns whether the rule is enabled by default -func (r *TerraformNamingConventionRule) Enabled() bool { +func (r *OpentofuNamingConventionRule) Enabled() bool { return true } // Severity returns the rule severity -func (r *TerraformNamingConventionRule) Severity() tflint.Severity { +func (r *OpentofuNamingConventionRule) Severity() tflint.Severity { return tflint.NOTICE } // Link returns the rule reference link -func (r *TerraformNamingConventionRule) Link() string { +func (r *OpentofuNamingConventionRule) Link() string { return project.ReferenceLink(r.Name()) } // Check checks whether blocks follow naming convention -func (r *TerraformNamingConventionRule) Check(rr tflint.Runner) error { - runner := rr.(*terraform.Runner) +func (r *OpentofuNamingConventionRule) Check(rr tflint.Runner) error { + runner := rr.(*opentofu.Runner) path, err := runner.GetModulePath() if err != nil { @@ -247,7 +247,7 @@ func (r *TerraformNamingConventionRule) Check(rr tflint.Runner) error { return nil } -func (validator *NameValidator) checkBlock(runner tflint.Runner, r *TerraformNamingConventionRule, blockTypeName string, blockName string, blockDeclRange *hcl.Range) error { +func (validator *NameValidator) checkBlock(runner tflint.Runner, r *OpentofuNamingConventionRule, blockTypeName string, blockName string, blockDeclRange *hcl.Range) error { if validator != nil && !validator.Regexp.MatchString(blockName) { var formatType string if validator.IsNamedFormat { diff --git a/rules/terraform_naming_convention_test.go b/rules/opentofu_naming_convention_test.go similarity index 86% rename from rules/terraform_naming_convention_test.go rename to rules/opentofu_naming_convention_test.go index 9950f33..3cc722a 100644 --- a/rules/terraform_naming_convention_test.go +++ b/rules/opentofu_naming_convention_test.go @@ -9,40 +9,40 @@ import ( ) // Data blocks -func Test_TerraformNamingConventionRule_Data_DefaultEmpty(t *testing.T) { +func Test_OpentofuNamingConventionRule_Data_DefaultEmpty(t *testing.T) { testDataSnakeCase(t, "default config", "format: snake_case", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true }`) } -func Test_TerraformNamingConventionRule_Data_DefaultFormat(t *testing.T) { +func Test_OpentofuNamingConventionRule_Data_DefaultFormat(t *testing.T) { testDataMixedSnakeCase(t, `default config (format="mixed_snake_case")`, ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "mixed_snake_case" }`) } -func Test_TerraformNamingConventionRule_Data_DefaultCustom(t *testing.T) { +func Test_OpentofuNamingConventionRule_Data_DefaultCustom(t *testing.T) { testDataSnakeCase(t, `default config (custom="^[a-z_]+$")`, "RegExp: ^[a-z][a-z]*(_[a-z]+)*$", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true custom = "^[a-z][a-z]*(_[a-z]+)*$" }`) } -func Test_TerraformNamingConventionRule_Data_DefaultDisabled(t *testing.T) { +func Test_OpentofuNamingConventionRule_Data_DefaultDisabled(t *testing.T) { testDataDisabled(t, `default config (format=null)`, ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "none" }`) } -func Test_TerraformNamingConventionRule_Data_DefaultFormat_OverrideFormat(t *testing.T) { +func Test_OpentofuNamingConventionRule_Data_DefaultFormat_OverrideFormat(t *testing.T) { testDataSnakeCase(t, `overridden config (format="snake_case")`, "format: snake_case", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "mixed_snake_case" @@ -52,9 +52,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Data_DefaultFormat_OverrideCustom(t *testing.T) { +func Test_OpentofuNamingConventionRule_Data_DefaultFormat_OverrideCustom(t *testing.T) { testDataSnakeCase(t, `overridden config (format="snake_case")`, "RegExp: ^[a-z][a-z]*(_[a-z]+)*$", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "mixed_snake_case" @@ -64,9 +64,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Data_DefaultCustom_OverrideFormat(t *testing.T) { +func Test_OpentofuNamingConventionRule_Data_DefaultCustom_OverrideFormat(t *testing.T) { testDataSnakeCase(t, `overridden config (format="snake_case")`, "format: snake_case", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true custom = "^ignored$" @@ -76,9 +76,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Data_DefaultCustom_OverrideCustom(t *testing.T) { +func Test_OpentofuNamingConventionRule_Data_DefaultCustom_OverrideCustom(t *testing.T) { testDataSnakeCase(t, `overridden config (format="snake_case")`, "RegExp: ^[a-z][a-z]*(_[a-z]+)*$", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true custom = "^ignored$" @@ -88,9 +88,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Data_DefaultDisabled_OverrideFormat(t *testing.T) { +func Test_OpentofuNamingConventionRule_Data_DefaultDisabled_OverrideFormat(t *testing.T) { testDataSnakeCase(t, `overridden config (format="snake_case")`, "format: snake_case", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "none" @@ -100,9 +100,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Data_DefaultDisabled_OverrideCustom(t *testing.T) { +func Test_OpentofuNamingConventionRule_Data_DefaultDisabled_OverrideCustom(t *testing.T) { testDataSnakeCase(t, `overridden config (format="snake_case")`, "RegExp: ^[a-z][a-z]*(_[a-z]+)*$", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "none" @@ -112,9 +112,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Data_DefaultEmpty_OverrideDisabled(t *testing.T) { +func Test_OpentofuNamingConventionRule_Data_DefaultEmpty_OverrideDisabled(t *testing.T) { testDataDisabled(t, `overridden config (format=null)`, ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true data { @@ -123,9 +123,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Data_DefaultFormat_OverrideDisabled(t *testing.T) { +func Test_OpentofuNamingConventionRule_Data_DefaultFormat_OverrideDisabled(t *testing.T) { testDataDisabled(t, `overridden config (format=null)`, ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "snake_case" @@ -135,9 +135,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Data_CustomFormats(t *testing.T) { +func Test_OpentofuNamingConventionRule_Data_CustomFormats(t *testing.T) { testDataSnakeCase(t, `default config (custom_format="custom_snake_case")`, "format: Custom Snake Case", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "custom_snake_case" @@ -150,9 +150,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Data_CustomFormats_OverridePredefined(t *testing.T) { +func Test_OpentofuNamingConventionRule_Data_CustomFormats_OverridePredefined(t *testing.T) { testDataSnakeCase(t, `default config (custom_format="snake_case")`, "format: Custom Snake Case", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "snake_case" @@ -166,7 +166,7 @@ rule "terraform_naming_convention" { } func testDataSnakeCase(t *testing.T, testType string, formatName string, config string) { - rule := NewTerraformNamingConventionRule() + rule := NewOpentofuNamingConventionRule() cases := []struct { Name string @@ -345,7 +345,7 @@ check "ignored" { } func testDataMixedSnakeCase(t *testing.T, testType string, config string) { - rule := NewTerraformNamingConventionRule() + rule := NewOpentofuNamingConventionRule() cases := []struct { Name string @@ -471,7 +471,7 @@ data "aws_eip" "camelCase" { } func testDataDisabled(t *testing.T, testType string, config string) { - rule := NewTerraformNamingConventionRule() + rule := NewOpentofuNamingConventionRule() cases := []struct { Name string @@ -551,40 +551,40 @@ data "aws_eip" "camelCase" { } // Local values -func Test_TerraformNamingConventionRule_Locals_DefaultEmpty(t *testing.T) { +func Test_OpentofuNamingConventionRule_Locals_DefaultEmpty(t *testing.T) { testLocalsSnakeCase(t, "default config", "format: snake_case", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true }`) } -func Test_TerraformNamingConventionRule_Locals_DefaultFormat(t *testing.T) { +func Test_OpentofuNamingConventionRule_Locals_DefaultFormat(t *testing.T) { testLocalsMixedSnakeCase(t, `default config (format="mixed_snake_case")`, ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "mixed_snake_case" }`) } -func Test_TerraformNamingConventionRule_Locals_DefaultCustom(t *testing.T) { +func Test_OpentofuNamingConventionRule_Locals_DefaultCustom(t *testing.T) { testLocalsSnakeCase(t, `default config (custom="^[a-z_]+$")`, "RegExp: ^[a-z][a-z]*(_[a-z]+)*$", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true custom = "^[a-z][a-z]*(_[a-z]+)*$" }`) } -func Test_TerraformNamingConventionRule_Locals_DefaultDisabled(t *testing.T) { +func Test_OpentofuNamingConventionRule_Locals_DefaultDisabled(t *testing.T) { testLocalsDisabled(t, `default config (format=null)`, ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "none" }`) } -func Test_TerraformNamingConventionRule_Locals_DefaultFormat_OverrideFormat(t *testing.T) { +func Test_OpentofuNamingConventionRule_Locals_DefaultFormat_OverrideFormat(t *testing.T) { testLocalsSnakeCase(t, `overridden config (format="snake_case")`, "format: snake_case", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "mixed_snake_case" @@ -594,9 +594,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Locals_DefaultFormat_OverrideCustom(t *testing.T) { +func Test_OpentofuNamingConventionRule_Locals_DefaultFormat_OverrideCustom(t *testing.T) { testLocalsSnakeCase(t, `overridden config (format="snake_case")`, "RegExp: ^[a-z][a-z]*(_[a-z]+)*$", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "mixed_snake_case" @@ -606,9 +606,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Locals_DefaultCustom_OverrideFormat(t *testing.T) { +func Test_OpentofuNamingConventionRule_Locals_DefaultCustom_OverrideFormat(t *testing.T) { testLocalsSnakeCase(t, `overridden config (format="snake_case")`, "format: snake_case", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true custom = "^ignored$" @@ -618,9 +618,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Locals_DefaultCustom_OverrideCustom(t *testing.T) { +func Test_OpentofuNamingConventionRule_Locals_DefaultCustom_OverrideCustom(t *testing.T) { testLocalsSnakeCase(t, `overridden config (format="snake_case")`, "RegExp: ^[a-z][a-z]*(_[a-z]+)*$", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true custom = "^ignored$" @@ -630,9 +630,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Locals_DefaultDisabled_OverrideFormat(t *testing.T) { +func Test_OpentofuNamingConventionRule_Locals_DefaultDisabled_OverrideFormat(t *testing.T) { testLocalsSnakeCase(t, `overridden config (format="snake_case")`, "format: snake_case", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "none" @@ -642,9 +642,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Locals_DefaultDisabled_OverrideCustom(t *testing.T) { +func Test_OpentofuNamingConventionRule_Locals_DefaultDisabled_OverrideCustom(t *testing.T) { testLocalsSnakeCase(t, `overridden config (format="snake_case")`, "RegExp: ^[a-z][a-z]*(_[a-z]+)*$", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "none" @@ -654,9 +654,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Locals_DefaultEmpty_OverrideDisabled(t *testing.T) { +func Test_OpentofuNamingConventionRule_Locals_DefaultEmpty_OverrideDisabled(t *testing.T) { testLocalsDisabled(t, `overridden config (format=null)`, ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true locals { @@ -665,9 +665,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Locals_DefaultFormat_OverrideDisabled(t *testing.T) { +func Test_OpentofuNamingConventionRule_Locals_DefaultFormat_OverrideDisabled(t *testing.T) { testLocalsDisabled(t, `overridden config (format=null)`, ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "snake_case" @@ -678,7 +678,7 @@ rule "terraform_naming_convention" { } func testLocalsSnakeCase(t *testing.T, testType string, formatName string, config string) { - rule := NewTerraformNamingConventionRule() + rule := NewOpentofuNamingConventionRule() cases := []struct { Name string @@ -815,7 +815,7 @@ locals { } func testLocalsMixedSnakeCase(t *testing.T, testType string, config string) { - rule := NewTerraformNamingConventionRule() + rule := NewOpentofuNamingConventionRule() cases := []struct { Name string @@ -950,7 +950,7 @@ locals { } func testLocalsDisabled(t *testing.T, testType string, config string) { - rule := NewTerraformNamingConventionRule() + rule := NewOpentofuNamingConventionRule() cases := []struct { Name string @@ -1037,40 +1037,40 @@ locals { } // Module blocks -func Test_TerraformNamingConventionRule_Module_DefaultEmpty(t *testing.T) { +func Test_OpentofuNamingConventionRule_Module_DefaultEmpty(t *testing.T) { testModuleSnakeCase(t, "default config", "format: snake_case", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true }`) } -func Test_TerraformNamingConventionRule_Module_DefaultFormat(t *testing.T) { +func Test_OpentofuNamingConventionRule_Module_DefaultFormat(t *testing.T) { testModuleMixedSnakeCase(t, `default config (format="mixed_snake_case")`, ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "mixed_snake_case" }`) } -func Test_TerraformNamingConventionRule_Module_DefaultCustom(t *testing.T) { +func Test_OpentofuNamingConventionRule_Module_DefaultCustom(t *testing.T) { testModuleSnakeCase(t, `default config (custom="^[a-z_]+$")`, "RegExp: ^[a-z][a-z]*(_[a-z]+)*$", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true custom = "^[a-z][a-z]*(_[a-z]+)*$" }`) } -func Test_TerraformNamingConventionRule_Module_DefaultDisabled(t *testing.T) { +func Test_OpentofuNamingConventionRule_Module_DefaultDisabled(t *testing.T) { testModuleDisabled(t, `default config (format=null)`, ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "none" }`) } -func Test_TerraformNamingConventionRule_Module_DefaultFormat_OverrideFormat(t *testing.T) { +func Test_OpentofuNamingConventionRule_Module_DefaultFormat_OverrideFormat(t *testing.T) { testModuleSnakeCase(t, `overridden config (format="snake_case")`, "format: snake_case", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "mixed_snake_case" @@ -1080,9 +1080,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Module_DefaultFormat_OverrideCustom(t *testing.T) { +func Test_OpentofuNamingConventionRule_Module_DefaultFormat_OverrideCustom(t *testing.T) { testModuleSnakeCase(t, `overridden config (format="snake_case")`, "RegExp: ^[a-z][a-z]*(_[a-z]+)*$", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "mixed_snake_case" @@ -1092,9 +1092,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Module_DefaultCustom_OverrideFormat(t *testing.T) { +func Test_OpentofuNamingConventionRule_Module_DefaultCustom_OverrideFormat(t *testing.T) { testModuleSnakeCase(t, `overridden config (format="snake_case")`, "format: snake_case", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true custom = "^ignored$" @@ -1104,9 +1104,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Module_DefaultCustom_OverrideCustom(t *testing.T) { +func Test_OpentofuNamingConventionRule_Module_DefaultCustom_OverrideCustom(t *testing.T) { testModuleSnakeCase(t, `overridden config (format="snake_case")`, "RegExp: ^[a-z][a-z]*(_[a-z]+)*$", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true custom = "^ignored$" @@ -1116,9 +1116,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Module_DefaultDisabled_OverrideFormat(t *testing.T) { +func Test_OpentofuNamingConventionRule_Module_DefaultDisabled_OverrideFormat(t *testing.T) { testModuleSnakeCase(t, `overridden config (format="snake_case")`, "format: snake_case", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "none" @@ -1128,9 +1128,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Module_DefaultDisabled_OverrideCustom(t *testing.T) { +func Test_OpentofuNamingConventionRule_Module_DefaultDisabled_OverrideCustom(t *testing.T) { testModuleSnakeCase(t, `overridden config (format="snake_case")`, "RegExp: ^[a-z][a-z]*(_[a-z]+)*$", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "none" @@ -1140,9 +1140,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Module_DefaultEmpty_OverrideDisabled(t *testing.T) { +func Test_OpentofuNamingConventionRule_Module_DefaultEmpty_OverrideDisabled(t *testing.T) { testModuleDisabled(t, `overridden config (format=null)`, ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true module { @@ -1151,9 +1151,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Module_DefaultFormat_OverrideDisabled(t *testing.T) { +func Test_OpentofuNamingConventionRule_Module_DefaultFormat_OverrideDisabled(t *testing.T) { testModuleDisabled(t, `overridden config (format=null)`, ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "snake_case" @@ -1164,7 +1164,7 @@ rule "terraform_naming_convention" { } func testModuleSnakeCase(t *testing.T, testType string, formatName string, config string) { - rule := NewTerraformNamingConventionRule() + rule := NewOpentofuNamingConventionRule() cases := []struct { Name string @@ -1301,7 +1301,7 @@ module "foo" { } func testModuleMixedSnakeCase(t *testing.T, testType string, config string) { - rule := NewTerraformNamingConventionRule() + rule := NewOpentofuNamingConventionRule() cases := []struct { Name string @@ -1436,7 +1436,7 @@ module "camelCase" { } func testModuleDisabled(t *testing.T, testType string, config string) { - rule := NewTerraformNamingConventionRule() + rule := NewOpentofuNamingConventionRule() cases := []struct { Name string @@ -1523,40 +1523,40 @@ module "camelCase" { } // Output blocks -func Test_TerraformNamingConventionRule_Output_DefaultEmpty(t *testing.T) { +func Test_OpentofuNamingConventionRule_Output_DefaultEmpty(t *testing.T) { testOutputSnakeCase(t, "default config", "format: snake_case", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true }`) } -func Test_TerraformNamingConventionRule_Output_DefaultFormat(t *testing.T) { +func Test_OpentofuNamingConventionRule_Output_DefaultFormat(t *testing.T) { testOutputMixedSnakeCase(t, `default config (format="mixed_snake_case")`, ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "mixed_snake_case" }`) } -func Test_TerraformNamingConventionRule_Output_DefaultCustom(t *testing.T) { +func Test_OpentofuNamingConventionRule_Output_DefaultCustom(t *testing.T) { testOutputSnakeCase(t, `default config (custom="^[a-z_]+$")`, "RegExp: ^[a-z][a-z]*(_[a-z]+)*$", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true custom = "^[a-z][a-z]*(_[a-z]+)*$" }`) } -func Test_TerraformNamingConventionRule_Output_DefaultDisabled(t *testing.T) { +func Test_OpentofuNamingConventionRule_Output_DefaultDisabled(t *testing.T) { testOutputDisabled(t, `default config (format=null)`, ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "none" }`) } -func Test_TerraformNamingConventionRule_Output_DefaultFormat_OverrideFormat(t *testing.T) { +func Test_OpentofuNamingConventionRule_Output_DefaultFormat_OverrideFormat(t *testing.T) { testOutputSnakeCase(t, `overridden config (format="snake_case")`, "format: snake_case", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "mixed_snake_case" @@ -1566,9 +1566,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Output_DefaultFormat_OverrideCustom(t *testing.T) { +func Test_OpentofuNamingConventionRule_Output_DefaultFormat_OverrideCustom(t *testing.T) { testOutputSnakeCase(t, `overridden config (format="snake_case")`, "RegExp: ^[a-z][a-z]*(_[a-z]+)*$", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "mixed_snake_case" @@ -1578,9 +1578,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Output_DefaultCustom_OverrideFormat(t *testing.T) { +func Test_OpentofuNamingConventionRule_Output_DefaultCustom_OverrideFormat(t *testing.T) { testOutputSnakeCase(t, `overridden config (format="snake_case")`, "format: snake_case", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true custom = "^ignored$" @@ -1590,9 +1590,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Output_DefaultCustom_OverrideCustom(t *testing.T) { +func Test_OpentofuNamingConventionRule_Output_DefaultCustom_OverrideCustom(t *testing.T) { testOutputSnakeCase(t, `overridden config (format="snake_case")`, "RegExp: ^[a-z][a-z]*(_[a-z]+)*$", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true custom = "^ignored$" @@ -1602,9 +1602,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Output_DefaultDisabled_OverrideFormat(t *testing.T) { +func Test_OpentofuNamingConventionRule_Output_DefaultDisabled_OverrideFormat(t *testing.T) { testOutputSnakeCase(t, `overridden config (format="snake_case")`, "format: snake_case", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "none" @@ -1614,9 +1614,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Output_DefaultDisabled_OverrideCustom(t *testing.T) { +func Test_OpentofuNamingConventionRule_Output_DefaultDisabled_OverrideCustom(t *testing.T) { testOutputSnakeCase(t, `overridden config (format="snake_case")`, "RegExp: ^[a-z][a-z]*(_[a-z]+)*$", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "none" @@ -1626,9 +1626,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Output_DefaultEmpty_OverrideDisabled(t *testing.T) { +func Test_OpentofuNamingConventionRule_Output_DefaultEmpty_OverrideDisabled(t *testing.T) { testOutputDisabled(t, `overridden config (format=null)`, ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true output { @@ -1637,9 +1637,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Output_DefaultFormat_OverrideDisabled(t *testing.T) { +func Test_OpentofuNamingConventionRule_Output_DefaultFormat_OverrideDisabled(t *testing.T) { testOutputDisabled(t, `overridden config (format=null)`, ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "snake_case" @@ -1650,7 +1650,7 @@ rule "terraform_naming_convention" { } func testOutputSnakeCase(t *testing.T, testType string, formatName string, config string) { - rule := NewTerraformNamingConventionRule() + rule := NewOpentofuNamingConventionRule() cases := []struct { Name string @@ -1787,7 +1787,7 @@ output "foo" { } func testOutputMixedSnakeCase(t *testing.T, testType string, config string) { - rule := NewTerraformNamingConventionRule() + rule := NewOpentofuNamingConventionRule() cases := []struct { Name string @@ -1922,7 +1922,7 @@ output "camelCase" { } func testOutputDisabled(t *testing.T, testType string, config string) { - rule := NewTerraformNamingConventionRule() + rule := NewOpentofuNamingConventionRule() cases := []struct { Name string @@ -2009,40 +2009,40 @@ output "camelCase" { } // Resource blocks -func Test_TerraformNamingConventionRule_Resource_DefaultEmpty(t *testing.T) { +func Test_OpentofuNamingConventionRule_Resource_DefaultEmpty(t *testing.T) { testResourceSnakeCase(t, "default config", "format: snake_case", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true }`) } -func Test_TerraformNamingConventionRule_Resource_DefaultFormat(t *testing.T) { +func Test_OpentofuNamingConventionRule_Resource_DefaultFormat(t *testing.T) { testResourceMixedSnakeCase(t, `default config (format="mixed_snake_case")`, ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "mixed_snake_case" }`) } -func Test_TerraformNamingConventionRule_Resource_DefaultCustom(t *testing.T) { +func Test_OpentofuNamingConventionRule_Resource_DefaultCustom(t *testing.T) { testResourceSnakeCase(t, `default config (custom="^[a-z_]+$")`, "RegExp: ^[a-z][a-z]*(_[a-z]+)*$", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true custom = "^[a-z][a-z]*(_[a-z]+)*$" }`) } -func Test_TerraformNamingConventionRule_Resource_DefaultDisabled(t *testing.T) { +func Test_OpentofuNamingConventionRule_Resource_DefaultDisabled(t *testing.T) { testResourceDisabled(t, `default config (format=null)`, ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "none" }`) } -func Test_TerraformNamingConventionRule_Resource_DefaultFormat_OverrideFormat(t *testing.T) { +func Test_OpentofuNamingConventionRule_Resource_DefaultFormat_OverrideFormat(t *testing.T) { testResourceSnakeCase(t, `overridden config (format="snake_case")`, "format: snake_case", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "mixed_snake_case" @@ -2052,9 +2052,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Resource_DefaultFormat_OverrideCustom(t *testing.T) { +func Test_OpentofuNamingConventionRule_Resource_DefaultFormat_OverrideCustom(t *testing.T) { testResourceSnakeCase(t, `overridden config (format="snake_case")`, "RegExp: ^[a-z][a-z]*(_[a-z]+)*$", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "mixed_snake_case" @@ -2064,9 +2064,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Resource_DefaultCustom_OverrideFormat(t *testing.T) { +func Test_OpentofuNamingConventionRule_Resource_DefaultCustom_OverrideFormat(t *testing.T) { testResourceSnakeCase(t, `overridden config (format="snake_case")`, "format: snake_case", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true custom = "^ignored$" @@ -2076,9 +2076,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Resource_DefaultCustom_OverrideCustom(t *testing.T) { +func Test_OpentofuNamingConventionRule_Resource_DefaultCustom_OverrideCustom(t *testing.T) { testResourceSnakeCase(t, `overridden config (format="snake_case")`, "RegExp: ^[a-z][a-z]*(_[a-z]+)*$", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true custom = "^ignored$" @@ -2088,9 +2088,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Resource_DefaultDisabled_OverrideFormat(t *testing.T) { +func Test_OpentofuNamingConventionRule_Resource_DefaultDisabled_OverrideFormat(t *testing.T) { testResourceSnakeCase(t, `overridden config (format="snake_case")`, "format: snake_case", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "none" @@ -2100,9 +2100,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Resource_DefaultDisabled_OverrideCustom(t *testing.T) { +func Test_OpentofuNamingConventionRule_Resource_DefaultDisabled_OverrideCustom(t *testing.T) { testResourceSnakeCase(t, `overridden config (format="snake_case")`, "RegExp: ^[a-z][a-z]*(_[a-z]+)*$", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "none" @@ -2112,9 +2112,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Resource_DefaultEmpty_OverrideDisabled(t *testing.T) { +func Test_OpentofuNamingConventionRule_Resource_DefaultEmpty_OverrideDisabled(t *testing.T) { testResourceDisabled(t, `overridden config (format=null)`, ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true resource { @@ -2123,9 +2123,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Resource_DefaultFormat_OverrideDisabled(t *testing.T) { +func Test_OpentofuNamingConventionRule_Resource_DefaultFormat_OverrideDisabled(t *testing.T) { testResourceDisabled(t, `overridden config (format=null)`, ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "snake_case" @@ -2136,7 +2136,7 @@ rule "terraform_naming_convention" { } func testResourceSnakeCase(t *testing.T, testType string, formatName string, config string) { - rule := NewTerraformNamingConventionRule() + rule := NewOpentofuNamingConventionRule() cases := []struct { Name string @@ -2266,7 +2266,7 @@ resource "aws_eip" "foo" { } func testResourceMixedSnakeCase(t *testing.T, testType string, config string) { - rule := NewTerraformNamingConventionRule() + rule := NewOpentofuNamingConventionRule() cases := []struct { Name string @@ -2392,7 +2392,7 @@ resource "aws_eip" "camelCase" { } func testResourceDisabled(t *testing.T, testType string, config string) { - rule := NewTerraformNamingConventionRule() + rule := NewOpentofuNamingConventionRule() cases := []struct { Name string @@ -2472,40 +2472,40 @@ resource "aws_eip" "camelCase" { } // Variable blocks -func Test_TerraformNamingConventionRule_Variable_DefaultEmpty(t *testing.T) { +func Test_OpentofuNamingConventionRule_Variable_DefaultEmpty(t *testing.T) { testVariableSnakeCase(t, "default config", "format: snake_case", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true }`) } -func Test_TerraformNamingConventionRule_Variable_DefaultFormat(t *testing.T) { +func Test_OpentofuNamingConventionRule_Variable_DefaultFormat(t *testing.T) { testVariableMixedSnakeCase(t, `default config (format="mixed_snake_case")`, ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "mixed_snake_case" }`) } -func Test_TerraformNamingConventionRule_Variable_DefaultCustom(t *testing.T) { +func Test_OpentofuNamingConventionRule_Variable_DefaultCustom(t *testing.T) { testVariableSnakeCase(t, `default config (custom="^[a-z_]+$")`, "RegExp: ^[a-z][a-z]*(_[a-z]+)*$", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true custom = "^[a-z][a-z]*(_[a-z]+)*$" }`) } -func Test_TerraformNamingConventionRule_Variable_DefaultDisabled(t *testing.T) { +func Test_OpentofuNamingConventionRule_Variable_DefaultDisabled(t *testing.T) { testVariableDisabled(t, `default config (format=null)`, ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "none" }`) } -func Test_TerraformNamingConventionRule_Variable_DefaultFormat_OverrideFormat(t *testing.T) { +func Test_OpentofuNamingConventionRule_Variable_DefaultFormat_OverrideFormat(t *testing.T) { testVariableSnakeCase(t, `overridden config (format="snake_case")`, "format: snake_case", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "mixed_snake_case" @@ -2515,9 +2515,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Variable_DefaultFormat_OverrideCustom(t *testing.T) { +func Test_OpentofuNamingConventionRule_Variable_DefaultFormat_OverrideCustom(t *testing.T) { testVariableSnakeCase(t, `overridden config (format="snake_case")`, "RegExp: ^[a-z][a-z]*(_[a-z]+)*$", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "mixed_snake_case" @@ -2527,9 +2527,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Variable_DefaultCustom_OverrideFormat(t *testing.T) { +func Test_OpentofuNamingConventionRule_Variable_DefaultCustom_OverrideFormat(t *testing.T) { testVariableSnakeCase(t, `overridden config (format="snake_case")`, "format: snake_case", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true custom = "^ignored$" @@ -2539,9 +2539,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Variable_DefaultCustom_OverrideCustom(t *testing.T) { +func Test_OpentofuNamingConventionRule_Variable_DefaultCustom_OverrideCustom(t *testing.T) { testVariableSnakeCase(t, `overridden config (format="snake_case")`, "RegExp: ^[a-z][a-z]*(_[a-z]+)*$", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true custom = "^ignored$" @@ -2551,9 +2551,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Variable_DefaultDisabled_OverrideFormat(t *testing.T) { +func Test_OpentofuNamingConventionRule_Variable_DefaultDisabled_OverrideFormat(t *testing.T) { testVariableSnakeCase(t, `overridden config (format="snake_case")`, "format: snake_case", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "none" @@ -2563,9 +2563,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Variable_DefaultDisabled_OverrideCustom(t *testing.T) { +func Test_OpentofuNamingConventionRule_Variable_DefaultDisabled_OverrideCustom(t *testing.T) { testVariableSnakeCase(t, `overridden config (format="snake_case")`, "RegExp: ^[a-z][a-z]*(_[a-z]+)*$", ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "none" @@ -2575,9 +2575,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Variable_DefaultEmpty_OverrideDisabled(t *testing.T) { +func Test_OpentofuNamingConventionRule_Variable_DefaultEmpty_OverrideDisabled(t *testing.T) { testVariableDisabled(t, `overridden config (format=null)`, ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true variable { @@ -2586,9 +2586,9 @@ rule "terraform_naming_convention" { }`) } -func Test_TerraformNamingConventionRule_Variable_DefaultFormat_OverrideDisabled(t *testing.T) { +func Test_OpentofuNamingConventionRule_Variable_DefaultFormat_OverrideDisabled(t *testing.T) { testVariableDisabled(t, `overridden config (format=null)`, ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true format = "snake_case" @@ -2599,7 +2599,7 @@ rule "terraform_naming_convention" { } func testVariableSnakeCase(t *testing.T, testType string, formatName string, config string) { - rule := NewTerraformNamingConventionRule() + rule := NewOpentofuNamingConventionRule() cases := []struct { Name string @@ -2736,7 +2736,7 @@ variable "foo" { } func testVariableMixedSnakeCase(t *testing.T, testType string, config string) { - rule := NewTerraformNamingConventionRule() + rule := NewOpentofuNamingConventionRule() cases := []struct { Name string @@ -2871,7 +2871,7 @@ variable "camelCase" { } func testVariableDisabled(t *testing.T, testType string, config string) { - rule := NewTerraformNamingConventionRule() + rule := NewOpentofuNamingConventionRule() cases := []struct { Name string @@ -2957,11 +2957,11 @@ variable "camelCase" { } } -func Test_TerraformNamingConventionRule_Check(t *testing.T) { - rule := NewTerraformNamingConventionRule() +func Test_OpentofuNamingConventionRule_Check(t *testing.T) { + rule := NewOpentofuNamingConventionRule() config := ` -rule "terraform_naming_convention" { +rule "opentofu_naming_convention" { enabled = true check { diff --git a/rules/terraform_required_providers.go b/rules/opentofu_required_providers.go similarity index 81% rename from rules/terraform_required_providers.go rename to rules/opentofu_required_providers.go index c5cccf9..52c3dd1 100644 --- a/rules/terraform_required_providers.go +++ b/rules/opentofu_required_providers.go @@ -3,56 +3,56 @@ package rules import ( "fmt" + "github.com/diofeher/tflint-ruleset-opentofu/opentofu" + "github.com/diofeher/tflint-ruleset-opentofu/project" "github.com/hashicorp/hcl/v2" - tfaddr "github.com/hashicorp/terraform-registry-address" + tfaddr "github.com/opentofu/registry-address" "github.com/terraform-linters/tflint-plugin-sdk/hclext" tfsdk "github.com/terraform-linters/tflint-plugin-sdk/terraform" "github.com/terraform-linters/tflint-plugin-sdk/tflint" - "github.com/terraform-linters/tflint-ruleset-terraform/project" - "github.com/terraform-linters/tflint-ruleset-terraform/terraform" "github.com/zclconf/go-cty/cty" ) -// TerraformRequiredProvidersRule checks whether Terraform sets version constraints for all configured providers -type TerraformRequiredProvidersRule struct { +// OpentofuRequiredProvidersRule checks whether Opentofu sets version constraints for all configured providers +type OpentofuRequiredProvidersRule struct { tflint.DefaultRule } -type terraformRequiredProvidersRuleConfig struct { +type opentofuRequiredProvidersRuleConfig struct { // Source specifies whether the rule should assert the presence of a `source` attribute Source *bool `hclext:"source,optional"` // Version specifies whether the rule should assert the presence of a `version` attribute Version *bool `hclext:"version,optional"` } -// NewTerraformRequiredProvidersRule returns new rule with default attributes -func NewTerraformRequiredProvidersRule() *TerraformRequiredProvidersRule { - return &TerraformRequiredProvidersRule{} +// NewOpentofuRequiredProvidersRule returns new rule with default attributes +func NewOpentofuRequiredProvidersRule() *OpentofuRequiredProvidersRule { + return &OpentofuRequiredProvidersRule{} } // Name returns the rule name -func (r *TerraformRequiredProvidersRule) Name() string { - return "terraform_required_providers" +func (r *OpentofuRequiredProvidersRule) Name() string { + return "opentofu_required_providers" } // Enabled returns whether the rule is enabled by default -func (r *TerraformRequiredProvidersRule) Enabled() bool { +func (r *OpentofuRequiredProvidersRule) Enabled() bool { return true } // Severity returns the rule severity -func (r *TerraformRequiredProvidersRule) Severity() tflint.Severity { +func (r *OpentofuRequiredProvidersRule) Severity() tflint.Severity { return tflint.WARNING } // Link returns the rule reference link -func (r *TerraformRequiredProvidersRule) Link() string { +func (r *OpentofuRequiredProvidersRule) Link() string { return project.ReferenceLink(r.Name()) } // config returns the rule config, with defaults -func (r *TerraformRequiredProvidersRule) config(runner tflint.Runner) (*terraformRequiredProvidersRuleConfig, error) { - config := &terraformRequiredProvidersRuleConfig{} +func (r *OpentofuRequiredProvidersRule) config(runner tflint.Runner) (*opentofuRequiredProvidersRuleConfig, error) { + config := &opentofuRequiredProvidersRuleConfig{} if err := runner.DecodeRuleConfig(r.Name(), config); err != nil { return nil, err @@ -71,8 +71,8 @@ func (r *TerraformRequiredProvidersRule) config(runner tflint.Runner) (*terrafor } // Check Checks whether provider required version is set -func (r *TerraformRequiredProvidersRule) Check(rr tflint.Runner) error { - runner := rr.(*terraform.Runner) +func (r *OpentofuRequiredProvidersRule) Check(rr tflint.Runner) error { + runner := rr.(*opentofu.Runner) path, err := runner.GetModulePath() if err != nil { @@ -107,12 +107,12 @@ func (r *TerraformRequiredProvidersRule) Check(rr tflint.Runner) error { for _, provider := range body.Blocks { if _, exists := provider.Body.Attributes["version"]; exists { - if err := runner.EmitIssue( + if runErr := runner.EmitIssue( r, "provider version constraint should be specified via `required_providers`", provider.DefRange, ); err != nil { - return err + return runErr } } } @@ -149,8 +149,8 @@ func (r *TerraformRequiredProvidersRule) Check(rr tflint.Runner) error { } requiredProviders := hclext.Attributes{} - for _, terraform := range body.Blocks { - for _, requiredProvidersBlock := range terraform.Body.Blocks { + for _, opentofuBlock := range body.Blocks { + for _, requiredProvidersBlock := range opentofuBlock.Body.Blocks { for name, attr := range requiredProvidersBlock.Body.Attributes { requiredProviders[name] = attr } @@ -214,6 +214,7 @@ func (r *TerraformRequiredProvidersRule) Check(rr tflint.Runner) error { if source, exists := vm["source"]; exists { p, err := tfaddr.ParseProviderSource(source.AsString()) + if err != nil { return err } diff --git a/rules/terraform_required_providers_test.go b/rules/opentofu_required_providers_test.go similarity index 91% rename from rules/terraform_required_providers_test.go rename to rules/opentofu_required_providers_test.go index 551b058..fadec10 100644 --- a/rules/terraform_required_providers_test.go +++ b/rules/opentofu_required_providers_test.go @@ -7,7 +7,7 @@ import ( "github.com/terraform-linters/tflint-plugin-sdk/helper" ) -func Test_TerraformRequiredProvidersRule(t *testing.T) { +func Test_OpentofuRequiredProvidersRule(t *testing.T) { cases := []struct { Name string Content string @@ -23,7 +23,7 @@ provider "template" {} `, Expected: helper.Issues{ { - Rule: NewTerraformRequiredProvidersRule(), + Rule: NewOpentofuRequiredProvidersRule(), Message: "Missing version constraint for provider \"template\" in `required_providers`", Range: hcl.Range{ Filename: "module.tf", @@ -48,7 +48,7 @@ resource "random_string" "foo" { `, Expected: helper.Issues{ { - Rule: NewTerraformRequiredProvidersRule(), + Rule: NewOpentofuRequiredProvidersRule(), Message: "Missing version constraint for provider \"random\" in `required_providers`", Range: hcl.Range{ Filename: "module.tf", @@ -73,7 +73,7 @@ ephemeral "random_string" "foo" { `, Expected: helper.Issues{ { - Rule: NewTerraformRequiredProvidersRule(), + Rule: NewOpentofuRequiredProvidersRule(), Message: "Missing version constraint for provider \"random\" in `required_providers`", Range: hcl.Range{ Filename: "module.tf", @@ -98,7 +98,7 @@ data "template_file" "foo" { `, Expected: helper.Issues{ { - Rule: NewTerraformRequiredProvidersRule(), + Rule: NewOpentofuRequiredProvidersRule(), Message: "Missing version constraint for provider \"template\" in `required_providers`", Range: hcl.Range{ Filename: "module.tf", @@ -141,7 +141,7 @@ provider "template" {} `, Expected: helper.Issues{ { - Rule: NewTerraformRequiredProvidersRule(), + Rule: NewOpentofuRequiredProvidersRule(), Message: "Legacy version constraint for provider \"template\" in `required_providers`", Range: hcl.Range{ Filename: "module.tf", @@ -183,7 +183,7 @@ provider "template" {} `, Expected: helper.Issues{ { - Rule: NewTerraformRequiredProvidersRule(), + Rule: NewOpentofuRequiredProvidersRule(), Message: "Missing version constraint for provider \"template\" in `required_providers`", Range: hcl.Range{ Filename: "module.tf", @@ -213,7 +213,7 @@ terraform { provider "template" {} `, Config: ` -rule "terraform_required_providers" { +rule "opentofu_required_providers" { enabled = true version = false @@ -236,7 +236,7 @@ provider "template" {} `, Expected: helper.Issues{ { - Rule: NewTerraformRequiredProvidersRule(), + Rule: NewOpentofuRequiredProvidersRule(), Message: "Missing `source` for provider \"template\" in `required_providers`", Range: hcl.Range{ Filename: "module.tf", @@ -278,7 +278,7 @@ terraform { provider "template" {} `, Config: ` -rule "terraform_required_providers" { +rule "opentofu_required_providers" { enabled = true source = false @@ -299,7 +299,7 @@ provider "template" {} `, Expected: helper.Issues{ { - Rule: NewTerraformRequiredProvidersRule(), + Rule: NewOpentofuRequiredProvidersRule(), Message: "Missing `source` for provider \"template\" in `required_providers`", Range: hcl.Range{ Filename: "module.tf", @@ -314,7 +314,7 @@ provider "template" {} }, }, { - Rule: NewTerraformRequiredProvidersRule(), + Rule: NewOpentofuRequiredProvidersRule(), Message: "Missing version constraint for provider \"template\" in `required_providers`", Range: hcl.Range{ Filename: "module.tf", @@ -350,7 +350,7 @@ provider "template" { `, Expected: helper.Issues{ { - Rule: NewTerraformRequiredProvidersRule(), + Rule: NewOpentofuRequiredProvidersRule(), Message: "Missing version constraint for provider \"template\" in `required_providers`", Range: hcl.Range{ Filename: "module.tf", @@ -384,7 +384,7 @@ provider "template" { `, Expected: helper.Issues{ { - Rule: NewTerraformRequiredProvidersRule(), + Rule: NewOpentofuRequiredProvidersRule(), Message: "provider version constraint should be specified via `required_providers`", Range: hcl.Range{ Filename: "module.tf", @@ -438,7 +438,7 @@ provider "template" { `, Expected: helper.Issues{ { - Rule: NewTerraformRequiredProvidersRule(), + Rule: NewOpentofuRequiredProvidersRule(), Message: "provider version constraint should be specified via `required_providers`", Range: hcl.Range{ Filename: "module.tf", @@ -491,7 +491,7 @@ resource "google_compute_instance" "foo" { }`, Expected: helper.Issues{ { - Rule: NewTerraformRequiredProvidersRule(), + Rule: NewOpentofuRequiredProvidersRule(), Message: "Missing version constraint for provider \"google-beta\" in `required_providers`", Range: hcl.Range{ Filename: "module.tf", @@ -523,7 +523,7 @@ resource "google_compute_instance" "foo" { }`, Expected: helper.Issues{ { - Rule: NewTerraformRequiredProvidersRule(), + Rule: NewOpentofuRequiredProvidersRule(), Message: "Missing version constraint for provider \"google-beta\" in `required_providers`", Range: hcl.Range{ Filename: "module.tf", @@ -555,7 +555,7 @@ resource "google_compute_instance" "foo" { JSON: true, Expected: helper.Issues{ { - Rule: NewTerraformRequiredProvidersRule(), + Rule: NewOpentofuRequiredProvidersRule(), Message: "Legacy version constraint for provider \"template\" in `required_providers`", Range: hcl.Range{ Filename: "module.tf.json", @@ -579,7 +579,7 @@ output "foo" { }`, Expected: helper.Issues{ { - Rule: NewTerraformRequiredProvidersRule(), + Rule: NewOpentofuRequiredProvidersRule(), Message: "Missing version constraint for provider \"time\" in `required_providers`", Range: hcl.Range{ Filename: "module.tf", @@ -620,7 +620,7 @@ terraform { `, Expected: helper.Issues{ { - Rule: NewTerraformRequiredProvidersRule(), + Rule: NewOpentofuRequiredProvidersRule(), Message: "Legacy version constraint for provider \"template\" in `required_providers`", Range: hcl.Range{ Filename: "module.tf", @@ -635,7 +635,7 @@ terraform { }, }, { - Rule: NewTerraformRequiredProvidersRule(), + Rule: NewOpentofuRequiredProvidersRule(), Message: "Legacy version constraint for provider \"aws\" in `required_providers`", Range: hcl.Range{ Filename: "module.tf", @@ -650,7 +650,7 @@ terraform { }, }, { - Rule: NewTerraformRequiredProvidersRule(), + Rule: NewOpentofuRequiredProvidersRule(), Message: "Legacy version constraint for provider \"google\" in `required_providers`", Range: hcl.Range{ Filename: "module.tf", @@ -698,7 +698,7 @@ terraform { }, } - rule := NewTerraformRequiredProvidersRule() + rule := NewOpentofuRequiredProvidersRule() for _, tc := range cases { t.Run(tc.Name, func(t *testing.T) { diff --git a/rules/terraform_required_version.go b/rules/opentofu_required_version.go similarity index 73% rename from rules/terraform_required_version.go rename to rules/opentofu_required_version.go index 34f1367..dfbec0a 100644 --- a/rules/terraform_required_version.go +++ b/rules/opentofu_required_version.go @@ -3,44 +3,44 @@ package rules import ( "path/filepath" + "github.com/diofeher/tflint-ruleset-opentofu/project" "github.com/hashicorp/hcl/v2" "github.com/terraform-linters/tflint-plugin-sdk/hclext" "github.com/terraform-linters/tflint-plugin-sdk/tflint" - "github.com/terraform-linters/tflint-ruleset-terraform/project" ) -// TerraformRequiredVersionRule checks whether a terraform version has required_version attribute -type TerraformRequiredVersionRule struct { +// OpentofuRequiredVersionRule checks whether a terraform version has required_version attribute +type OpentofuRequiredVersionRule struct { tflint.DefaultRule } -// NewTerraformRequiredVersionRule returns new rule with default attributes -func NewTerraformRequiredVersionRule() *TerraformRequiredVersionRule { - return &TerraformRequiredVersionRule{} +// NewOpentofuRequiredVersionRule returns new rule with default attributes +func NewOpentofuRequiredVersionRule() *OpentofuRequiredVersionRule { + return &OpentofuRequiredVersionRule{} } // Name returns the rule name -func (r *TerraformRequiredVersionRule) Name() string { - return "terraform_required_version" +func (r *OpentofuRequiredVersionRule) Name() string { + return "opentofu_required_version" } // Enabled returns whether the rule is enabled by default -func (r *TerraformRequiredVersionRule) Enabled() bool { +func (r *OpentofuRequiredVersionRule) Enabled() bool { return true } // Severity returns the rule severity -func (r *TerraformRequiredVersionRule) Severity() tflint.Severity { +func (r *OpentofuRequiredVersionRule) Severity() tflint.Severity { return tflint.WARNING } // Link returns the rule reference link -func (r *TerraformRequiredVersionRule) Link() string { +func (r *OpentofuRequiredVersionRule) Link() string { return project.ReferenceLink(r.Name()) } // Check Checks whether required_version is set -func (r *TerraformRequiredVersionRule) Check(runner tflint.Runner) error { +func (r *OpentofuRequiredVersionRule) Check(runner tflint.Runner) error { path, err := runner.GetModulePath() if err != nil { return err @@ -55,7 +55,7 @@ func (r *TerraformRequiredVersionRule) Check(runner tflint.Runner) error { return err } if len(files) == 0 { - // This rule does not run on non-Terraform directory. + // This rule does not run on non-Opentofu directory. return nil } @@ -125,7 +125,7 @@ func (r *TerraformRequiredVersionRule) Check(runner tflint.Runner) error { } // emitIssue emits issue for missing terraform require version -func (r *TerraformRequiredVersionRule) emitIssue(missingRange hcl.Range, runner tflint.Runner) error { +func (r *OpentofuRequiredVersionRule) emitIssue(missingRange hcl.Range, runner tflint.Runner) error { return runner.EmitIssue( r, `terraform "required_version" attribute is required`, diff --git a/rules/terraform_required_version_test.go b/rules/opentofu_required_version_test.go similarity index 88% rename from rules/terraform_required_version_test.go rename to rules/opentofu_required_version_test.go index fa540da..dfad97e 100644 --- a/rules/terraform_required_version_test.go +++ b/rules/opentofu_required_version_test.go @@ -8,7 +8,7 @@ import ( "github.com/terraform-linters/tflint-plugin-sdk/helper" ) -func Test_TerraformRequiredVersionRule(t *testing.T) { +func Test_OpentofuRequiredVersionRule(t *testing.T) { cases := []struct { Name string Content string @@ -25,7 +25,7 @@ terraform {} `, Expected: helper.Issues{ { - Rule: NewTerraformRequiredVersionRule(), + Rule: NewOpentofuRequiredVersionRule(), Message: "terraform \"required_version\" attribute is required", Range: hcl.Range{ Filename: "module.tf", @@ -75,7 +75,7 @@ locals { `, Expected: helper.Issues{ { - Rule: NewTerraformRequiredVersionRule(), + Rule: NewOpentofuRequiredVersionRule(), Message: "terraform \"required_version\" attribute is required", Range: hcl.Range{ Filename: "module.tf", @@ -93,7 +93,7 @@ locals { }, } - rule := NewTerraformRequiredVersionRule() + rule := NewOpentofuRequiredVersionRule() for _, tc := range cases { t.Run(tc.Name, func(t *testing.T) { @@ -112,7 +112,7 @@ locals { } } -func Test_TerraformRequiredVersionRuleMultipleFiles(t *testing.T) { +func Test_OpentofuRequiredVersionRuleMultipleFiles(t *testing.T) { cases := []struct { Name string Files []string @@ -123,7 +123,7 @@ func Test_TerraformRequiredVersionRuleMultipleFiles(t *testing.T) { Files: []string{"modules/foo/main.tf", "modules/foo/terraform.tf"}, Expected: helper.Issues{ { - Rule: NewTerraformRequiredVersionRule(), + Rule: NewOpentofuRequiredVersionRule(), Message: "terraform \"required_version\" attribute is required", Range: hcl.Range{ Filename: filepath.FromSlash("modules/foo/terraform.tf"), @@ -144,7 +144,7 @@ func Test_TerraformRequiredVersionRuleMultipleFiles(t *testing.T) { Files: []string{"modules/foo/outputs.tf", "modules/foo/main.tf", "modules/foo/variables.tf"}, Expected: helper.Issues{ { - Rule: NewTerraformRequiredVersionRule(), + Rule: NewOpentofuRequiredVersionRule(), Message: "terraform \"required_version\" attribute is required", Range: hcl.Range{ Filename: filepath.FromSlash("modules/foo/main.tf"), @@ -165,7 +165,7 @@ func Test_TerraformRequiredVersionRuleMultipleFiles(t *testing.T) { Files: []string{"modules/foo/variables.tf", "modules/foo/outputs.tf"}, Expected: helper.Issues{ { - Rule: NewTerraformRequiredVersionRule(), + Rule: NewOpentofuRequiredVersionRule(), Message: "terraform \"required_version\" attribute is required", Range: hcl.Range{ Filename: filepath.FromSlash("modules/foo/terraform.tf"), @@ -175,7 +175,7 @@ func Test_TerraformRequiredVersionRuleMultipleFiles(t *testing.T) { }, } - rule := NewTerraformRequiredVersionRule() + rule := NewOpentofuRequiredVersionRule() for _, tc := range cases { t.Run(tc.Name, func(t *testing.T) { diff --git a/rules/terraform_standard_module_structure.go b/rules/opentofu_standard_module_structure.go similarity index 74% rename from rules/terraform_standard_module_structure.go rename to rules/opentofu_standard_module_structure.go index bb2a278..d205dc5 100644 --- a/rules/terraform_standard_module_structure.go +++ b/rules/opentofu_standard_module_structure.go @@ -4,10 +4,10 @@ import ( "fmt" "path/filepath" + "github.com/diofeher/tflint-ruleset-opentofu/project" "github.com/hashicorp/hcl/v2" "github.com/terraform-linters/tflint-plugin-sdk/hclext" "github.com/terraform-linters/tflint-plugin-sdk/tflint" - "github.com/terraform-linters/tflint-ruleset-terraform/project" ) const ( @@ -16,38 +16,38 @@ const ( filenameOutputs = "outputs.tf" ) -// TerraformStandardModuleStructureRule checks whether modules adhere to Terraform's standard module structure -type TerraformStandardModuleStructureRule struct { +// OpentofuStandardModuleStructureRule checks whether modules adhere to Opentofu's standard module structure +type OpentofuStandardModuleStructureRule struct { tflint.DefaultRule } -// NewTerraformStandardModuleStructureRule returns a new rule -func NewTerraformStandardModuleStructureRule() *TerraformStandardModuleStructureRule { - return &TerraformStandardModuleStructureRule{} +// NewOpentofuStandardModuleStructureRule returns a new rule +func NewOpentofuStandardModuleStructureRule() *OpentofuStandardModuleStructureRule { + return &OpentofuStandardModuleStructureRule{} } // Name returns the rule name -func (r *TerraformStandardModuleStructureRule) Name() string { - return "terraform_standard_module_structure" +func (r *OpentofuStandardModuleStructureRule) Name() string { + return "opentofu_standard_module_structure" } // Enabled returns whether the rule is enabled by default -func (r *TerraformStandardModuleStructureRule) Enabled() bool { +func (r *OpentofuStandardModuleStructureRule) Enabled() bool { return true } // Severity returns the rule severity -func (r *TerraformStandardModuleStructureRule) Severity() tflint.Severity { +func (r *OpentofuStandardModuleStructureRule) Severity() tflint.Severity { return tflint.WARNING } // Link returns the rule reference link -func (r *TerraformStandardModuleStructureRule) Link() string { +func (r *OpentofuStandardModuleStructureRule) Link() string { return project.ReferenceLink(r.Name()) } // Check emits errors for any missing files and any block types that are included in the wrong file -func (r *TerraformStandardModuleStructureRule) Check(runner tflint.Runner) error { +func (r *OpentofuStandardModuleStructureRule) Check(runner tflint.Runner) error { path, err := runner.GetModulePath() if err != nil { return err @@ -62,7 +62,7 @@ func (r *TerraformStandardModuleStructureRule) Check(runner tflint.Runner) error return err } if len(files) == 0 { - // This rule does not run on non-Terraform directory. + // This rule does not run on non-Opentofu directory. return nil } @@ -99,7 +99,7 @@ func (r *TerraformStandardModuleStructureRule) Check(runner tflint.Runner) error return nil } -func (r *TerraformStandardModuleStructureRule) checkFiles(runner tflint.Runner, blocks hclext.Blocks) error { +func (r *OpentofuStandardModuleStructureRule) checkFiles(runner tflint.Runner, blocks hclext.Blocks) error { onlyJSON, err := r.onlyJSON(runner) if err != nil { return err @@ -161,7 +161,7 @@ func (r *TerraformStandardModuleStructureRule) checkFiles(runner tflint.Runner, return nil } -func (r *TerraformStandardModuleStructureRule) checkVariables(runner tflint.Runner, variables hclext.Blocks) error { +func (r *OpentofuStandardModuleStructureRule) checkVariables(runner tflint.Runner, variables hclext.Blocks) error { for _, variable := range variables { if filename := variable.DefRange.Filename; r.shouldMove(filename, filenameVariables) { if err := runner.EmitIssue( @@ -176,7 +176,7 @@ func (r *TerraformStandardModuleStructureRule) checkVariables(runner tflint.Runn return nil } -func (r *TerraformStandardModuleStructureRule) checkOutputs(runner tflint.Runner, outputs hclext.Blocks) error { +func (r *OpentofuStandardModuleStructureRule) checkOutputs(runner tflint.Runner, outputs hclext.Blocks) error { for _, output := range outputs { if filename := output.DefRange.Filename; r.shouldMove(filename, filenameOutputs) { if err := runner.EmitIssue( @@ -191,7 +191,7 @@ func (r *TerraformStandardModuleStructureRule) checkOutputs(runner tflint.Runner return nil } -func (r *TerraformStandardModuleStructureRule) onlyJSON(runner tflint.Runner) (bool, error) { +func (r *OpentofuStandardModuleStructureRule) onlyJSON(runner tflint.Runner) (bool, error) { files, err := runner.GetFiles() if err != nil { return false, err @@ -210,7 +210,7 @@ func (r *TerraformStandardModuleStructureRule) onlyJSON(runner tflint.Runner) (b return true, nil } -func (r *TerraformStandardModuleStructureRule) shouldMove(path string, expected string) bool { +func (r *OpentofuStandardModuleStructureRule) shouldMove(path string, expected string) bool { // json files are likely generated and conventional filenames do not apply if filepath.Ext(path) == ".json" { return false diff --git a/rules/terraform_standard_module_structure_test.go b/rules/opentofu_standard_module_structure_test.go similarity index 86% rename from rules/terraform_standard_module_structure_test.go rename to rules/opentofu_standard_module_structure_test.go index 24150fe..d9f2288 100644 --- a/rules/terraform_standard_module_structure_test.go +++ b/rules/opentofu_standard_module_structure_test.go @@ -8,7 +8,7 @@ import ( "github.com/terraform-linters/tflint-plugin-sdk/helper" ) -func Test_TerraformStandardModuleStructureRule(t *testing.T) { +func Test_OpentofuStandardModuleStructureRule(t *testing.T) { cases := []struct { Name string Content map[string]string @@ -26,7 +26,7 @@ func Test_TerraformStandardModuleStructureRule(t *testing.T) { }, Expected: helper.Issues{ { - Rule: NewTerraformStandardModuleStructureRule(), + Rule: NewOpentofuStandardModuleStructureRule(), Message: "Module should include a main.tf file as the primary entrypoint", Range: hcl.Range{ Filename: "main.tf", @@ -34,7 +34,7 @@ func Test_TerraformStandardModuleStructureRule(t *testing.T) { }, }, { - Rule: NewTerraformStandardModuleStructureRule(), + Rule: NewOpentofuStandardModuleStructureRule(), Message: "Module should include an empty variables.tf file", Range: hcl.Range{ Filename: "variables.tf", @@ -42,7 +42,7 @@ func Test_TerraformStandardModuleStructureRule(t *testing.T) { }, }, { - Rule: NewTerraformStandardModuleStructureRule(), + Rule: NewOpentofuStandardModuleStructureRule(), Message: "Module should include an empty outputs.tf file", Range: hcl.Range{ Filename: "outputs.tf", @@ -61,7 +61,7 @@ variable "v" {} }, Expected: helper.Issues{ { - Rule: NewTerraformStandardModuleStructureRule(), + Rule: NewOpentofuStandardModuleStructureRule(), Message: "Module should include an empty outputs.tf file", Range: hcl.Range{ Filename: filepath.Join("foo", "outputs.tf"), @@ -81,7 +81,7 @@ variable "v" {} }, Expected: helper.Issues{ { - Rule: NewTerraformStandardModuleStructureRule(), + Rule: NewOpentofuStandardModuleStructureRule(), Message: `variable "v" should be moved from main.tf to variables.tf`, Range: hcl.Range{ Filename: "main.tf", @@ -108,7 +108,7 @@ output "o" { value = null } }, Expected: helper.Issues{ { - Rule: NewTerraformStandardModuleStructureRule(), + Rule: NewOpentofuStandardModuleStructureRule(), Message: `output "o" should be moved from main.tf to outputs.tf`, Range: hcl.Range{ Filename: "main.tf", @@ -147,7 +147,7 @@ output "o" { value = null } }, } - rule := NewTerraformStandardModuleStructureRule() + rule := NewOpentofuStandardModuleStructureRule() for _, tc := range cases { t.Run(tc.Name, func(t *testing.T) { diff --git a/rules/terraform_typed_variables.go b/rules/opentofu_typed_variables.go similarity index 65% rename from rules/terraform_typed_variables.go rename to rules/opentofu_typed_variables.go index 8c83397..5e630ae 100644 --- a/rules/terraform_typed_variables.go +++ b/rules/opentofu_typed_variables.go @@ -3,43 +3,43 @@ package rules import ( "fmt" + "github.com/diofeher/tflint-ruleset-opentofu/project" "github.com/terraform-linters/tflint-plugin-sdk/hclext" "github.com/terraform-linters/tflint-plugin-sdk/tflint" - "github.com/terraform-linters/tflint-ruleset-terraform/project" ) -// TerraformTypedVariablesRule checks whether variables have a type declared -type TerraformTypedVariablesRule struct { +// OpentofuTypedVariablesRule checks whether variables have a type declared +type OpentofuTypedVariablesRule struct { tflint.DefaultRule } -// NewTerraformTypedVariablesRule returns a new rule -func NewTerraformTypedVariablesRule() *TerraformTypedVariablesRule { - return &TerraformTypedVariablesRule{} +// NewOpentofuTypedVariablesRule returns a new rule +func NewOpentofuTypedVariablesRule() *OpentofuTypedVariablesRule { + return &OpentofuTypedVariablesRule{} } // Name returns the rule name -func (r *TerraformTypedVariablesRule) Name() string { - return "terraform_typed_variables" +func (r *OpentofuTypedVariablesRule) Name() string { + return "opentofu_typed_variables" } // Enabled returns whether the rule is enabled by default -func (r *TerraformTypedVariablesRule) Enabled() bool { +func (r *OpentofuTypedVariablesRule) Enabled() bool { return true } // Severity returns the rule severity -func (r *TerraformTypedVariablesRule) Severity() tflint.Severity { +func (r *OpentofuTypedVariablesRule) Severity() tflint.Severity { return tflint.WARNING } // Link returns the rule reference link -func (r *TerraformTypedVariablesRule) Link() string { +func (r *OpentofuTypedVariablesRule) Link() string { return project.ReferenceLink(r.Name()) } // Check checks whether variables have type -func (r *TerraformTypedVariablesRule) Check(runner tflint.Runner) error { +func (r *OpentofuTypedVariablesRule) Check(runner tflint.Runner) error { path, err := runner.GetModulePath() if err != nil { return err diff --git a/rules/terraform_typed_variables_test.go b/rules/opentofu_typed_variables_test.go similarity index 90% rename from rules/terraform_typed_variables_test.go rename to rules/opentofu_typed_variables_test.go index 11cbfa0..00765a1 100644 --- a/rules/terraform_typed_variables_test.go +++ b/rules/opentofu_typed_variables_test.go @@ -7,7 +7,7 @@ import ( "github.com/terraform-linters/tflint-plugin-sdk/helper" ) -func Test_TerraformTypedVariablesRule(t *testing.T) { +func Test_OpentofuTypedVariablesRule(t *testing.T) { cases := []struct { Name string Content string @@ -22,7 +22,7 @@ variable "no_type" { }`, Expected: helper.Issues{ { - Rule: NewTerraformTypedVariablesRule(), + Rule: NewOpentofuTypedVariablesRule(), Message: "`no_type` variable has no type", Range: hcl.Range{ Filename: "variables.tf", @@ -88,7 +88,7 @@ variable "any" { `, Expected: helper.Issues{ { - Rule: NewTerraformTypedVariablesRule(), + Rule: NewOpentofuTypedVariablesRule(), Message: "`no_type` variable has no type", Range: hcl.Range{ Filename: "variables.tf.json", @@ -100,7 +100,7 @@ variable "any" { }, } - rule := NewTerraformTypedVariablesRule() + rule := NewOpentofuTypedVariablesRule() for _, tc := range cases { t.Run(tc.Name, func(t *testing.T) { diff --git a/rules/terraform_unused_declarations.go b/rules/opentofu_unused_declarations.go similarity index 84% rename from rules/terraform_unused_declarations.go rename to rules/opentofu_unused_declarations.go index 3f657f5..184e985 100644 --- a/rules/terraform_unused_declarations.go +++ b/rules/opentofu_unused_declarations.go @@ -3,56 +3,56 @@ package rules import ( "fmt" + "github.com/diofeher/tflint-ruleset-opentofu/opentofu" + "github.com/diofeher/tflint-ruleset-opentofu/project" "github.com/hashicorp/hcl/v2" "github.com/hashicorp/hcl/v2/gohcl" "github.com/terraform-linters/tflint-plugin-sdk/hclext" "github.com/terraform-linters/tflint-plugin-sdk/terraform/addrs" "github.com/terraform-linters/tflint-plugin-sdk/terraform/lang" "github.com/terraform-linters/tflint-plugin-sdk/tflint" - "github.com/terraform-linters/tflint-ruleset-terraform/project" - "github.com/terraform-linters/tflint-ruleset-terraform/terraform" ) -// TerraformUnusedDeclarationsRule checks whether variables, data sources, or locals are declared but unused -type TerraformUnusedDeclarationsRule struct { +// OpentofuUnusedDeclarationsRule checks whether variables, data sources, or locals are declared but unused +type OpentofuUnusedDeclarationsRule struct { tflint.DefaultRule } type declarations struct { Variables map[string]*hclext.Block DataResources map[string]*hclext.Block - Locals map[string]*terraform.Local + Locals map[string]*opentofu.Local ProviderAliases map[string]*hclext.Block } -// NewTerraformUnusedDeclarationsRule returns a new rule -func NewTerraformUnusedDeclarationsRule() *TerraformUnusedDeclarationsRule { - return &TerraformUnusedDeclarationsRule{} +// NewOpentofuUnusedDeclarationsRule returns a new rule +func NewOpentofuUnusedDeclarationsRule() *OpentofuUnusedDeclarationsRule { + return &OpentofuUnusedDeclarationsRule{} } // Name returns the rule name -func (r *TerraformUnusedDeclarationsRule) Name() string { - return "terraform_unused_declarations" +func (r *OpentofuUnusedDeclarationsRule) Name() string { + return "opentofu_unused_declarations" } // Enabled returns whether the rule is enabled by default -func (r *TerraformUnusedDeclarationsRule) Enabled() bool { +func (r *OpentofuUnusedDeclarationsRule) Enabled() bool { return true } // Severity returns the rule severity -func (r *TerraformUnusedDeclarationsRule) Severity() tflint.Severity { +func (r *OpentofuUnusedDeclarationsRule) Severity() tflint.Severity { return tflint.WARNING } // Link returns the rule reference link -func (r *TerraformUnusedDeclarationsRule) Link() string { +func (r *OpentofuUnusedDeclarationsRule) Link() string { return project.ReferenceLink(r.Name()) } // Check emits issues for any variables, locals, and data sources that are declared but not used -func (r *TerraformUnusedDeclarationsRule) Check(rr tflint.Runner) error { - runner := rr.(*terraform.Runner) +func (r *OpentofuUnusedDeclarationsRule) Check(rr tflint.Runner) error { + runner := rr.(*opentofu.Runner) path, err := runner.GetModulePath() if err != nil { @@ -124,11 +124,11 @@ func (r *TerraformUnusedDeclarationsRule) Check(rr tflint.Runner) error { return nil } -func (r *TerraformUnusedDeclarationsRule) declarations(runner *terraform.Runner) (*declarations, error) { +func (r *OpentofuUnusedDeclarationsRule) declarations(runner *opentofu.Runner) (*declarations, error) { decl := &declarations{ Variables: map[string]*hclext.Block{}, DataResources: map[string]*hclext.Block{}, - Locals: map[string]*terraform.Local{}, + Locals: map[string]*opentofu.Local{}, ProviderAliases: map[string]*hclext.Block{}, } @@ -217,7 +217,7 @@ func (r *TerraformUnusedDeclarationsRule) declarations(runner *terraform.Runner) return decl, nil } -func (r *TerraformUnusedDeclarationsRule) checkForRefsInExpr(expr hcl.Expression, decl *declarations) { +func (r *OpentofuUnusedDeclarationsRule) checkForRefsInExpr(expr hcl.Expression, decl *declarations) { // Check for provider alias references (e.g., aws.west in provider = aws.west) if traversal, diags := hcl.AbsTraversalForExpr(expr); diags == nil && len(traversal) == 2 { // Provider aliases are referenced as . (2 parts) diff --git a/rules/terraform_unused_declarations_test.go b/rules/opentofu_unused_declarations_test.go similarity index 93% rename from rules/terraform_unused_declarations_test.go rename to rules/opentofu_unused_declarations_test.go index 86092e4..679efeb 100644 --- a/rules/terraform_unused_declarations_test.go +++ b/rules/opentofu_unused_declarations_test.go @@ -7,7 +7,7 @@ import ( "github.com/terraform-linters/tflint-plugin-sdk/helper" ) -func Test_TerraformUnusedDeclarationsRule(t *testing.T) { +func Test_OpentofuUnusedDeclarationsRule(t *testing.T) { cases := []struct { Name string Content string @@ -24,7 +24,7 @@ output "u" { value = var.used } `, Expected: helper.Issues{ { - Rule: NewTerraformUnusedDeclarationsRule(), + Rule: NewOpentofuUnusedDeclarationsRule(), Message: `variable "not_used" is declared but not used`, Range: hcl.Range{ Filename: "config.tf", @@ -47,7 +47,7 @@ output "u" { value = data.null_data_source.used } `, Expected: helper.Issues{ { - Rule: NewTerraformUnusedDeclarationsRule(), + Rule: NewOpentofuUnusedDeclarationsRule(), Message: `data "null_data_source" "not_used" is declared but not used`, Range: hcl.Range{ Filename: "config.tf", @@ -72,7 +72,7 @@ output "u" { value = local.used } `, Expected: helper.Issues{ { - Rule: NewTerraformUnusedDeclarationsRule(), + Rule: NewOpentofuUnusedDeclarationsRule(), Message: `local.not_used is declared but not used`, Range: hcl.Range{ Filename: "config.tf", @@ -191,7 +191,7 @@ variable "unused" { `, Expected: helper.Issues{ { - Rule: NewTerraformUnusedDeclarationsRule(), + Rule: NewOpentofuUnusedDeclarationsRule(), Message: `variable "unused" is declared but not used`, Range: hcl.Range{ Filename: "config.tf", @@ -212,7 +212,7 @@ check "unused" { `, Expected: helper.Issues{ { - Rule: NewTerraformUnusedDeclarationsRule(), + Rule: NewOpentofuUnusedDeclarationsRule(), Message: `data "null_data_source" "unused" is declared but not used`, Range: hcl.Range{ Filename: "config.tf", @@ -257,7 +257,7 @@ check "unused" { }`, Expected: helper.Issues{ { - Rule: NewTerraformUnusedDeclarationsRule(), + Rule: NewOpentofuUnusedDeclarationsRule(), Message: `variable "again" is declared but not used`, Range: hcl.Range{ Filename: "config.tf.json", @@ -278,7 +278,7 @@ provider "azurerm" { `, Expected: helper.Issues{ { - Rule: NewTerraformUnusedDeclarationsRule(), + Rule: NewOpentofuUnusedDeclarationsRule(), Message: `provider "azurerm" with alias "test_123" is declared but not used`, Range: hcl.Range{ Filename: "config.tf", @@ -395,7 +395,7 @@ resource "aws_instance" "example" { `, Expected: helper.Issues{ { - Rule: NewTerraformUnusedDeclarationsRule(), + Rule: NewOpentofuUnusedDeclarationsRule(), Message: `provider "aws" with alias "east" is declared but not used`, Range: hcl.Range{ Filename: "config.tf", @@ -419,7 +419,7 @@ resource "aws_instance" "example" { }, } - rule := NewTerraformUnusedDeclarationsRule() + rule := NewOpentofuUnusedDeclarationsRule() for _, tc := range cases { filename := "config.tf" diff --git a/rules/terraform_unused_required_providers.go b/rules/opentofu_unused_required_providers.go similarity index 67% rename from rules/terraform_unused_required_providers.go rename to rules/opentofu_unused_required_providers.go index b75b484..344bfee 100644 --- a/rules/terraform_unused_required_providers.go +++ b/rules/opentofu_unused_required_providers.go @@ -3,45 +3,45 @@ package rules import ( "fmt" + "github.com/diofeher/tflint-ruleset-opentofu/opentofu" + "github.com/diofeher/tflint-ruleset-opentofu/project" "github.com/hashicorp/hcl/v2" "github.com/terraform-linters/tflint-plugin-sdk/tflint" - "github.com/terraform-linters/tflint-ruleset-terraform/project" - "github.com/terraform-linters/tflint-ruleset-terraform/terraform" ) -// TerraformUnusedRequiredProvidersRule checks whether required providers are used in the module -type TerraformUnusedRequiredProvidersRule struct { +// OpentofuUnusedRequiredProvidersRule checks whether required providers are used in the module +type OpentofuUnusedRequiredProvidersRule struct { tflint.DefaultRule } -// NewTerraformUnusedRequiredProvidersRule returns new rule with default attributes -func NewTerraformUnusedRequiredProvidersRule() *TerraformUnusedRequiredProvidersRule { - return &TerraformUnusedRequiredProvidersRule{} +// NewOpentofuUnusedRequiredProvidersRule returns new rule with default attributes +func NewOpentofuUnusedRequiredProvidersRule() *OpentofuUnusedRequiredProvidersRule { + return &OpentofuUnusedRequiredProvidersRule{} } // Name returns the rule name -func (r *TerraformUnusedRequiredProvidersRule) Name() string { - return "terraform_unused_required_providers" +func (r *OpentofuUnusedRequiredProvidersRule) Name() string { + return "opentofu_unused_required_providers" } // Enabled returns whether the rule is enabled by default -func (r *TerraformUnusedRequiredProvidersRule) Enabled() bool { +func (r *OpentofuUnusedRequiredProvidersRule) Enabled() bool { return true } // Severity returns the rule severity -func (r *TerraformUnusedRequiredProvidersRule) Severity() tflint.Severity { +func (r *OpentofuUnusedRequiredProvidersRule) Severity() tflint.Severity { return tflint.WARNING } // Link returns the rule reference link -func (r *TerraformUnusedRequiredProvidersRule) Link() string { +func (r *OpentofuUnusedRequiredProvidersRule) Link() string { return project.ReferenceLink(r.Name()) } // Check checks whether required providers are used -func (r *TerraformUnusedRequiredProvidersRule) Check(rr tflint.Runner) error { - runner := rr.(*terraform.Runner) +func (r *OpentofuUnusedRequiredProvidersRule) Check(rr tflint.Runner) error { + runner := rr.(*opentofu.Runner) path, err := runner.GetModulePath() if err != nil { diff --git a/rules/terraform_unused_required_providers_test.go b/rules/opentofu_unused_required_providers_test.go similarity index 94% rename from rules/terraform_unused_required_providers_test.go rename to rules/opentofu_unused_required_providers_test.go index 3bf1b86..a3feab0 100644 --- a/rules/terraform_unused_required_providers_test.go +++ b/rules/opentofu_unused_required_providers_test.go @@ -7,7 +7,7 @@ import ( "github.com/terraform-linters/tflint-plugin-sdk/helper" ) -func Test_TerraformUnusedRequiredProvidersRule(t *testing.T) { +func Test_OpentofuUnusedRequiredProvidersRule(t *testing.T) { cases := []struct { Name string Content string @@ -159,7 +159,7 @@ func Test_TerraformUnusedRequiredProvidersRule(t *testing.T) { `, Expected: helper.Issues{ { - Rule: NewTerraformUnusedRequiredProvidersRule(), + Rule: NewOpentofuUnusedRequiredProvidersRule(), Message: "provider 'null' is declared in required_providers but not used by the module", Range: hcl.Range{ Filename: "module.tf", @@ -194,7 +194,7 @@ func Test_TerraformUnusedRequiredProvidersRule(t *testing.T) { `, Expected: helper.Issues{ { - Rule: NewTerraformUnusedRequiredProvidersRule(), + Rule: NewOpentofuUnusedRequiredProvidersRule(), Message: "provider 'null' is declared in required_providers but not used by the module", Range: hcl.Range{ Filename: "module.tf", @@ -226,7 +226,7 @@ func Test_TerraformUnusedRequiredProvidersRule(t *testing.T) { `, Expected: helper.Issues{ { - Rule: NewTerraformUnusedRequiredProvidersRule(), + Rule: NewOpentofuUnusedRequiredProvidersRule(), Message: "provider 'null' is declared in required_providers but not used by the module", Range: hcl.Range{ Filename: "module.tf", @@ -296,7 +296,7 @@ func Test_TerraformUnusedRequiredProvidersRule(t *testing.T) { `, Expected: helper.Issues{ { - Rule: NewTerraformUnusedRequiredProvidersRule(), + Rule: NewOpentofuUnusedRequiredProvidersRule(), Message: "provider 'aws' is declared in required_providers but not used by the module", Range: hcl.Range{ Filename: "module.tf", @@ -314,7 +314,7 @@ func Test_TerraformUnusedRequiredProvidersRule(t *testing.T) { }, } - rule := NewTerraformUnusedRequiredProvidersRule() + rule := NewOpentofuUnusedRequiredProvidersRule() for _, tc := range cases { t.Run(tc.Name, func(t *testing.T) { diff --git a/rules/terraform_workspace_remote.go b/rules/opentofu_workspace_remote.go similarity index 80% rename from rules/terraform_workspace_remote.go rename to rules/opentofu_workspace_remote.go index 24632a2..d428ef2 100644 --- a/rules/terraform_workspace_remote.go +++ b/rules/opentofu_workspace_remote.go @@ -1,6 +1,7 @@ package rules import ( + "github.com/diofeher/tflint-ruleset-opentofu/project" "github.com/hashicorp/go-version" "github.com/hashicorp/hcl/v2" "github.com/hashicorp/hcl/v2/hclsyntax" @@ -9,36 +10,35 @@ import ( "github.com/terraform-linters/tflint-plugin-sdk/terraform/addrs" "github.com/terraform-linters/tflint-plugin-sdk/terraform/lang" "github.com/terraform-linters/tflint-plugin-sdk/tflint" - "github.com/terraform-linters/tflint-ruleset-terraform/project" ) -// TerraformWorkspaceRemoteRule warns of the use of terraform.workspace with a remote backend -type TerraformWorkspaceRemoteRule struct { +// OpentofuWorkspaceRemoteRule warns of the use of terraform.workspace with a remote backend +type OpentofuWorkspaceRemoteRule struct { tflint.DefaultRule } -// NewTerraformWorkspaceRemoteRule return a new rule -func NewTerraformWorkspaceRemoteRule() *TerraformWorkspaceRemoteRule { - return &TerraformWorkspaceRemoteRule{} +// NewOpentofuWorkspaceRemoteRule return a new rule +func NewOpentofuWorkspaceRemoteRule() *OpentofuWorkspaceRemoteRule { + return &OpentofuWorkspaceRemoteRule{} } // Name returns the rule name -func (r *TerraformWorkspaceRemoteRule) Name() string { - return "terraform_workspace_remote" +func (r *OpentofuWorkspaceRemoteRule) Name() string { + return "opentofu_workspace_remote" } // Enabled returns whether the rule is enabled by default -func (r *TerraformWorkspaceRemoteRule) Enabled() bool { +func (r *OpentofuWorkspaceRemoteRule) Enabled() bool { return true } // Severity returns the rule severity -func (r *TerraformWorkspaceRemoteRule) Severity() tflint.Severity { +func (r *OpentofuWorkspaceRemoteRule) Severity() tflint.Severity { return tflint.WARNING } // Link returns the rule reference link -func (r *TerraformWorkspaceRemoteRule) Link() string { +func (r *OpentofuWorkspaceRemoteRule) Link() string { return project.ReferenceLink(r.Name()) } @@ -60,7 +60,7 @@ var tf10Versions = []*version.Version{ // Check checks for a "remote" backend and if found emits issues for // each use of terraform.workspace in an expression. -func (r *TerraformWorkspaceRemoteRule) Check(runner tflint.Runner) error { +func (r *OpentofuWorkspaceRemoteRule) Check(runner tflint.Runner) error { path, err := runner.GetModulePath() if err != nil { return err @@ -129,7 +129,7 @@ func (r *TerraformWorkspaceRemoteRule) Check(runner tflint.Runner) error { } diags := runner.WalkExpressions(tflint.ExprWalkFunc(func(expr hcl.Expression) hcl.Diagnostics { - return r.checkForTerraformWorkspaceInExpr(runner, expr) + return r.checkForOpentofuWorkspaceInExpr(runner, expr) })) if diags.HasErrors() { return diags @@ -137,7 +137,7 @@ func (r *TerraformWorkspaceRemoteRule) Check(runner tflint.Runner) error { return nil } -func (r *TerraformWorkspaceRemoteRule) checkForTerraformWorkspaceInExpr(runner tflint.Runner, expr hcl.Expression) hcl.Diagnostics { +func (r *OpentofuWorkspaceRemoteRule) checkForOpentofuWorkspaceInExpr(runner tflint.Runner, expr hcl.Expression) hcl.Diagnostics { _, isScopeTraversalExpr := expr.(*hclsyntax.ScopeTraversalExpr) if !isScopeTraversalExpr && !json.IsJSONExpression(expr) { return nil diff --git a/rules/terraform_workspace_remote_test.go b/rules/opentofu_workspace_remote_test.go similarity index 93% rename from rules/terraform_workspace_remote_test.go rename to rules/opentofu_workspace_remote_test.go index 2ad1f1f..4b7ce78 100644 --- a/rules/terraform_workspace_remote_test.go +++ b/rules/opentofu_workspace_remote_test.go @@ -7,7 +7,7 @@ import ( "github.com/terraform-linters/tflint-plugin-sdk/helper" ) -func Test_TerraformWorkspaceRemoteRule(t *testing.T) { +func Test_OpentofuWorkspaceRemoteRule(t *testing.T) { cases := []struct { Name string JSON bool @@ -28,7 +28,7 @@ resource "null_resource" "a" { }`, Expected: helper.Issues{ { - Rule: NewTerraformWorkspaceRemoteRule(), + Rule: NewOpentofuWorkspaceRemoteRule(), Message: "terraform.workspace should not be used with a 'remote' backend", Range: hcl.Range{ Filename: "config.tf", @@ -116,7 +116,7 @@ data "null_data_source" "a" { }`, Expected: helper.Issues{ { - Rule: NewTerraformWorkspaceRemoteRule(), + Rule: NewOpentofuWorkspaceRemoteRule(), Message: "terraform.workspace should not be used with a 'remote' backend", Range: hcl.Range{ Filename: "config.tf", @@ -139,7 +139,7 @@ module "a" { }`, Expected: helper.Issues{ { - Rule: NewTerraformWorkspaceRemoteRule(), + Rule: NewOpentofuWorkspaceRemoteRule(), Message: "terraform.workspace should not be used with a 'remote' backend", Range: hcl.Range{ Filename: "config.tf", @@ -163,7 +163,7 @@ provider "aws" { }`, Expected: helper.Issues{ { - Rule: NewTerraformWorkspaceRemoteRule(), + Rule: NewOpentofuWorkspaceRemoteRule(), Message: "terraform.workspace should not be used with a 'remote' backend", Range: hcl.Range{ Filename: "config.tf", @@ -185,7 +185,7 @@ locals { }`, Expected: helper.Issues{ { - Rule: NewTerraformWorkspaceRemoteRule(), + Rule: NewOpentofuWorkspaceRemoteRule(), Message: "terraform.workspace should not be used with a 'remote' backend", Range: hcl.Range{ Filename: "config.tf", @@ -207,7 +207,7 @@ output "o" { }`, Expected: helper.Issues{ { - Rule: NewTerraformWorkspaceRemoteRule(), + Rule: NewOpentofuWorkspaceRemoteRule(), Message: "terraform.workspace should not be used with a 'remote' backend", Range: hcl.Range{ Filename: "config.tf", @@ -272,7 +272,7 @@ resource "aws_instance" "foo" { }`, Expected: helper.Issues{ { - Rule: NewTerraformWorkspaceRemoteRule(), + Rule: NewOpentofuWorkspaceRemoteRule(), Message: "terraform.workspace should not be used with a 'remote' backend", Range: hcl.Range{ Filename: "config.tf.json", @@ -318,7 +318,7 @@ resource "null_resource" "a" { }, } - rule := NewTerraformWorkspaceRemoteRule() + rule := NewOpentofuWorkspaceRemoteRule() for _, tc := range cases { t.Run(tc.Name, func(t *testing.T) { diff --git a/rules/preset.go b/rules/preset.go index b325ac6..8003266 100644 --- a/rules/preset.go +++ b/rules/preset.go @@ -4,40 +4,40 @@ import "github.com/terraform-linters/tflint-plugin-sdk/tflint" var PresetRules = map[string][]tflint.Rule{ "all": { - NewTerraformCommentSyntaxRule(), - NewTerraformDeprecatedIndexRule(), - NewTerraformDeprecatedInterpolationRule(), - NewTerraformDeprecatedLookupRule(), - NewTerraformDocumentedOutputsRule(), - NewTerraformDocumentedVariablesRule(), - NewTerraformEmptyListEqualityRule(), - NewTerraformJSONSyntaxRule(), - NewTerraformMapDuplicateKeysRule(), - NewTerraformModulePinnedSourceRule(), - NewTerraformModuleShallowCloneRule(), - NewTerraformModuleVersionRule(), - NewTerraformNamingConventionRule(), - NewTerraformRequiredProvidersRule(), - NewTerraformRequiredVersionRule(), - NewTerraformStandardModuleStructureRule(), - NewTerraformTypedVariablesRule(), - NewTerraformUnusedDeclarationsRule(), - NewTerraformUnusedRequiredProvidersRule(), - NewTerraformWorkspaceRemoteRule(), + NewOpentofuCommentSyntaxRule(), + NewOpentofuDeprecatedIndexRule(), + NewOpentofuDeprecatedInterpolationRule(), + NewOpentofuDeprecatedLookupRule(), + NewOpentofuDocumentedOutputsRule(), + NewOpentofuDocumentedVariablesRule(), + NewOpentofuEmptyListEqualityRule(), + NewOpentofuJSONSyntaxRule(), + NewOpentofuMapDuplicateKeysRule(), + NewOpentofuModulePinnedSourceRule(), + NewOpentofuModuleShallowCloneRule(), + NewOpentofuModuleVersionRule(), + NewOpentofuNamingConventionRule(), + NewOpentofuRequiredProvidersRule(), + NewOpentofuRequiredVersionRule(), + NewOpentofuStandardModuleStructureRule(), + NewOpentofuTypedVariablesRule(), + NewOpentofuUnusedDeclarationsRule(), + NewOpentofuUnusedRequiredProvidersRule(), + NewOpentofuWorkspaceRemoteRule(), }, "recommended": { - NewTerraformDeprecatedIndexRule(), - NewTerraformDeprecatedInterpolationRule(), - NewTerraformDeprecatedLookupRule(), - NewTerraformEmptyListEqualityRule(), - NewTerraformJSONSyntaxRule(), - NewTerraformMapDuplicateKeysRule(), - NewTerraformModulePinnedSourceRule(), - NewTerraformModuleVersionRule(), - NewTerraformRequiredProvidersRule(), - NewTerraformRequiredVersionRule(), - NewTerraformTypedVariablesRule(), - NewTerraformUnusedDeclarationsRule(), - NewTerraformWorkspaceRemoteRule(), + NewOpentofuDeprecatedIndexRule(), + NewOpentofuDeprecatedInterpolationRule(), + NewOpentofuDeprecatedLookupRule(), + NewOpentofuEmptyListEqualityRule(), + NewOpentofuJSONSyntaxRule(), + NewOpentofuMapDuplicateKeysRule(), + NewOpentofuModulePinnedSourceRule(), + NewOpentofuModuleVersionRule(), + NewOpentofuRequiredProvidersRule(), + NewOpentofuRequiredVersionRule(), + NewOpentofuTypedVariablesRule(), + NewOpentofuUnusedDeclarationsRule(), + NewOpentofuWorkspaceRemoteRule(), }, } diff --git a/rules/rules_test.go b/rules/rules_test.go index c3467b9..8b528a5 100644 --- a/rules/rules_test.go +++ b/rules/rules_test.go @@ -3,10 +3,10 @@ package rules import ( "testing" + "github.com/diofeher/tflint-ruleset-opentofu/opentofu" "github.com/terraform-linters/tflint-plugin-sdk/helper" - "github.com/terraform-linters/tflint-ruleset-terraform/terraform" ) -func testRunner(t *testing.T, files map[string]string) *terraform.Runner { - return terraform.NewRunner(helper.TestRunner(t, files)) +func testRunner(t *testing.T, files map[string]string) *opentofu.Runner { + return opentofu.NewRunner(helper.TestRunner(t, files)) } diff --git a/terraform/terraform.go b/terraform/terraform.go deleted file mode 100644 index c919c5a..0000000 --- a/terraform/terraform.go +++ /dev/null @@ -1,134 +0,0 @@ -package terraform - -import ( - "github.com/hashicorp/go-version" - "github.com/hashicorp/hcl/v2" - "github.com/hashicorp/hcl/v2/gohcl" - "github.com/hashicorp/hcl/v2/hclsyntax" - "github.com/terraform-linters/tflint-plugin-sdk/hclext" -) - -// ModuleCall represents a "module" block. -type ModuleCall struct { - Name string - DefRange hcl.Range - Source string - SourceAttr *hclext.Attribute - Version version.Constraints - VersionAttr *hclext.Attribute -} - -// @see https://github.com/hashicorp/terraform/blob/v1.2.7/internal/configs/module_call.go#L36-L224 -func decodeModuleCall(block *hclext.Block) (*ModuleCall, hcl.Diagnostics) { - module := &ModuleCall{ - Name: block.Labels[0], - DefRange: block.DefRange, - } - diags := hcl.Diagnostics{} - - if source, exists := block.Body.Attributes["source"]; exists { - module.SourceAttr = source - sourceDiags := gohcl.DecodeExpression(source.Expr, nil, &module.Source) - diags = diags.Extend(sourceDiags) - } - - if versionAttr, exists := block.Body.Attributes["version"]; exists { - module.VersionAttr = versionAttr - - var versionVal string - versionDiags := gohcl.DecodeExpression(versionAttr.Expr, nil, &versionVal) - diags = diags.Extend(versionDiags) - if diags.HasErrors() { - return module, diags - } - - constraints, err := version.NewConstraint(versionVal) - if err != nil { - diags = append(diags, &hcl.Diagnostic{ - Severity: hcl.DiagError, - Summary: "Invalid version constraint", - Detail: "This string does not use correct version constraint syntax.", - Subject: versionAttr.Expr.Range().Ptr(), - }) - } - module.Version = constraints - } - - return module, diags -} - -// Local represents a single entry from a "locals" block. -type Local struct { - Name string - Attribute *hcl.Attribute - DefRange hcl.Range -} - -// ProviderRef represents a reference to a provider like `provider = google.europe` in a resource or module. -type ProviderRef struct { - Name string - DefRange hcl.Range -} - -// @see https://github.com/hashicorp/terraform/blob/v1.2.7/internal/configs/resource.go#L624-L695 -func decodeProviderRef(expr hcl.Expression, defRange hcl.Range) (*ProviderRef, hcl.Diagnostics) { - expr, diags := shimTraversalInString(expr) - if diags.HasErrors() { - return nil, diags - } - - traversal, diags := hcl.AbsTraversalForExpr(expr) - if diags.HasErrors() { - return nil, diags - } - - return &ProviderRef{ - Name: traversal.RootName(), - DefRange: defRange, - }, nil -} - -// @see https://github.com/hashicorp/terraform/blob/v1.2.5/internal/configs/compat_shim.go#L34 -func shimTraversalInString(expr hcl.Expression) (hcl.Expression, hcl.Diagnostics) { - // ObjectConsKeyExpr is a special wrapper type used for keys on object - // constructors to deal with the fact that naked identifiers are normally - // handled as "bareword" strings rather than as variable references. Since - // we know we're interpreting as a traversal anyway (and thus it won't - // matter whether it's a string or an identifier) we can safely just unwrap - // here and then process whatever we find inside as normal. - if ocke, ok := expr.(*hclsyntax.ObjectConsKeyExpr); ok { - expr = ocke.Wrapped - } - - if _, ok := expr.(*hclsyntax.TemplateExpr); !ok { - return expr, nil - } - - strVal, diags := expr.Value(nil) - if diags.HasErrors() || strVal.IsNull() || !strVal.IsKnown() { - // Since we're not even able to attempt a shim here, we'll discard - // the diagnostics we saw so far and let the caller's own error - // handling take care of reporting the invalid expression. - return expr, nil - } - - // The position handling here isn't _quite_ right because it won't - // take into account any escape sequences in the literal string, but - // it should be close enough for any error reporting to make sense. - srcRange := expr.Range() - startPos := srcRange.Start // copy - startPos.Column++ // skip initial quote - startPos.Byte++ // skip initial quote - - traversal, tDiags := hclsyntax.ParseTraversalAbs( - []byte(strVal.AsString()), - srcRange.Filename, - startPos, - ) - diags = append(diags, tDiags...) - - return &hclsyntax.ScopeTraversalExpr{ - Traversal: traversal, - SrcRange: srcRange, - }, diags -}