mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-05-17 18:25:26 +00:00
fn/framework support for reading from stdin in standalone
- speficy '-' to read from stdin when running standalone
This commit is contained in:
@@ -95,11 +95,21 @@ type ResourceList struct {
|
||||
|
||||
// NoPrintError if set will prevent the error from being printed
|
||||
NoPrintError bool
|
||||
|
||||
Command *cobra.Command
|
||||
}
|
||||
|
||||
// Read reads the ResourceList
|
||||
func (r *ResourceList) Read() error {
|
||||
var in io.Reader = os.Stdin
|
||||
var out io.Writer = os.Stdout
|
||||
if r.Command != nil {
|
||||
in = r.Command.InOrStdin()
|
||||
out = r.Command.OutOrStdout()
|
||||
}
|
||||
|
||||
// parse the inputs from the args
|
||||
var readStdinStandalone bool
|
||||
if len(r.Args) > 0 && !r.DisableStandalone {
|
||||
// write the files as input
|
||||
var buf bytes.Buffer
|
||||
@@ -109,6 +119,12 @@ func (r *ResourceList) Read() error {
|
||||
if i == 0 {
|
||||
continue
|
||||
}
|
||||
if r.Args[i] == "-" {
|
||||
// Read stdin separately
|
||||
readStdinStandalone = true
|
||||
continue
|
||||
}
|
||||
|
||||
b, err := ioutil.ReadFile(r.Args[i])
|
||||
if err != nil {
|
||||
return errors.WrapPrefixf(err, "unable to read input file %s", r.Args[i])
|
||||
@@ -120,10 +136,10 @@ func (r *ResourceList) Read() error {
|
||||
}
|
||||
|
||||
if r.Reader == nil {
|
||||
r.Reader = os.Stdin
|
||||
r.Reader = in
|
||||
}
|
||||
if r.Writer == nil {
|
||||
r.Writer = os.Stdout
|
||||
r.Writer = out
|
||||
}
|
||||
r.rw = &kio.ByteReadWriter{
|
||||
Reader: r.Reader,
|
||||
@@ -157,6 +173,16 @@ func (r *ResourceList) Read() error {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
if readStdinStandalone {
|
||||
br := kio.ByteReader{Reader: in}
|
||||
items, err := br.Read()
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
// stdin always comes first so files are patches
|
||||
r.Items = append(items, r.Items...)
|
||||
}
|
||||
|
||||
// parse the functionConfig
|
||||
return func() error {
|
||||
if r.rw.FunctionConfig == nil {
|
||||
@@ -223,8 +249,9 @@ func (r *ResourceList) Write() error {
|
||||
// a Dockerfile to build the function into a container image
|
||||
//
|
||||
// go run main.go gen DIR/
|
||||
func Command(resourceList *ResourceList, function Function) cobra.Command {
|
||||
func Command(resourceList *ResourceList, function Function) *cobra.Command {
|
||||
cmd := cobra.Command{}
|
||||
resourceList.Command = &cmd
|
||||
AddGenerateDockerfile(&cmd)
|
||||
var printStack bool
|
||||
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
@@ -242,7 +269,7 @@ func Command(resourceList *ResourceList, function Function) cobra.Command {
|
||||
cmd.Args = cobra.MinimumNArgs(0)
|
||||
cmd.SilenceErrors = true
|
||||
cmd.SilenceUsage = true
|
||||
return cmd
|
||||
return &cmd
|
||||
}
|
||||
|
||||
// TemplateCommand provides a cobra command to invoke a template
|
||||
@@ -310,7 +337,7 @@ func (tc TemplateCommand) doTemplate(t *template.Template, rl *ResourceList) err
|
||||
}
|
||||
|
||||
// GetCommand returns a new cobra command
|
||||
func (tc TemplateCommand) GetCommand() cobra.Command {
|
||||
func (tc TemplateCommand) GetCommand() *cobra.Command {
|
||||
rl := ResourceList{
|
||||
FunctionConfig: tc.API,
|
||||
NoPrintError: true,
|
||||
|
||||
@@ -4,13 +4,16 @@
|
||||
package framework_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"sigs.k8s.io/kustomize/kyaml/fn/framework"
|
||||
"sigs.k8s.io/kustomize/kyaml/fn/framework/frameworktestutil"
|
||||
"sigs.k8s.io/kustomize/kyaml/testutil"
|
||||
@@ -66,7 +69,7 @@ func TestCommand_standalone(t *testing.T) {
|
||||
var config api
|
||||
|
||||
resourceList := &framework.ResourceList{FunctionConfig: &config}
|
||||
cmdFn := func() cobra.Command {
|
||||
cmdFn := func() *cobra.Command {
|
||||
return framework.Command(resourceList, func() error {
|
||||
resourceList.Items = append(resourceList.Items, yaml.MustParse(`
|
||||
apiVersion: apps/v1
|
||||
@@ -90,3 +93,72 @@ metadata:
|
||||
|
||||
frameworktestutil.ResultsChecker{Command: cmdFn}.Assert(t)
|
||||
}
|
||||
|
||||
func TestCommand_standalonestdin(t *testing.T) {
|
||||
// TODO: make this test pass on windows -- currently failure seems spurious
|
||||
testutil.SkipWindows(t)
|
||||
|
||||
type api = struct {
|
||||
A string `json:"a" yaml:"a"`
|
||||
}
|
||||
var config api
|
||||
|
||||
resourceList := &framework.ResourceList{FunctionConfig: &config}
|
||||
cmd := framework.Command(resourceList, func() error {
|
||||
resourceList.Items = append(resourceList.Items, yaml.MustParse(`
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: bar2
|
||||
namespace: default
|
||||
annotations:
|
||||
foo: bar2
|
||||
`))
|
||||
for i := range resourceList.Items {
|
||||
err := resourceList.Items[i].PipeE(yaml.SetAnnotation("a", config.A))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
cmd.SetIn(bytes.NewBufferString(`
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: bar1
|
||||
namespace: default
|
||||
annotations:
|
||||
foo: bar1
|
||||
spec:
|
||||
replicas: 1
|
||||
`))
|
||||
var out bytes.Buffer
|
||||
cmd.SetOut(&out)
|
||||
cmd.SetArgs([]string{filepath.Join("testdata", "command", "config.yaml"), "-"})
|
||||
|
||||
require.NoError(t, cmd.Execute())
|
||||
|
||||
require.Equal(t, strings.TrimSpace(`
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: bar1
|
||||
namespace: default
|
||||
annotations:
|
||||
foo: bar1
|
||||
a: 'b'
|
||||
spec:
|
||||
replicas: 1
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: bar2
|
||||
namespace: default
|
||||
annotations:
|
||||
foo: bar2
|
||||
a: 'b'
|
||||
`), strings.TrimSpace(out.String()))
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ type ResultsChecker struct {
|
||||
ExpectedErrorFilename string
|
||||
|
||||
// Command provides the function to run.
|
||||
Command func() cobra.Command
|
||||
Command func() *cobra.Command
|
||||
}
|
||||
|
||||
// Assert asserts the results for functions
|
||||
|
||||
@@ -21,7 +21,7 @@ func TestPatchTemplate(t *testing.T) {
|
||||
// TODO: make this test pass on windows -- current failure seems spurious
|
||||
testutil.SkipWindows(t)
|
||||
|
||||
cmdFn := func() cobra.Command {
|
||||
cmdFn := func() *cobra.Command {
|
||||
type api struct {
|
||||
Selector framework.Selector `json:"selector" yaml:"selector"`
|
||||
A string `json:"a" yaml:"a"`
|
||||
|
||||
Reference in New Issue
Block a user