From 4714ee0b6661775764055c87e096b60e25d8e7c4 Mon Sep 17 00:00:00 2001 From: David Gageot Date: Mon, 28 May 2018 10:19:03 +0200 Subject: [PATCH 1/3] Add --output format flag to `skaffold build` Signed-off-by: David Gageot --- cmd/skaffold/app/cmd/build.go | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/cmd/skaffold/app/cmd/build.go b/cmd/skaffold/app/cmd/build.go index 73d5630d780..af0184c9dd4 100644 --- a/cmd/skaffold/app/cmd/build.go +++ b/cmd/skaffold/app/cmd/build.go @@ -18,14 +18,17 @@ package cmd import ( "context" - "fmt" "io" + "github.com/GoogleContainerTools/skaffold/cmd/skaffold/app/flags" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/build" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/runner" "github.com/pkg/errors" "github.com/spf13/cobra" ) +var buildFormatFlag = flags.NewTemplateFlag("{{range .Builds}}{{.ImageName}} -> {{.Tag}}\n{{end}}", BuildOutput{}) + // NewCmdBuild describes the CLI command to build artifacts. func NewCmdBuild(out io.Writer) *cobra.Command { cmd := &cobra.Command{ @@ -33,14 +36,20 @@ func NewCmdBuild(out io.Writer) *cobra.Command { Short: "Builds the artifacts", Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { - return build(out, filename) + return runBuild(out, filename) }, } AddRunDevFlags(cmd) + cmd.Flags().VarP(buildFormatFlag, "output", "o", buildFormatFlag.Usage()) return cmd } -func build(out io.Writer, filename string) error { +// BuildOutput is the output of `skaffold build`. +type BuildOutput struct { + Builds []build.Build +} + +func runBuild(out io.Writer, filename string) error { ctx := context.Background() config, err := readConfiguration(filename) @@ -58,9 +67,9 @@ func build(out io.Writer, filename string) error { return errors.Wrap(err, "build step") } - for _, build := range bRes { - fmt.Fprintln(out, build.ImageName, "->", build.Tag) + cmdOut := BuildOutput{Builds: bRes} + if err := buildFormatFlag.Template().Execute(out, cmdOut); err != nil { + return errors.Wrap(err, "executing template") } - - return err + return nil } From 2af19dc92f043ca6d9eedf531434cd45bcd537c4 Mon Sep 17 00:00:00 2001 From: David Gageot Date: Mon, 28 May 2018 10:19:26 +0200 Subject: [PATCH 2/3] Add a few default functions to templates. Signed-off-by: David Gageot --- cmd/skaffold/app/flags/template.go | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/cmd/skaffold/app/flags/template.go b/cmd/skaffold/app/flags/template.go index 2708752f9b3..f26329a447a 100644 --- a/cmd/skaffold/app/flags/template.go +++ b/cmd/skaffold/app/flags/template.go @@ -17,8 +17,11 @@ limitations under the License. package flags import ( + "bytes" + "encoding/json" "fmt" "reflect" + "strings" "text/template" "github.com/pkg/errors" @@ -45,7 +48,7 @@ func (t *TemplateFlag) Usage() string { } func (t *TemplateFlag) Set(value string) error { - tmpl, err := template.New("flagtemplate").Parse(value) + tmpl, err := parseTemplate(value) if err != nil { return errors.Wrap(err, "setting template flag") } @@ -64,8 +67,26 @@ func (t *TemplateFlag) Template() *template.Template { func NewTemplateFlag(value string, context interface{}) *TemplateFlag { return &TemplateFlag{ - template: template.Must(template.New("flagtemplate").Parse(value)), + template: template.Must(parseTemplate(value)), rawTemplate: value, context: context, } } + +func parseTemplate(value string) (*template.Template, error) { + var funcs = template.FuncMap{ + "json": func(v interface{}) string { + buf := &bytes.Buffer{} + enc := json.NewEncoder(buf) + enc.SetEscapeHTML(false) + enc.Encode(v) + return strings.TrimSpace(buf.String()) + }, + "join": strings.Join, + "title": strings.Title, + "lower": strings.ToLower, + "upper": strings.ToUpper, + } + + return template.New("flagtemplate").Funcs(funcs).Parse(value) +} From bd4f3159a4ab81055e379b046a93e6c3e88cecc7 Mon Sep 17 00:00:00 2001 From: David Gageot Date: Mon, 28 May 2018 10:26:40 +0200 Subject: [PATCH 3/3] Add a -q flag to `skaffold build` Signed-off-by: David Gageot --- cmd/skaffold/app/cmd/build.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/cmd/skaffold/app/cmd/build.go b/cmd/skaffold/app/cmd/build.go index af0184c9dd4..d6204fa3f26 100644 --- a/cmd/skaffold/app/cmd/build.go +++ b/cmd/skaffold/app/cmd/build.go @@ -19,6 +19,7 @@ package cmd import ( "context" "io" + "io/ioutil" "github.com/GoogleContainerTools/skaffold/cmd/skaffold/app/flags" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/build" @@ -27,7 +28,10 @@ import ( "github.com/spf13/cobra" ) -var buildFormatFlag = flags.NewTemplateFlag("{{range .Builds}}{{.ImageName}} -> {{.Tag}}\n{{end}}", BuildOutput{}) +var ( + quietFlag bool + buildFormatFlag = flags.NewTemplateFlag("{{range .Builds}}{{.ImageName}} -> {{.Tag}}\n{{end}}", BuildOutput{}) +) // NewCmdBuild describes the CLI command to build artifacts. func NewCmdBuild(out io.Writer) *cobra.Command { @@ -40,6 +44,7 @@ func NewCmdBuild(out io.Writer) *cobra.Command { }, } AddRunDevFlags(cmd) + cmd.Flags().BoolVarP(&quietFlag, "quiet", "q", false, "Suppress the build output and print image built on success") cmd.Flags().VarP(buildFormatFlag, "output", "o", buildFormatFlag.Usage()) return cmd } @@ -62,7 +67,12 @@ func runBuild(out io.Writer, filename string) error { return errors.Wrap(err, "creating runner") } - bRes, err := runner.Build(ctx, out, runner.Tagger, config.Build.Artifacts) + buildOut := out + if quietFlag { + buildOut = ioutil.Discard + } + + bRes, err := runner.Build(ctx, buildOut, runner.Tagger, config.Build.Artifacts) if err != nil { return errors.Wrap(err, "build step") }