github.com/crossplane/upjet@v1.3.0/pkg/types/comments/comment.go (about)

     1  // SPDX-FileCopyrightText: 2023 The Crossplane Authors <https://crossplane.io>
     2  //
     3  // SPDX-License-Identifier: Apache-2.0
     4  
     5  package comments
     6  
     7  import (
     8  	"strings"
     9  
    10  	"github.com/crossplane/upjet/pkg/config"
    11  	"github.com/crossplane/upjet/pkg/types/markers"
    12  )
    13  
    14  // Option is a comment option
    15  type Option func(*Comment)
    16  
    17  // WithReferenceConfig returns a comment options with the given reference config
    18  func WithReferenceConfig(cfg config.Reference) Option {
    19  	return func(c *Comment) {
    20  		c.Reference = cfg
    21  	}
    22  }
    23  
    24  // WithTFTag returns a comment options with input tf tag
    25  func WithTFTag(s string) Option {
    26  	return func(c *Comment) {
    27  		c.FieldTFTag = &s
    28  	}
    29  }
    30  
    31  // New returns a Comment by parsing Upjet markers as Options
    32  func New(text string, opts ...Option) (*Comment, error) {
    33  	to := markers.UpjetOptions{}
    34  	co := markers.CrossplaneOptions{}
    35  
    36  	rawLines := strings.Split(strings.TrimSpace(text), "\n")
    37  	lines := make([]string, 0, len(rawLines))
    38  	for _, rl := range rawLines {
    39  		rl = strings.TrimSpace(rl)
    40  		if rl == "" {
    41  			lines = append(lines, rl)
    42  			continue
    43  		}
    44  		// Only add raw marker line if not processed as an option (e.g. if it is
    45  		// not a known marker.) Known markers will still be printed as
    46  		// comments while building from options.
    47  		parsed, err := markers.ParseAsUpjetOption(&to, rl)
    48  		if err != nil {
    49  			return nil, err
    50  		}
    51  		if parsed {
    52  			continue
    53  		}
    54  
    55  		lines = append(lines, rl)
    56  	}
    57  
    58  	c := &Comment{
    59  		Text: strings.Join(lines, "\n"),
    60  		Options: markers.Options{
    61  			UpjetOptions:      to,
    62  			CrossplaneOptions: co,
    63  		},
    64  	}
    65  
    66  	for _, o := range opts {
    67  		o(c)
    68  	}
    69  
    70  	return c, nil
    71  }
    72  
    73  // Comment represents a comment with text and supported marker options.
    74  type Comment struct {
    75  	Text string
    76  	markers.Options
    77  }
    78  
    79  // String returns a string representation of this Comment (no "// " prefix)
    80  func (c *Comment) String() string {
    81  	if c.Text == "" {
    82  		return c.Options.String()
    83  	}
    84  	return c.Text + "\n" + c.Options.String()
    85  }
    86  
    87  // Build builds comments by adding comment prefix ("// ") to each line of
    88  // the string representation of this Comment.
    89  func (c *Comment) Build() string {
    90  	all := strings.ReplaceAll("// "+c.String(), "\n", "\n// ")
    91  	return strings.TrimSuffix(all, "// ")
    92  }
    93  
    94  // CommentWithoutOptions returns a new Comment without the Options.
    95  func (c *Comment) CommentWithoutOptions() *Comment {
    96  	if c == nil {
    97  		return nil
    98  	}
    99  	return &Comment{
   100  		Text: c.Text,
   101  	}
   102  }