Repository: terraform-docs/terraform-docs (go)

Issue:
Adding first-class support for `.tofu` files.
### What problem are you facing?

OpenTofu is adding support for `.tofu` files in addition to `.tf` files. Terraform only supports `.tf` files, and OpenTofu will support both. This will allow users to have tool-specific configurations in places where it matters (e.g., provider functions landing in Terraform 1.8 and OpenTofu 1.7, and wanting to gate-keep the CLI tool by version).

If two files have the same name with each file extension (e.g., `main.tf` and `main.tofu`), OpenTofu will execute `main.tofu` and NOT `main.tf`, while Terraform will execute `main.tf`.

It's still all HCL syntax in these files.

### How could terraform-docs help solve your problem?

I don't believe that generating two sets of documentation is the right approach — one for Terraform, and one for OpenTofu. Instead, I believe that in cases where `.tofu` files exist, the OpenTofu configuration should be provided in tandem with the Terraform configuration.

For example, in the JSON output, `requirements` is an array of objects, with each object defining `name` and `version`. Perhaps this could be modified to support `"name": "opentofu"` with its version, and for any providers/modules, there is a new `tool` key which contains an array of tool identifiers (e.g., `terraform` and `opentofu`).

This would allow flexibility in the future in case (God forbid) another fork happens in the community. This also _shouldn't_ (AFAIK) require any backwards-incompatible changes.

This would also mean that for [content](https://terraform-docs.io/user-guide/configuration/content/), it would be useful to define `.IsTerraform` and `.IsOpenTofu` variables, so that users can adjust the examples or other custom documentation to more specifically target each tool.

Ways for readers to switch between the two flavors of tooling _could_ be either a tabbed interface (and a nice touch would be like many API documentation websites where if you select a preferred language in a tabbed interface to view those examples, that all other examples switch to that same language too) — OR something simpler, but less "nice" like a `<select>` HTML field where you can select which version to view.

Pull request description:
add support for .tofu files
<!--
Thank you for helping to improve terraform-docs!

Please read through https://git.io/JtEzg if this is your first time opening a
terraform-docs pull request. Find us in https://slack.terraform-docs.io/messages/dev if
you need any help contributing.
-->

### Description of your changes

Adds .tofu to permitted file formats.

<!--
Briefly describe what this pull request does. Be sure to direct your reviewers'
attention to anything that needs special consideration.

We love pull requests that resolve an open terraform-docs issue. If yours does, you
can uncomment the below line to indicate which issue your PR fixes, for example
"Fixes #500":
-->

resolves #811 

I have:

- [x] Read and followed terraform-docs' [contribution process].
- [x] All tests pass when I run `make test`.

### How has this code been tested

tests pass.

<!--
Before reviewers can be confident in the correctness of this pull request, it
needs to tested and shown to be correct. Briefly describe the testing that has
already been done or which is planned for this change.
-->

[contribution process]: https://git.io/JtEzg


Patch:
diff --git a/docs/user-guide/configuration/footer-from.md b/docs/user-guide/configuration/footer-from.md
index 6a425fa..960141b 100644
--- a/docs/user-guide/configuration/footer-from.md
+++ b/docs/user-guide/configuration/footer-from.md
@@ -11,14 +11,14 @@ toc: true
 Since `v0.12.0`
 
 Relative path to a file to extract footer for the generated output from. Supported
-file formats are `.adoc`, `.md`, `.tf`, and `.txt`.
+file formats are `.adoc`, `.md`, `.tf`, `.tofu`, and `.txt`.
 
 {{< alert type="info" >}}
 The whole file content is being extracted as module footer when extracting from
 `.adoc`, `.md`, or `.txt`.
 {{< /alert >}}
 
-To extract footer from `.tf` file you need to use following javascript, c, or java
+To extract footer from `.tf` or `.tofu` file you need to use following javascript, c, or java
 like multi-line comment.
 
 ```tf
@@ -37,7 +37,7 @@ resource "foo" "bar" { ... }
 ```
 
 {{< alert type="info" >}}
-This comment must start at the immediate first line of the `.tf` file
+This comment must start at the immediate first line of the `.tf` or `.tofu` file
 before any `resource`, `variable`, `module`, etc.
 {{< /alert >}}
 
diff --git a/docs/user-guide/configuration/header-from.md b/docs/user-guide/configuration/header-from.md
index b5f016e..2ab4a0b 100644
--- a/docs/user-guide/configuration/header-from.md
+++ b/docs/user-guide/configuration/header-from.md
@@ -11,14 +11,14 @@ toc: true
 Since `v0.10.0`
 
 Relative path to a file to extract header for the generated output from. Supported
-file formats are `.adoc`, `.md`, `.tf`, and `.txt`.
+file formats are `.adoc`, `.md`, `.tf`, `.tofu`, and `.txt`.
 
 {{< alert type="info" >}}
 The whole file content is being extracted as module header when extracting from
 `.adoc`, `.md`, or `.txt`.
 {{< /alert >}}
 
-To extract header from `.tf` file you need to use following javascript, c, or java
+To extract header from `.tf` or `.tofu` file you need to use following javascript, c, or java
 like multi-line comment.
 
 ```tf
@@ -37,7 +37,7 @@ resource "foo" "bar" { ... }
 ```
 
 {{< alert type="info" >}}
-This comment must start at the immediate first line of the `.tf` file
+This comment must start at the immediate first line of the `.tf` or `.tofu` file
 before any `resource`, `variable`, `module`, etc.
 {{< /alert >}}
 
diff --git a/terraform/load.go b/terraform/load.go
index fea188b..55dfc72 100644
--- a/terraform/load.go
+++ b/terraform/load.go
@@ -108,10 +108,10 @@ func isFileFormatSupported(filename string, section string) (bool, error) {
 		return false, fmt.Errorf("--%s-from value is missing", section)
 	}
 	switch getFileFormat(filename) {
-	case ".adoc", ".md", ".tf", ".txt":
+	case ".adoc", ".md", ".tf", ".tofu", ".txt":
 		return true, nil
 	}
-	return false, fmt.Errorf("only .adoc, .md, .tf, and .txt formats are supported to read %s from", section)
+	return false, fmt.Errorf("only .adoc, .md, .tf, .tofu and .txt formats are supported to read %s from", section)
 }
 
 func loadHeader(config *print.Config) (string, error) {
@@ -146,7 +146,8 @@ func loadSection(config *print.Config, file string, section string) (string, err
 		}
 		return "", err // user explicitly asked for a file which doesn't exist
 	}
-	if getFileFormat(file) != ".tf" {
+	format := getFileFormat(file)
+	if format != ".tf" && format != ".tofu" {
 		content, err := os.ReadFile(filepath.Clean(filename))
 		if err != nil {
 			return "", err


Test patch:
diff --git a/terraform/load_test.go b/terraform/load_test.go
index 89a87eb..563770f 100644
--- a/terraform/load_test.go
+++ b/terraform/load_test.go
@@ -161,6 +161,14 @@ func TestIsFileFormatSupported(t *testing.T) {
 			errText:  "",
 			section:  "header",
 		},
+		{
+			name:     "is file format supported",
+			filename: "main.tofu",
+			expected: true,
+			wantErr:  false,
+			errText:  "",
+			section:  "header",
+		},
 		{
 			name:     "is file format supported",
 			filename: "main.txt",
@@ -174,7 +182,7 @@ func TestIsFileFormatSupported(t *testing.T) {
 			filename: "main.doc",
 			expected: false,
 			wantErr:  true,
-			errText:  "only .adoc, .md, .tf, and .txt formats are supported to read header from",
+			errText:  "only .adoc, .md, .tf, .tofu and .txt formats are supported to read header from",
 			section:  "header",
 		},
 		{
@@ -189,7 +197,7 @@ func TestIsFileFormatSupported(t *testing.T) {
 			filename: "main.doc",
 			expected: false,
 			wantErr:  true,
-			errText:  "only .adoc, .md, .tf, and .txt formats are supported to read footer from",
+			errText:  "only .adoc, .md, .tf, .tofu and .txt formats are supported to read footer from",
 			section:  "footer",
 		},
 		{
@@ -405,7 +413,7 @@ func TestLoadSections(t *testing.T) {
 			file:     "wrong-formate.docx",
 			expected: "",
 			wantErr:  true,
-			errText:  "only .adoc, .md, .tf, and .txt formats are supported to read footer from",
+			errText:  "only .adoc, .md, .tf, .tofu and .txt formats are supported to read footer from",
 			section:  "footer",
 		},
 		{