github.com/opentofu/opentofu@v1.7.1/internal/command/jsonformat/computed/renderers/util.go (about)

     1  // Copyright (c) The OpenTofu Authors
     2  // SPDX-License-Identifier: MPL-2.0
     3  // Copyright (c) 2023 HashiCorp, Inc.
     4  // SPDX-License-Identifier: MPL-2.0
     5  
     6  package renderers
     7  
     8  import (
     9  	"fmt"
    10  	"strings"
    11  
    12  	"github.com/opentofu/opentofu/internal/command/format"
    13  
    14  	"github.com/hashicorp/hcl/v2/hclsyntax"
    15  
    16  	"github.com/opentofu/opentofu/internal/command/jsonformat/computed"
    17  	"github.com/opentofu/opentofu/internal/plans"
    18  )
    19  
    20  // NoWarningsRenderer defines a Warnings function that returns an empty list of
    21  // warnings. This can be used by other renderers to ensure we don't see lots of
    22  // repeats of this empty function.
    23  type NoWarningsRenderer struct{}
    24  
    25  // WarningsHuman returns an empty slice, as the name NoWarningsRenderer suggests.
    26  func (render NoWarningsRenderer) WarningsHuman(_ computed.Diff, _ int, _ computed.RenderHumanOpts) []string {
    27  	return nil
    28  }
    29  
    30  // nullSuffix returns the `-> null` suffix if the change is a delete action, and
    31  // it has not been overridden.
    32  func nullSuffix(action plans.Action, opts computed.RenderHumanOpts) string {
    33  	if !opts.OverrideNullSuffix && action == plans.Delete {
    34  		return opts.Colorize.Color(" [dark_gray]-> null[reset]")
    35  	}
    36  	return ""
    37  }
    38  
    39  // forcesReplacement returns the `# forces replacement` suffix if this change is
    40  // driving the entire resource to be replaced.
    41  func forcesReplacement(replace bool, opts computed.RenderHumanOpts) string {
    42  	if replace || opts.OverrideForcesReplacement {
    43  		return opts.Colorize.Color(" [red]# forces replacement[reset]")
    44  	}
    45  	return ""
    46  }
    47  
    48  // indent returns whitespace that is the required length for the specified
    49  // indent.
    50  func formatIndent(indent int) string {
    51  	return strings.Repeat("    ", indent)
    52  }
    53  
    54  // unchanged prints out a description saying how many of 'keyword' have been
    55  // hidden because they are unchanged or noop actions.
    56  func unchanged(keyword string, count int, opts computed.RenderHumanOpts) string {
    57  	if count == 1 {
    58  		return opts.Colorize.Color(fmt.Sprintf("[dark_gray]# (%d unchanged %s hidden)[reset]", count, keyword))
    59  	}
    60  	return opts.Colorize.Color(fmt.Sprintf("[dark_gray]# (%d unchanged %ss hidden)[reset]", count, keyword))
    61  }
    62  
    63  // EnsureValidAttributeName checks if `name` contains any HCL syntax and calls
    64  // and returns hclEscapeString.
    65  func EnsureValidAttributeName(name string) string {
    66  	if !hclsyntax.ValidIdentifier(name) {
    67  		return hclEscapeString(name)
    68  	}
    69  	return name
    70  }
    71  
    72  // hclEscapeString formats the input string into a format that is safe for
    73  // rendering within HCL.
    74  //
    75  // Note, this function doesn't actually do a very good job of this currently. We
    76  // need to expose some internal functions from HCL in a future version and call
    77  // them from here. For now, just use "%q" formatting.
    78  func hclEscapeString(str string) string {
    79  	// TODO: Replace this with more complete HCL logic instead of the simple
    80  	// go workaround.
    81  	return fmt.Sprintf("%q", str)
    82  }
    83  
    84  // writeDiffActionSymbol writes out the symbols for the associated action, and
    85  // handles localized colorization of the symbol as well as indenting the symbol
    86  // to be 4 spaces wide.
    87  //
    88  // If the opts has HideDiffActionSymbols set then this function returns an empty
    89  // string.
    90  func writeDiffActionSymbol(action plans.Action, opts computed.RenderHumanOpts) string {
    91  	if opts.HideDiffActionSymbols {
    92  		return ""
    93  	}
    94  	return fmt.Sprintf("%s ", opts.Colorize.Color(format.DiffActionSymbol(action)))
    95  }