mirror of
https://github.com/terraform-docs/terraform-docs.git
synced 2026-03-27 04:48:33 +07:00
feat: ignore outputs, providers, resources with comments
Prepend any type of resource, including `resource`, `data`, `module`, `variable`, and `output` with a comment including "terraform-docs-ignore" to exclude it from the generated output. Signed-off-by: Khosrow Moossavi <khos2ow@gmail.com>
This commit is contained in:
@@ -189,7 +189,7 @@ func loadInputs(tfmodule *tfconfig.Module, config *print.Config) ([]*Input, []*I
|
||||
for _, input := range tfmodule.Variables {
|
||||
comments := loadComments(input.Pos.Filename, input.Pos.Line)
|
||||
|
||||
// Skip over inputs that are marked as being ignored
|
||||
// skip over inputs that are marked as being ignored
|
||||
if strings.Contains(comments, "terraform-docs-ignore") {
|
||||
continue
|
||||
}
|
||||
@@ -252,13 +252,20 @@ func loadModulecalls(tfmodule *tfconfig.Module, config *print.Config) []*ModuleC
|
||||
var source, version string
|
||||
|
||||
for _, m := range tfmodule.ModuleCalls {
|
||||
source, version = formatSource(m.Source, m.Version)
|
||||
comments := loadComments(m.Pos.Filename, m.Pos.Line)
|
||||
|
||||
// skip over modules that are marked as being ignored
|
||||
if strings.Contains(comments, "terraform-docs-ignore") {
|
||||
continue
|
||||
}
|
||||
|
||||
description := ""
|
||||
if config.Settings.ReadComments {
|
||||
description = loadComments(m.Pos.Filename, m.Pos.Line)
|
||||
description = comments
|
||||
}
|
||||
|
||||
source, version = formatSource(m.Source, m.Version)
|
||||
|
||||
modules = append(modules, &ModuleCall{
|
||||
Name: m.Name,
|
||||
Source: source,
|
||||
@@ -284,10 +291,17 @@ func loadOutputs(tfmodule *tfconfig.Module, config *print.Config) ([]*Output, er
|
||||
}
|
||||
}
|
||||
for _, o := range tfmodule.Outputs {
|
||||
comments := loadComments(o.Pos.Filename, o.Pos.Line)
|
||||
|
||||
// skip over outputs that are marked as being ignored
|
||||
if strings.Contains(comments, "terraform-docs-ignore") {
|
||||
continue
|
||||
}
|
||||
|
||||
// convert CRLF to LF early on (https://github.com/terraform-docs/terraform-docs/issues/584)
|
||||
description := strings.ReplaceAll(o.Description, "\r\n", "\n")
|
||||
if description == "" && config.Settings.ReadComments {
|
||||
description = loadComments(o.Pos.Filename, o.Pos.Line)
|
||||
description = comments
|
||||
}
|
||||
|
||||
output := &Output{
|
||||
@@ -337,7 +351,11 @@ func loadOutputValues(config *print.Config) (map[string]*output, error) {
|
||||
return terraformOutputs, err
|
||||
}
|
||||
|
||||
func loadProviders(tfmodule *tfconfig.Module, config *print.Config) []*Provider {
|
||||
func loadProviders(tfmodule *tfconfig.Module, config *print.Config) []*Provider { //nolint:gocyclo
|
||||
// NOTE(khos2ow): this function is over our cyclomatic complexity goal.
|
||||
// Be wary when adding branches, and look for functionality that could
|
||||
// be reasonably moved into an injected dependency.
|
||||
|
||||
type provider struct {
|
||||
Name string `hcl:"name,label"`
|
||||
Version string `hcl:"version"`
|
||||
@@ -367,6 +385,13 @@ func loadProviders(tfmodule *tfconfig.Module, config *print.Config) []*Provider
|
||||
|
||||
for _, resource := range resources {
|
||||
for _, r := range resource {
|
||||
comments := loadComments(r.Pos.Filename, r.Pos.Line)
|
||||
|
||||
// skip over resources that are marked as being ignored
|
||||
if strings.Contains(comments, "terraform-docs-ignore") {
|
||||
continue
|
||||
}
|
||||
|
||||
var version = ""
|
||||
if l, ok := lock[r.Provider.Name]; ok {
|
||||
version = l.Version
|
||||
@@ -375,6 +400,10 @@ func loadProviders(tfmodule *tfconfig.Module, config *print.Config) []*Provider
|
||||
}
|
||||
|
||||
key := fmt.Sprintf("%s.%s", r.Provider.Name, r.Provider.Alias)
|
||||
if _, ok := discovered[key]; ok {
|
||||
continue
|
||||
}
|
||||
|
||||
discovered[key] = &Provider{
|
||||
Name: r.Provider.Name,
|
||||
Alias: types.String(r.Provider.Alias),
|
||||
@@ -391,6 +420,7 @@ func loadProviders(tfmodule *tfconfig.Module, config *print.Config) []*Provider
|
||||
for _, provider := range discovered {
|
||||
providers = append(providers, provider)
|
||||
}
|
||||
|
||||
return providers
|
||||
}
|
||||
|
||||
@@ -427,6 +457,13 @@ func loadResources(tfmodule *tfconfig.Module, config *print.Config) []*Resource
|
||||
|
||||
for _, resource := range allResources {
|
||||
for _, r := range resource {
|
||||
comments := loadComments(r.Pos.Filename, r.Pos.Line)
|
||||
|
||||
// skip over resources that are marked as being ignored
|
||||
if strings.Contains(comments, "terraform-docs-ignore") {
|
||||
continue
|
||||
}
|
||||
|
||||
var version string
|
||||
if rv, ok := tfmodule.RequiredProviders[r.Provider.Name]; ok {
|
||||
version = resourceVersion(rv.VersionConstraints)
|
||||
@@ -444,7 +481,7 @@ func loadResources(tfmodule *tfconfig.Module, config *print.Config) []*Resource
|
||||
|
||||
description := ""
|
||||
if config.Settings.ReadComments {
|
||||
description = loadComments(r.Pos.Filename, r.Pos.Line)
|
||||
description = comments
|
||||
}
|
||||
|
||||
discovered[key] = &Resource{
|
||||
|
||||
@@ -11,12 +11,14 @@ the root directory of this source tree.
|
||||
package terraform
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.org/x/exp/slices"
|
||||
|
||||
"github.com/terraform-docs/terraform-docs/print"
|
||||
)
|
||||
@@ -38,6 +40,7 @@ func TestLoadModuleWithOptions(t *testing.T) {
|
||||
assert.Equal(true, module.HasModuleCalls())
|
||||
assert.Equal(true, module.HasProviders())
|
||||
assert.Equal(true, module.HasRequirements())
|
||||
assert.Equal(true, module.HasResources())
|
||||
|
||||
config.Sections.Header = false
|
||||
config.Sections.Footer = true
|
||||
@@ -774,6 +777,87 @@ func TestLoadProviders(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadRequirements(t *testing.T) {
|
||||
type expected struct {
|
||||
requirements []string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
path string
|
||||
expected expected
|
||||
}{
|
||||
{
|
||||
name: "load module requirements from path",
|
||||
path: "full-example",
|
||||
expected: expected{
|
||||
requirements: []string{"terraform >= 0.12", "aws >= 2.15.0"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "load module requirements from path",
|
||||
path: "no-requirements",
|
||||
expected: expected{
|
||||
requirements: []string{},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
module, _ := loadModule(filepath.Join("testdata", tt.path))
|
||||
requirements := loadRequirements(module)
|
||||
|
||||
assert.Equal(len(tt.expected.requirements), len(requirements))
|
||||
|
||||
for i, r := range tt.expected.requirements {
|
||||
assert.Equal(r, fmt.Sprintf("%s %s", requirements[i].Name, requirements[i].Version))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadResources(t *testing.T) {
|
||||
type expected struct {
|
||||
resources []string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
path string
|
||||
expected expected
|
||||
}{
|
||||
{
|
||||
name: "load module resources from path",
|
||||
path: "full-example",
|
||||
expected: expected{
|
||||
resources: []string{"tls_private_key.baz", "aws_caller_identity.current", "null_resource.foo"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "load module resources from path",
|
||||
path: "no-resources",
|
||||
expected: expected{
|
||||
resources: []string{},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
config := print.NewConfig()
|
||||
module, _ := loadModule(filepath.Join("testdata", tt.path))
|
||||
resources := loadResources(module, config)
|
||||
|
||||
assert.Equal(len(tt.expected.resources), len(resources))
|
||||
|
||||
for _, r := range resources {
|
||||
assert.True(slices.Contains(tt.expected.resources, fmt.Sprintf("%s_%s.%s", r.ProviderName, r.Type, r.Name)))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadComments(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
14
terraform/testdata/full-example/main.tf
vendored
14
terraform/testdata/full-example/main.tf
vendored
@@ -21,8 +21,16 @@ data "aws_caller_identity" "current" {
|
||||
provider = "aws"
|
||||
}
|
||||
|
||||
# terraform-docs-ignore
|
||||
data "aws_caller_identity" "ignored" {
|
||||
provider = "aws"
|
||||
}
|
||||
|
||||
resource "null_resource" "foo" {}
|
||||
|
||||
# terraform-docs-ignore
|
||||
resource "null_resource" "ignored" {}
|
||||
|
||||
module "foo" {
|
||||
source = "bar"
|
||||
version = "1.2.3"
|
||||
@@ -35,3 +43,9 @@ module "foobar" {
|
||||
locals {
|
||||
arn = provider::aws::arn_parse("arn:aws:iam::444455556666:role/example")
|
||||
}
|
||||
|
||||
// terraform-docs-ignore
|
||||
module "ignored" {
|
||||
source = "baz"
|
||||
version = "1.2.3"
|
||||
}
|
||||
|
||||
5
terraform/testdata/full-example/outputs.tf
vendored
5
terraform/testdata/full-example/outputs.tf
vendored
@@ -17,3 +17,8 @@ output "B" {
|
||||
output "D" {
|
||||
value = null
|
||||
}
|
||||
|
||||
# terraform-docs-ignore
|
||||
output "ignored" {
|
||||
value = "e"
|
||||
}
|
||||
|
||||
2
terraform/testdata/full-example/variables.tf
vendored
2
terraform/testdata/full-example/variables.tf
vendored
@@ -30,7 +30,7 @@ variable "G" {
|
||||
}
|
||||
|
||||
# terraform-docs-ignore
|
||||
variable "H" {
|
||||
variable "ignored" {
|
||||
description = "H description"
|
||||
default = null
|
||||
}
|
||||
|
||||
0
terraform/testdata/no-requirements/main.tf
vendored
Normal file
0
terraform/testdata/no-requirements/main.tf
vendored
Normal file
0
terraform/testdata/no-resources/main.tf
vendored
Normal file
0
terraform/testdata/no-resources/main.tf
vendored
Normal file
@@ -7,3 +7,8 @@ variable "B" {
|
||||
output "B" {
|
||||
value = "b"
|
||||
}
|
||||
|
||||
// terraform-docs-ignore
|
||||
output "ignored" {
|
||||
value = "c"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user