github.com/bitrise-io/bitrise-step-update-gitops-repository@v0.0.0-20240426081835-1466be593380/pkg/gitops/templates.go (about)

     1  package gitops
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  	"text/template"
     8  )
     9  
    10  //go:generate moq -out templates_moq_test.go . allFilesRenderer
    11  type allFilesRenderer interface {
    12  	renderAllFiles() error
    13  }
    14  
    15  // templates implements the allFilesRenderer interface.
    16  var _ allFilesRenderer = (*Templates)(nil)
    17  
    18  // Templates renders a folder of templates to a local repository.
    19  type Templates struct {
    20  	// Source folder of templates.
    21  	SourceFolder string
    22  	// Values to substitute into the templates.
    23  	Values map[string]string
    24  	// Destination repository for rendered files.
    25  	DestinationRepo localRepository
    26  	// Destination folder inside the repository for rendered files.
    27  	DestinationFolder string
    28  }
    29  
    30  func (tr Templates) renderAllFiles() error {
    31  	// Get all template file names from the source folder.
    32  	files, err := os.ReadDir(tr.SourceFolder)
    33  	if err != nil {
    34  		return fmt.Errorf("read files in %q: %w", tr.SourceFolder, err)
    35  	}
    36  
    37  	// Render templates one-by-one to the destinaton folder
    38  	// (substituting values given).
    39  	for _, file := range files {
    40  		if err := tr.renderFile(file.Name()); err != nil {
    41  			return fmt.Errorf("render file %q: %w", file.Name(), err)
    42  		}
    43  	}
    44  	return nil
    45  }
    46  
    47  func (tr Templates) renderFile(fileName string) error {
    48  	// Parse template.
    49  	sourceFilePath := filepath.Join(tr.SourceFolder, fileName)
    50  	t, err := template.ParseFiles(sourceFilePath)
    51  	if err != nil {
    52  		return fmt.Errorf("parse template %q: %w", sourceFilePath, err)
    53  	}
    54  
    55  	// Create a file for the rendered template.
    56  	destinationFilePath := filepath.Join(
    57  		tr.DestinationRepo.localPath(), tr.DestinationFolder, fileName)
    58  	f, err := os.Create(destinationFilePath)
    59  	if err != nil {
    60  		return fmt.Errorf("create destination file: %w", err)
    61  	}
    62  
    63  	// Render the template to the previously created file.
    64  	if err := t.Option("missingkey=error").Execute(f, tr.Values); err != nil {
    65  		return fmt.Errorf("execute template %q: %w", sourceFilePath, err)
    66  	}
    67  	return nil
    68  }