github.com/Racer159/jackal@v0.32.7-0.20240401174413-0bd2339e4f2e/src/pkg/packager/generate.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // SPDX-FileCopyrightText: 2021-Present The Jackal Authors
     3  
     4  // Package packager contains functions for interacting with, managing and deploying Jackal packages.
     5  package packager
     6  
     7  import (
     8  	"fmt"
     9  	"os"
    10  	"path/filepath"
    11  	"strings"
    12  
    13  	"github.com/Racer159/jackal/src/config"
    14  	"github.com/Racer159/jackal/src/internal/packager/validate"
    15  	"github.com/Racer159/jackal/src/pkg/layout"
    16  	"github.com/Racer159/jackal/src/pkg/message"
    17  	"github.com/Racer159/jackal/src/types"
    18  	"github.com/defenseunicorns/pkg/helpers"
    19  	goyaml "github.com/goccy/go-yaml"
    20  )
    21  
    22  // Generate generates a Jackal package definition.
    23  func (p *Packager) Generate() (err error) {
    24  	generatedJackalYAMLPath := filepath.Join(p.cfg.GenerateOpts.Output, layout.JackalYAML)
    25  	spinner := message.NewProgressSpinner("Generating package for %q at %s", p.cfg.GenerateOpts.Name, generatedJackalYAMLPath)
    26  
    27  	if !helpers.InvalidPath(generatedJackalYAMLPath) {
    28  		prefixed := filepath.Join(p.cfg.GenerateOpts.Output, fmt.Sprintf("%s-%s", p.cfg.GenerateOpts.Name, layout.JackalYAML))
    29  
    30  		message.Warnf("%s already exists, writing to %s", generatedJackalYAMLPath, prefixed)
    31  
    32  		generatedJackalYAMLPath = prefixed
    33  
    34  		if !helpers.InvalidPath(generatedJackalYAMLPath) {
    35  			return fmt.Errorf("unable to generate package, %s already exists", generatedJackalYAMLPath)
    36  		}
    37  	}
    38  
    39  	generatedComponent := types.JackalComponent{
    40  		Name:     p.cfg.GenerateOpts.Name,
    41  		Required: helpers.BoolPtr(true),
    42  		Charts: []types.JackalChart{
    43  			{
    44  				Name:      p.cfg.GenerateOpts.Name,
    45  				Version:   p.cfg.GenerateOpts.Version,
    46  				Namespace: p.cfg.GenerateOpts.Name,
    47  				URL:       p.cfg.GenerateOpts.URL,
    48  				GitPath:   p.cfg.GenerateOpts.GitPath,
    49  			},
    50  		},
    51  	}
    52  
    53  	p.cfg.Pkg = types.JackalPackage{
    54  		Kind: types.JackalPackageConfig,
    55  		Metadata: types.JackalMetadata{
    56  			Name:        p.cfg.GenerateOpts.Name,
    57  			Version:     p.cfg.GenerateOpts.Version,
    58  			Description: "auto-generated using `jackal dev generate`",
    59  		},
    60  		Components: []types.JackalComponent{
    61  			generatedComponent,
    62  		},
    63  	}
    64  
    65  	images, err := p.findImages()
    66  	if err != nil {
    67  		// purposefully not returning error here, as we can still generate the package without images
    68  		message.Warnf("Unable to find images: %s", err.Error())
    69  	}
    70  
    71  	for i := range p.cfg.Pkg.Components {
    72  		name := p.cfg.Pkg.Components[i].Name
    73  		p.cfg.Pkg.Components[i].Images = images[name]
    74  	}
    75  
    76  	if err := validate.Run(p.cfg.Pkg); err != nil {
    77  		return err
    78  	}
    79  
    80  	if err := helpers.CreateDirectory(p.cfg.GenerateOpts.Output, helpers.ReadExecuteAllWriteUser); err != nil {
    81  		return err
    82  	}
    83  
    84  	b, err := goyaml.MarshalWithOptions(p.cfg.Pkg, goyaml.IndentSequence(true), goyaml.UseSingleQuote(false))
    85  	if err != nil {
    86  		return err
    87  	}
    88  
    89  	schemaComment := fmt.Sprintf("# yaml-language-server: $schema=https://raw.githubusercontent.com/%s/%s/jackal.schema.json", config.GithubProject, config.CLIVersion)
    90  	content := schemaComment + "\n" + string(b)
    91  
    92  	// lets space things out a bit
    93  	content = strings.Replace(content, "kind:\n", "\nkind:\n", 1)
    94  	content = strings.Replace(content, "metadata:\n", "\nmetadata:\n", 1)
    95  	content = strings.Replace(content, "components:\n", "\ncomponents:\n", 1)
    96  
    97  	spinner.Successf("Generated package for %q at %s", p.cfg.GenerateOpts.Name, generatedJackalYAMLPath)
    98  
    99  	return os.WriteFile(generatedJackalYAMLPath, []byte(content), helpers.ReadAllWriteUser)
   100  }