mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-12 01:14:22 +00:00
Merge pull request #3494 from KnVerey/template-cmd-without-cobra
[kyaml] Framework/TemplateCommand usability improvements
This commit is contained in:
@@ -90,8 +90,9 @@ type ResourceList struct {
|
|||||||
// Defaults to os.Stdout.
|
// Defaults to os.Stdout.
|
||||||
Writer io.Writer
|
Writer io.Writer
|
||||||
|
|
||||||
// rw reads function input and writes function output
|
// ReadWriter reads function input and writes function output
|
||||||
rw *kio.ByteReadWriter
|
// If set, it will take precedence over the Reader and Writer fields
|
||||||
|
ReadWriter *kio.ByteReadWriter
|
||||||
|
|
||||||
// NoPrintError if set will prevent the error from being printed
|
// NoPrintError if set will prevent the error from being printed
|
||||||
NoPrintError bool
|
NoPrintError bool
|
||||||
@@ -99,15 +100,36 @@ type ResourceList struct {
|
|||||||
Command *cobra.Command
|
Command *cobra.Command
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read reads the ResourceList
|
func (r *ResourceList) defaultReadWriter() *kio.ByteReadWriter {
|
||||||
func (r *ResourceList) Read() error {
|
rw := kio.ByteReadWriter{
|
||||||
var in io.Reader = os.Stdin
|
KeepReaderAnnotations: true,
|
||||||
var out io.Writer = os.Stdout
|
Reader: r.Reader,
|
||||||
if r.Command != nil {
|
Writer: r.Writer,
|
||||||
in = r.Command.InOrStdin()
|
|
||||||
out = r.Command.OutOrStdout()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default reader source precedence: r.Reader > r.Command.InOrStdin > os.Stdin
|
||||||
|
if rw.Reader == nil {
|
||||||
|
if r.Command != nil {
|
||||||
|
rw.Reader = r.Command.InOrStdin()
|
||||||
|
} else {
|
||||||
|
rw.Reader = os.Stdin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default writer source precedence: r.Writer > r.Command.OutOrStdout > os.Stdout
|
||||||
|
if rw.Writer == nil {
|
||||||
|
if r.Command != nil {
|
||||||
|
rw.Writer = r.Command.OutOrStdout()
|
||||||
|
} else {
|
||||||
|
rw.Writer = os.Stdout
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &rw
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read reads the ResourceList
|
||||||
|
func (r *ResourceList) Read() error {
|
||||||
// parse the inputs from the args
|
// parse the inputs from the args
|
||||||
var readStdinStandalone bool
|
var readStdinStandalone bool
|
||||||
if len(r.Args) > 0 && !r.DisableStandalone {
|
if len(r.Args) > 0 && !r.DisableStandalone {
|
||||||
@@ -135,25 +157,20 @@ func (r *ResourceList) Read() error {
|
|||||||
r.Reader = &buf
|
r.Reader = &buf
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.Reader == nil {
|
// Default the ReadWriter and ensure related fields are in a consistent state
|
||||||
r.Reader = in
|
if r.ReadWriter == nil {
|
||||||
}
|
r.ReadWriter = r.defaultReadWriter()
|
||||||
if r.Writer == nil {
|
|
||||||
r.Writer = out
|
|
||||||
}
|
|
||||||
r.rw = &kio.ByteReadWriter{
|
|
||||||
Reader: r.Reader,
|
|
||||||
Writer: r.Writer,
|
|
||||||
KeepReaderAnnotations: true,
|
|
||||||
}
|
}
|
||||||
|
r.Reader = r.ReadWriter.Reader
|
||||||
|
r.Writer = r.ReadWriter.Writer
|
||||||
|
|
||||||
// parse the resourceList.FunctionConfig from the first arg
|
// parse the resourceList.FunctionConfig from the first arg
|
||||||
if len(r.Args) > 0 && !r.DisableStandalone {
|
if len(r.Args) > 0 && !r.DisableStandalone {
|
||||||
// Don't keep the reader annotations if we are in standalone mode
|
// Don't keep the reader annotations if we are in standalone mode
|
||||||
r.rw.KeepReaderAnnotations = false
|
r.ReadWriter.KeepReaderAnnotations = false
|
||||||
// Don't wrap the resources in a resourceList -- we are in
|
// Don't wrap the resources in a resourceList -- we are in
|
||||||
// standalone mode and writing to stdout to be applied
|
// standalone mode and writing to stdout to be applied
|
||||||
r.rw.NoWrap = true
|
r.ReadWriter.NoWrap = true
|
||||||
|
|
||||||
b, err := ioutil.ReadFile(r.Args[0])
|
b, err := ioutil.ReadFile(r.Args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -164,16 +181,22 @@ func (r *ResourceList) Read() error {
|
|||||||
return errors.WrapPrefixf(err, "unable to parse configuration file %s", r.Args[0])
|
return errors.WrapPrefixf(err, "unable to parse configuration file %s", r.Args[0])
|
||||||
}
|
}
|
||||||
// use this as the function config used to configure the function
|
// use this as the function config used to configure the function
|
||||||
r.rw.FunctionConfig = fc
|
r.ReadWriter.FunctionConfig = fc
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
r.Items, err = r.rw.Read()
|
r.Items, err = r.ReadWriter.Read()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err)
|
return errors.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if readStdinStandalone {
|
if readStdinStandalone {
|
||||||
|
var in io.Reader
|
||||||
|
if r.Command != nil {
|
||||||
|
in = r.Command.InOrStdin()
|
||||||
|
} else {
|
||||||
|
in = os.Stdin
|
||||||
|
}
|
||||||
br := kio.ByteReader{Reader: in}
|
br := kio.ByteReader{Reader: in}
|
||||||
items, err := br.Read()
|
items, err := br.Read()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -185,16 +208,16 @@ func (r *ResourceList) Read() error {
|
|||||||
|
|
||||||
// parse the functionConfig
|
// parse the functionConfig
|
||||||
return func() error {
|
return func() error {
|
||||||
if r.rw.FunctionConfig == nil {
|
if r.ReadWriter.FunctionConfig == nil {
|
||||||
// no function config exists
|
// no function config exists
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if r.FunctionConfig == nil {
|
if r.FunctionConfig == nil {
|
||||||
// set directly from r.rw
|
// set directly from r.rw
|
||||||
r.FunctionConfig = r.rw.FunctionConfig
|
r.FunctionConfig = r.ReadWriter.FunctionConfig
|
||||||
} else {
|
} else {
|
||||||
// unmarshal the functionConfig into the provided value
|
// unmarshal the functionConfig into the provided value
|
||||||
err := yaml.Unmarshal([]byte(r.rw.FunctionConfig.MustString()), r.FunctionConfig)
|
err := yaml.Unmarshal([]byte(r.ReadWriter.FunctionConfig.MustString()), r.FunctionConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err)
|
return errors.Wrap(err)
|
||||||
}
|
}
|
||||||
@@ -205,7 +228,7 @@ func (r *ResourceList) Read() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// flags are always set from the "data" field
|
// flags are always set from the "data" field
|
||||||
data, err := r.rw.FunctionConfig.Pipe(yaml.Lookup("data"))
|
data, err := r.ReadWriter.FunctionConfig.Pipe(yaml.Lookup("data"))
|
||||||
if err != nil || data == nil {
|
if err != nil || data == nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -232,12 +255,12 @@ func (r *ResourceList) Write() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err)
|
return errors.Wrap(err)
|
||||||
}
|
}
|
||||||
r.rw.Results = y
|
r.ReadWriter.Results = y
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// write the results
|
// write the results
|
||||||
return r.rw.Write(r.Items)
|
return r.ReadWriter.Write(r.Items)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Command returns a cobra.Command to run a function.
|
// Command returns a cobra.Command to run a function.
|
||||||
@@ -255,7 +278,11 @@ func Command(resourceList *ResourceList, function Function) *cobra.Command {
|
|||||||
AddGenerateDockerfile(&cmd)
|
AddGenerateDockerfile(&cmd)
|
||||||
var printStack bool
|
var printStack bool
|
||||||
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||||
err := execute(resourceList, function, cmd, args)
|
resourceList.Reader = cmd.InOrStdin()
|
||||||
|
resourceList.Writer = cmd.OutOrStdout()
|
||||||
|
resourceList.Flags = cmd.Flags()
|
||||||
|
resourceList.Args = args
|
||||||
|
err := WrapInResourceListIO(resourceList, function)()
|
||||||
if err != nil && !resourceList.NoPrintError {
|
if err != nil && !resourceList.NoPrintError {
|
||||||
fmt.Fprintf(cmd.ErrOrStderr(), "%v", err)
|
fmt.Fprintf(cmd.ErrOrStderr(), "%v", err)
|
||||||
}
|
}
|
||||||
@@ -365,6 +392,11 @@ type Defaulter interface {
|
|||||||
Default() error
|
Default() error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validator is implemented by APIs to have Validate invoked
|
||||||
|
type Validator interface {
|
||||||
|
Validate() error
|
||||||
|
}
|
||||||
|
|
||||||
func (tc *TemplateCommand) doPreProcess(rl *ResourceList) error {
|
func (tc *TemplateCommand) doPreProcess(rl *ResourceList) error {
|
||||||
// do any preprocessing
|
// do any preprocessing
|
||||||
if tc.PreProcess != nil {
|
if tc.PreProcess != nil {
|
||||||
@@ -490,39 +522,46 @@ func (tc *TemplateCommand) doPatchContainerTemplates(rl *ResourceList) error {
|
|||||||
|
|
||||||
// GetCommand returns a new cobra command
|
// GetCommand returns a new cobra command
|
||||||
func (tc TemplateCommand) GetCommand() *cobra.Command {
|
func (tc TemplateCommand) GetCommand() *cobra.Command {
|
||||||
rl := ResourceList{
|
rl := &ResourceList{
|
||||||
FunctionConfig: tc.API,
|
FunctionConfig: tc.API,
|
||||||
NoPrintError: true,
|
NoPrintError: true,
|
||||||
}
|
}
|
||||||
c := Command(&rl, func() error {
|
return Command(rl, func() error { return tc.Execute(rl) })
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tc TemplateCommand) Execute(rl *ResourceList) error {
|
||||||
if d, ok := rl.FunctionConfig.(Defaulter); ok {
|
if d, ok := rl.FunctionConfig.(Defaulter); ok {
|
||||||
if err := d.Default(); err != nil {
|
if err := d.Default(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := tc.doPreProcess(&rl); err != nil {
|
if v, ok := rl.FunctionConfig.(Validator); ok {
|
||||||
|
if err := v.Validate(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := tc.doTemplates(&rl); err != nil {
|
}
|
||||||
|
|
||||||
|
if err := tc.doPreProcess(rl); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := tc.doPatchTemplates(&rl); err != nil {
|
if err := tc.doTemplates(rl); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := tc.doPatchContainerTemplates(&rl); err != nil {
|
if err := tc.doPatchTemplates(rl); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := tc.doMerge(&rl); err != nil {
|
if err := tc.doPatchContainerTemplates(rl); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := tc.doPostProcess(&rl); err != nil {
|
if err := tc.doMerge(rl); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := tc.doPostProcess(rl); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
|
||||||
return c
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddGenerateDockerfile adds a "gen" subcommand to create a Dockerfile for building
|
// AddGenerateDockerfile adds a "gen" subcommand to create a Dockerfile for building
|
||||||
@@ -547,12 +586,8 @@ CMD ["function"]
|
|||||||
cmd.AddCommand(gen)
|
cmd.AddCommand(gen)
|
||||||
}
|
}
|
||||||
|
|
||||||
func execute(rl *ResourceList, function Function, cmd *cobra.Command, args []string) error {
|
func WrapInResourceListIO(rl *ResourceList, function Function) Function {
|
||||||
rl.Reader = cmd.InOrStdin()
|
return func() error {
|
||||||
rl.Writer = cmd.OutOrStdout()
|
|
||||||
rl.Flags = cmd.Flags()
|
|
||||||
rl.Args = args
|
|
||||||
|
|
||||||
if err := rl.Read(); err != nil {
|
if err := rl.Read(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -565,6 +600,7 @@ func execute(rl *ResourceList, function Function, cmd *cobra.Command, args []str
|
|||||||
|
|
||||||
return retErr
|
return retErr
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Filters returns a function which returns the provided Filters
|
// Filters returns a function which returns the provided Filters
|
||||||
func Filters(fltrs ...kio.Filter) func(*ResourceList) []kio.Filter {
|
func Filters(fltrs ...kio.Filter) func(*ResourceList) []kio.Filter {
|
||||||
|
|||||||
Reference in New Issue
Block a user