github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/genconfig/generate_config_write.go (about)

     1  package genconfig
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"os"
     7  
     8  	"github.com/terramate-io/tf/tfdiags"
     9  )
    10  
    11  func ShouldWriteConfig(out string) bool {
    12  	// No specified out file, so don't write anything.
    13  	return len(out) != 0
    14  }
    15  
    16  func ValidateTargetFile(out string) (diags tfdiags.Diagnostics) {
    17  	if _, err := os.Stat(out); !os.IsNotExist(err) {
    18  		diags = diags.Append(tfdiags.Sourceless(
    19  			tfdiags.Error,
    20  			"Target generated file already exists",
    21  			"Terraform can only write generated config into a new file. Either choose a different target location or move all existing configuration out of the target file, delete it and try again."))
    22  
    23  	}
    24  	return diags
    25  }
    26  
    27  type Change struct {
    28  	Addr            string
    29  	ImportID        string
    30  	GeneratedConfig string
    31  }
    32  
    33  func (c *Change) MaybeWriteConfig(writer io.Writer, out string) (io.Writer, bool, tfdiags.Diagnostics) {
    34  	var wroteConfig bool
    35  	var diags tfdiags.Diagnostics
    36  	if len(c.GeneratedConfig) > 0 {
    37  		if writer == nil {
    38  			// Lazily create the generated file, in case we have no
    39  			// generated config to create.
    40  			if w, err := os.Create(out); err != nil {
    41  				if os.IsPermission(err) {
    42  					diags = diags.Append(tfdiags.Sourceless(
    43  						tfdiags.Error,
    44  						"Failed to create target generated file",
    45  						fmt.Sprintf("Terraform did not have permission to create the generated file (%s) in the target directory. Please modify permissions over the target directory, and try again.", out)))
    46  					return nil, false, diags
    47  				}
    48  
    49  				diags = diags.Append(tfdiags.Sourceless(
    50  					tfdiags.Error,
    51  					"Failed to create target generated file",
    52  					fmt.Sprintf("Terraform could not create the generated file (%s) in the target directory: %v. Depending on the error message, this may be a bug in Terraform itself. If so, please report it!", out, err)))
    53  				return nil, false, diags
    54  			} else {
    55  				writer = w
    56  			}
    57  
    58  			header := "# __generated__ by Terraform\n# Please review these resources and move them into your main configuration files.\n"
    59  			// Missing the header from the file, isn't the end of the world
    60  			// so if this did return an error, then we will just ignore it.
    61  			_, _ = writer.Write([]byte(header))
    62  		}
    63  
    64  		header := "\n# __generated__ by Terraform"
    65  		if len(c.ImportID) > 0 {
    66  			header += fmt.Sprintf(" from %q", c.ImportID)
    67  		}
    68  		header += "\n"
    69  		if _, err := writer.Write([]byte(fmt.Sprintf("%s%s\n", header, c.GeneratedConfig))); err != nil {
    70  			diags = diags.Append(tfdiags.Sourceless(
    71  				tfdiags.Warning,
    72  				"Failed to save generated config",
    73  				fmt.Sprintf("Terraform encountered an error while writing generated config: %v. The config for %s must be created manually before applying. Depending on the error message, this may be a bug in Terraform itself. If so, please report it!", err, c.Addr)))
    74  		}
    75  		wroteConfig = true
    76  	}
    77  
    78  	return writer, wroteConfig, diags
    79  }