# HG changeset patch
# User Florent Aide <florent.aide@gmail.com>
# Date 1665395312 -7200
#      Mon Oct 10 11:48:32 2022 +0200
# Node ID 15de5366d86d8d9993ffbccb7b38d810d1415bbc
# Parent  13cab2b329ba02123cf3698a0e03c0a5fee20052
cleanup .orig

diff --git a/runner/main.go.orig b/runner/main.go.orig
deleted file mode 100644
--- a/runner/main.go.orig
+++ /dev/null
@@ -1,384 +0,0 @@
-package runner
-
-import (
-	"bytes"
-	"errors"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"strings"
-
-	"github.com/go-cmd/cmd"
-	"github.com/go-yaml/yaml"
-)
-
-var (
-	defaultFileMod os.FileMode = 0600
-	defaultDirMod  os.FileMode = 0700
-	// TODO: find commands full path
-	yttCmd     = "ytt"
-	helmCmd    = "helm"
-	kubectlCmd = "kubectl"
-)
-
-// Runner is the struct in charge of launching commands
-type Runner struct {
-	config *CmdConfig
-}
-
-// NewRunner ...
-func NewRunner(cfg *CmdConfig) *Runner {
-	return &Runner{
-		config: cfg,
-	}
-}
-
-// Build is in charge of applying commands based on the config data
-func (r *Runner) Build(tmpDir string) error {
-	var outputDir string
-	if r.config.Output == "" {
-		outputDir = filepath.Join(r.config.RootDir, "build", r.config.Namespace)
-	} else {
-		outputDir = r.config.Output
-	}
-
-	preBuildDir := filepath.Join(tmpDir, "pre-build")
-	if err := r.DoBuild(tmpDir, preBuildDir); err != nil {
-		return fmt.Errorf("failed to do pre-build: %w", err)
-	}
-	if err := r.config.SetShas(preBuildDir); err != nil {
-		return fmt.Errorf("failed to set SHAs: %w", err)
-	}
-	files, err := ioutil.ReadDir(preBuildDir)
-	if err != nil {
-		return fmt.Errorf("cannot list directory: %s - %w", preBuildDir, err)
-	}
-	if err := CleanDir(outputDir); err != nil {
-		return fmt.Errorf("cannot clean dir: %s: %w", outputDir, err)
-	}
-	variables, err := r.config.prepareVariables(true)
-	if err != nil {
-		return fmt.Errorf("cannot prepare variables: %w", err)
-	}
-	for _, file := range files {
-		inFilePath := filepath.Join(preBuildDir, file.Name())
-		outFilePath := filepath.Join(outputDir, file.Name())
-		outFile, err := os.Create(outFilePath)
-		if err != nil {
-			return fmt.Errorf("cannot open: %s - %w", outFilePath, err)
-		}
-		defer func() {
-			if err := outFile.Close(); err != nil {
-				r.config.Logger.Fatal().Err(err).Msg("cannot close hydrated file")
-			}
-		}()
-		if err := hydrate(inFilePath, outFile, variables); err != nil {
-			return fmt.Errorf("cannot hydrate: %s - %w", outFilePath, err)
-		}
-	}
-	return nil
-}
-
-func (r *Runner) DoBuild(tmpDir, outputDir string) error {
-	cmds, err := r.prepareCmds()
-	if err != nil {
-		return err
-	}
-
-	compiled, err := r.runCommands(tmpDir, cmds)
-	if err != nil {
-		return err
-	}
-
-	yttOutput, err := r.runYtt(tmpDir, compiled)
-	if err != nil {
-		return err
-	}
-
-	kustomizeOutput, err := r.kustomize(tmpDir, yttOutput)
-	if err != nil {
-		return err
-	}
-
-	if r.config.DryRun {
-		return nil
-	}
-
-	if err := CleanDir(outputDir); err != nil {
-		return fmt.Errorf("cannot clean dir: %s: %w", outputDir, err)
-	}
-	if _, err := YamlSplit(outputDir, kustomizeOutput.Name()); err != nil {
-		return fmt.Errorf("cannot split full compiled file: %w", err)
-	}
-
-	return nil
-}
-
-func (r *Runner) kustomize(tmpDir string, input *os.File) (*os.File, error) {
-	kustomizeFilePath := filepath.Join(tmpDir, "kustomization.yaml")
-	f, err := os.Create(kustomizeFilePath)
-	if err != nil {
-		return nil, fmt.Errorf("fail to open %s: %w", kustomizeFilePath, err)
-	}
-	_, err = f.Write([]byte(fmt.Sprintf("resources: [%s]", filepath.Base(input.Name()))))
-	if err != nil {
-		return nil, fmt.Errorf("fail to write %s: %w", kustomizeFilePath, err)
-	}
-
-	variables, err := r.config.prepareVariables(false)
-	if err != nil {
-		return nil, fmt.Errorf("cannot prepare kustomize variables: %w", err)
-	}
-
-	var lastKustomizeFolder string
-
-	for _, layer := range r.config.Layers {
-		for _, ext := range []string{"yml", "yaml"} {
-			fName := fmt.Sprintf("kustomization.%s", ext)
-			fPath := filepath.Join(layer, "kustomize", fName)
-
-			fStat, err := os.Stat(fPath)
-			if err != nil || fStat.IsDir() {
-				continue
-			}
-			backupFile := fmt.Sprintf("%s.back", fPath)
-			if err := Copy(fPath, backupFile); err != nil {
-				return nil, fmt.Errorf("cannot copy kustomization file: %w", err)
-			}
-			defer func(fPath string) {
-				if err := Copy(backupFile, fPath); err != nil {
-					r.config.Logger.Fatal().Err(err).Msg("cannot restore kustomization back file")
-				}
-				if err := os.Remove(backupFile); err != nil {
-					r.config.Logger.Fatal().Err(err).Msg("cannot remove kustomization back file")
-				}
-			}(fPath)
-
-			if err := os.Remove(fPath); err != nil {
-				return nil, fmt.Errorf("cannot remove original kustomization file: %w", err)
-			}
-			outFile, err := os.Create(fPath)
-			if err != nil {
-				return nil, fmt.Errorf("cannot open: %s - %w", fPath, err)
-			}
-			defer func() {
-				if err := outFile.Close(); err != nil {
-					r.config.Logger.Fatal().Err(err).Msg("cannot close hydrated kustomization file")
-				}
-			}()
-
-			// kustomize root cannot be absolute
-			RelInputFilePath, err := filepath.Rel(filepath.Join(layer, "kustomize"), tmpDir)
-			if err != nil {
-				return nil, fmt.Errorf("cannot find relative path for: %s - %w", tmpDir, err)
-			}
-			variables["beaver.build"] = RelInputFilePath
-
-			if err := hydrate(backupFile, outFile, variables); err != nil {
-				return nil, fmt.Errorf("cannot hydrate: %s - %w", fPath, err)
-			}
-			lastKustomizeFolder = filepath.Join(layer, "kustomize")
-		}
-	}
-
-	// now run customize on the last layer with a kustomize folder
-	if lastKustomizeFolder != "" {
-		// now run customize on the last layer with a kustomize folder
-		kustomizeCmd := cmd.NewCmd(kubectlCmd, []string{"kustomize", lastKustomizeFolder}...)
-		return r.runCommand(tmpDir, "kustomize", kustomizeCmd)
-	}
-
-	return input, nil
-}
-
-func (r *Runner) prepareCmds() (map[string]*cmd.Cmd, error) {
-	// create helm commands
-	// create ytt chart commands
-	cmds := make(map[string]*cmd.Cmd)
-	for name, chart := range r.config.Spec.Charts {
-		args, err := chart.BuildArgs(name, r.config.Namespace)
-		if err != nil {
-			return nil, fmt.Errorf("build: failed to build args %w", err)
-		}
-		switch chart.Type {
-		case HelmType:
-			cmds[name] = cmd.NewCmd(helmCmd, args...)
-		case YttType:
-			cmds[name] = cmd.NewCmd(yttCmd, args...)
-		default:
-			return nil, fmt.Errorf("unsupported chart %s type: %q", chart.Path, chart.Type)
-		}
-	}
-
-	for key, create := range r.config.Spec.Creates {
-		strArgs := key.BuildArgs(r.config.Namespace, create.Args)
-		name := fmt.Sprintf("%s_%s", key.Type, key.Name)
-		c := cmd.NewCmd(kubectlCmd, strArgs...)
-		c.Dir = create.Dir
-		cmds[name] = c
-	}
-
-	return cmds, nil
-}
-
-func (r *Runner) runCommand(tmpDir, name string, cmd *cmd.Cmd) (*os.File, error) {
-	r.config.Logger.Info().
-		Str("command", cmd.Name).
-		Str("args", strings.Join(cmd.Args, " ")).
-		Msg("will run command")
-
-	if r.config.DryRun {
-		r.config.Logger.Info().
-			Str("command", cmd.Name).
-			Str("args", strings.Join(cmd.Args, " ")).
-			Msg("would run command")
-		return nil, nil
-	}
-	stdOut, stdErr, err := RunCMD(cmd)
-	if err != nil {
-		r.config.Logger.Err(err).
-			Str("command", cmd.Name).
-			Str("args", strings.Join(cmd.Args, " ")).
-			Str("sdtout", strings.Join(stdOut, "\n")).
-			Str("stderr", strings.Join(stdErr, "\n")).
-			Msg("failed to run command")
-
-		// Error must be pretty printed to end users /!\
-		fmt.Printf("\n%s\n\n", strings.Join(stdErr, "\n"))
-		return nil, fmt.Errorf("failed to run command: %w", err)
-	}
-	tmpFile, err := ioutil.TempFile(tmpDir, fmt.Sprintf("compiled-%s-*.yaml", name))
-	if err != nil {
-		return nil, fmt.Errorf("cannot create compiled file: %w", err)
-	}
-	defer func() {
-		if err := tmpFile.Close(); err != nil {
-			r.config.Logger.
-				Err(err).
-				Str("temp file", tmpFile.Name()).
-				Msg("failed to close temp file")
-		}
-	}()
-	if _, err := tmpFile.WriteString(strings.Join(stdOut, "\n")); err != nil {
-		return nil, fmt.Errorf("cannot write compiled file: %w", err)
-	}
-	return tmpFile, nil
-}
-
-func (r *Runner) runCommands(tmpDir string, cmds map[string]*cmd.Cmd) ([]string, error) {
-	var compiled []string
-	for name, cmd := range cmds {
-		f, err := r.runCommand(tmpDir, name, cmd)
-		if err != nil {
-			return nil, err
-		}
-		compiled = append(compiled, f.Name())
-	}
-	return compiled, nil
-}
-
-func (r *Runner) runYtt(tmpDir string, compiled []string) (*os.File, error) {
-	// create ytt additional command
-	args := r.config.BuildYttArgs(r.config.Spec.Ytt, compiled)
-
-	yttExtraCmd := cmd.NewCmd(yttCmd, args...)
-	return r.runCommand(tmpDir, "ytt", yttExtraCmd)
-}
-
-func CleanDir(directory string) error {
-	if err := os.RemoveAll(directory); err != nil {
-		return fmt.Errorf("cannot cleanup output directory: %w", err)
-	}
-	if err := os.MkdirAll(directory, defaultDirMod); err != nil {
-		return fmt.Errorf("cannot create output directory: %w", err)
-	}
-	return nil
-}
-
-func Copy(src, dst string) error {
-	in, err := os.Open(src)
-	if err != nil {
-		return err
-	}
-	defer in.Close()
-
-	out, err := os.Create(dst)
-	if err != nil {
-		return err
-	}
-	defer out.Close()
-
-	_, err = io.Copy(out, in)
-	if err != nil {
-		return err
-	}
-	return out.Close()
-}
-
-// YamlSplit takes a buildDir and an inputFile.
-// it returns a list of yaml documents and an eventual error
-func YamlSplit(buildDir, inputFile string) ([]string, error) {
-	var docs []string
-	var allResources []map[string]interface{}
-	input, err := os.ReadFile(inputFile)
-	if err != nil {
-		return nil, err
-	}
-	if err := unmarshalAllResources(input, &allResources); err != nil {
-		return nil, err
-	}
-	for _, resource := range allResources {
-		apiVersion, ok := resource["apiVersion"].(string)
-		if !ok {
-			return nil, fmt.Errorf("fail to type assert apiVersion from: %+v", resource)
-		}
-		kind, ok := resource["kind"].(string)
-		if !ok {
-			return nil, fmt.Errorf("kind missing from: %+v", resource)
-		}
-		metadata, ok := resource["metadata"].(map[interface{}]interface{})
-		if !ok {
-			return nil, fmt.Errorf("fail to type assert metadata from: %+v", resource)
-		}
-		name, ok := metadata["name"].(string)
-		if !ok {
-			return nil, fmt.Errorf("fail to type assert metadata.name from: %+v", resource)
-		}
-		filename := fmt.Sprintf("%s.%s.%s.yaml", kind, strings.ReplaceAll(apiVersion, "/", "_"), name)
-		fPath := filepath.Join(buildDir, filename)
-
-		out, err := yaml.Marshal(resource)
-		if err != nil {
-			return nil, fmt.Errorf("cannot marshal resource: %w", err)
-		}
-		if err := os.MkdirAll(buildDir, defaultDirMod); err != nil {
-			return nil, fmt.Errorf("cannot create build directory: %w", err)
-		}
-		content := append([]byte("---\n"), out...)
-		if err := os.WriteFile(fPath, content, defaultFileMod); err != nil {
-			return nil, fmt.Errorf("cannot write resource: %w", err)
-		}
-		docs = append(docs, fPath)
-	}
-
-	return docs, nil
-}
-
-func unmarshalAllResources(in []byte, out *[]map[string]interface{}) error {
-	r := bytes.NewReader(in)
-	decoder := yaml.NewDecoder(r)
-	for {
-		res := make(map[string]interface{})
-		if err := decoder.Decode(&res); err != nil {
-			// Break when there are no more documents to decode
-			if !errors.Is(err, io.EOF) {
-				return err
-			}
-			break
-		}
-		*out = append(*out, res)
-	}
-	return nil
-}