Files
kustomize/cmd/config/runner/runner.go
Natasha Sarkar ef60d5f9bb remove deprecated cfg and fn commands (#4930)
* remove deprecated cfg and fn commands

* fix lint error

* run gofmt
2022-12-14 12:15:35 -08:00

150 lines
4.1 KiB
Go

// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package runner
import (
"fmt"
"io"
"os"
"strings"
"github.com/go-errors/errors"
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/kyaml/pathutil"
)
// CmdRunner interface holds ExecuteCmd definition which executes respective command's
// implementation on single package
type CmdRunner interface {
ExecuteCmd(w io.Writer, pkgPath string) error
}
// ExecuteCmdOnPkgs struct holds the parameters necessary to
// execute the filter command on packages in rootPkgPath
type ExecuteCmdOnPkgs struct {
RootPkgPath string
RecurseSubPackages bool
NeedOpenAPI bool
CmdRunner CmdRunner
Writer io.Writer
SkipPkgPathPrint bool
}
// ExecuteCmdOnPkgs takes the function definition for a command to be executed on single package, applies that definition
// recursively on all the subpackages present in rootPkgPath if recurseSubPackages is true, else applies the command on rootPkgPath only
func (e ExecuteCmdOnPkgs) Execute() error {
pkgsPaths, err := pathutil.DirsWithFile(e.RootPkgPath, ext.KRMFileName(), e.RecurseSubPackages)
if err != nil {
return err
}
if len(pkgsPaths) == 0 {
// at this point, there are no openAPI files in the rootPkgPath
if e.NeedOpenAPI {
// few executions need openAPI file to be present(ex: setters commands), if true throw an error
return errors.Errorf("unable to find %q in package %q", ext.KRMFileName(), e.RootPkgPath)
}
// add root path for commands which doesn't need openAPI(ex: annotate, fmt)
pkgsPaths = []string{e.RootPkgPath}
}
// for commands which doesn't need openAPI file, make sure that the root package is
// included all the times
if !e.NeedOpenAPI && !containsString(pkgsPaths, e.RootPkgPath) {
pkgsPaths = append([]string{e.RootPkgPath}, pkgsPaths...)
}
for i := range pkgsPaths {
err := e.processPkg(pkgsPaths[i])
if err != nil {
return err
}
if i != len(pkgsPaths)-1 {
fmt.Fprint(e.Writer, "\n")
}
}
return nil
}
func (e ExecuteCmdOnPkgs) processPkg(pkgPath string) error {
// Add schema present in openAPI file for current package
if !e.SkipPkgPathPrint {
fmt.Fprintf(e.Writer, "%s/\n", pkgPath)
}
return e.CmdRunner.ExecuteCmd(e.Writer, pkgPath)
}
// ParseFieldPath parse a flag value into a field path
func ParseFieldPath(path string) ([]string, error) {
// fixup '\.' so we don't split on it
match := strings.ReplaceAll(path, "\\.", "$$$$")
parts := strings.Split(match, ".")
for i := range parts {
parts[i] = strings.ReplaceAll(parts[i], "$$$$", ".")
}
// split the list index from the list field
var newParts []string
for i := range parts {
if !strings.Contains(parts[i], "[") {
newParts = append(newParts, parts[i])
continue
}
p := strings.Split(parts[i], "[")
if len(p) != 2 {
return nil, fmt.Errorf("unrecognized path element: %s. "+
"Should be of the form 'list[field=value]'", parts[i])
}
p[1] = "[" + p[1]
newParts = append(newParts, p[0], p[1])
}
return newParts, nil
}
func HandleError(c *cobra.Command, err error) error {
if err == nil {
return nil
}
if StackOnError {
if err, ok := err.(*errors.Error); ok {
fmt.Fprintf(os.Stderr, "%s", err.Stack())
}
}
if ExitOnError {
fmt.Fprintf(c.ErrOrStderr(), "Error: %v\n", err)
os.Exit(1)
}
return err
}
// ExitOnError if true, will cause commands to call os.Exit instead of returning an error.
// Used for skipping printing usage on failure.
var ExitOnError bool
// StackOnError if true, will print a stack trace on failure.
var StackOnError bool
const cmdName = "kustomize fn"
// FixDocs replaces instances of old with new in the docs for c
func FixDocs(newStr string, c *cobra.Command) {
c.Use = strings.ReplaceAll(c.Use, cmdName, newStr)
c.Short = strings.ReplaceAll(c.Short, cmdName, newStr)
c.Long = strings.ReplaceAll(c.Long, cmdName, newStr)
c.Example = strings.ReplaceAll(c.Example, cmdName, newStr)
}
// containsString returns true if slice contains s
func containsString(slice []string, s string) bool {
for _, item := range slice {
if item == s {
return true
}
}
return false
}