From 7359e63960983cd98b213b433c51becbf2fa5394 Mon Sep 17 00:00:00 2001 From: Soule BA Date: Mon, 7 Mar 2022 12:05:53 +0100 Subject: [PATCH] Introduce a printer interface for flux resource If implemented, there will a common interface to print flux resource. We are adding new way to print resource information e.g. diff of objects. Signed-off-by: Soule BA --- cmd/flux/get.go | 16 +++++++-- internal/build/diff.go | 12 +++---- internal/utils/utils.go | 19 ---------- pkg/printers/dyff.go | 56 ++++++++++++++++++++++++++++++ pkg/printers/interface.go | 33 ++++++++++++++++++ pkg/printers/table_printer.go | 65 +++++++++++++++++++++++++++++++++++ 6 files changed, 171 insertions(+), 30 deletions(-) create mode 100644 pkg/printers/dyff.go create mode 100644 pkg/printers/interface.go create mode 100644 pkg/printers/table_printer.go diff --git a/cmd/flux/get.go b/cmd/flux/get.go index f52fd496..29fa1c2d 100644 --- a/cmd/flux/get.go +++ b/cmd/flux/get.go @@ -33,6 +33,7 @@ import ( "github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/flux2/internal/utils" + "github.com/fluxcd/flux2/pkg/printers" ) type deriveType func(runtime.Object) (summarisable, error) @@ -177,7 +178,10 @@ func (get getCommand) run(cmd *cobra.Command, args []string) error { return err } - utils.PrintTable(cmd.OutOrStdout(), header, rows) + err = printers.TablePrinter(header).Print(cmd.OutOrStdout(), rows) + if err != nil { + return err + } if getAll { fmt.Println() @@ -242,10 +246,16 @@ func watchUntil(ctx context.Context, w watch.Interface, get *getCommand) (bool, return false, err } if firstIteration { - utils.PrintTable(os.Stdout, header, rows) + err = printers.TablePrinter(header).Print(os.Stdout, rows) + if err != nil { + return false, err + } firstIteration = false } else { - utils.PrintTable(os.Stdout, []string{}, rows) + err = printers.TablePrinter([]string{}).Print(os.Stdout, rows) + if err != nil { + return false, err + } } return false, nil diff --git a/internal/build/diff.go b/internal/build/diff.go index 4c6b6efa..b955989c 100644 --- a/internal/build/diff.go +++ b/internal/build/diff.go @@ -27,6 +27,7 @@ import ( "sort" "strings" + "github.com/fluxcd/flux2/pkg/printers" kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2" "github.com/fluxcd/pkg/ssa" "github.com/gonvenience/bunt" @@ -112,7 +113,7 @@ func (b *Builder) Diff() (string, bool, error) { } if change.Action == string(ssa.ConfiguredAction) { - output.WriteString(writeString(fmt.Sprintf("► %s drifted\n", change.Subject), bunt.WhiteSmoke)) + output.WriteString(bunt.Sprint(fmt.Sprintf("► %s drifted\n", change.Subject))) liveFile, mergedFile, tmpDir, err := writeYamls(liveObject, mergedObject) if err != nil { return "", createdOrDrifted, err @@ -204,14 +205,9 @@ func diff(liveFile, mergedFile string, output io.Writer) error { return fmt.Errorf("failed to compare input files: %w", err) } - reportWriter := &dyff.HumanReport{ - Report: report, - OmitHeader: true, - } + printer := printers.NewDyffPrinter() - if err := reportWriter.WriteReport(output); err != nil { - return fmt.Errorf("failed to print report: %w", err) - } + printer.Print(output, report) return nil } diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 361b9448..cdadeaa4 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -27,7 +27,6 @@ import ( "runtime" "strings" - "github.com/olekukonko/tablewriter" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" @@ -247,24 +246,6 @@ func MakeDependsOn(deps []string) []dependency.CrossNamespaceDependencyReference return refs } -func PrintTable(writer io.Writer, header []string, rows [][]string) { - table := tablewriter.NewWriter(writer) - table.SetHeader(header) - table.SetAutoWrapText(false) - table.SetAutoFormatHeaders(true) - table.SetHeaderAlignment(tablewriter.ALIGN_LEFT) - table.SetAlignment(tablewriter.ALIGN_LEFT) - table.SetCenterSeparator("") - table.SetColumnSeparator("") - table.SetRowSeparator("") - table.SetHeaderLine(false) - table.SetBorder(false) - table.SetTablePadding("\t") - table.SetNoWhiteSpace(true) - table.AppendBulk(rows) - table.Render() -} - func ValidateComponents(components []string) error { defaults := install.MakeDefaultOptions() bootstrapAllComponents := append(defaults.Components, defaults.ComponentsExtra...) diff --git a/pkg/printers/dyff.go b/pkg/printers/dyff.go new file mode 100644 index 00000000..50db14d2 --- /dev/null +++ b/pkg/printers/dyff.go @@ -0,0 +1,56 @@ +/* +Copyright 2022 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package printers + +import ( + "fmt" + "io" + + "github.com/homeport/dyff/pkg/dyff" +) + +// DyffPrinter is a printer that prints dyff reports. +type DyffPrinter struct { + OmitHeader bool +} + +// NewDyffPrinter returns a new DyffPrinter. +func NewDyffPrinter() *DyffPrinter { + return &DyffPrinter{ + OmitHeader: true, + } +} + +// Print prints the given args to the given writer. +func (p *DyffPrinter) Print(w io.Writer, args ...interface{}) error { + for _, arg := range args { + switch arg := arg.(type) { + case dyff.Report: + reportWriter := &dyff.HumanReport{ + Report: arg, + OmitHeader: p.OmitHeader, + } + + if err := reportWriter.WriteReport(w); err != nil { + return fmt.Errorf("failed to print report: %w", err) + } + default: + return fmt.Errorf("unsupported type %T", arg) + } + } + return nil +} diff --git a/pkg/printers/interface.go b/pkg/printers/interface.go new file mode 100644 index 00000000..e01600e5 --- /dev/null +++ b/pkg/printers/interface.go @@ -0,0 +1,33 @@ +/* +Copyright 2022 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package printers + +import "io" + +// Printer is an interface for printing Flux cmd outputs. +type Printer interface { + // Print prints the given args to the given writer. + Print(io.Writer, ...interface{}) error +} + +// PrinterFunc is a function that can print args to a writer. +type PrinterFunc func(w io.Writer, args ...interface{}) error + +// Print implements Printer +func (fn PrinterFunc) Print(w io.Writer, args ...interface{}) error { + return fn(w, args) +} diff --git a/pkg/printers/table_printer.go b/pkg/printers/table_printer.go new file mode 100644 index 00000000..716166ab --- /dev/null +++ b/pkg/printers/table_printer.go @@ -0,0 +1,65 @@ +/* +Copyright 2022 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package printers + +import ( + "fmt" + "io" + + "github.com/olekukonko/tablewriter" +) + +// TablePrinter is a printer that prints Flux cmd outputs. +func TablePrinter(header []string) PrinterFunc { + return func(w io.Writer, args ...interface{}) error { + var rows [][]string + for _, arg := range args { + switch arg := arg.(type) { + case []interface{}: + for _, v := range arg { + s, ok := v.([][]string) + if !ok { + return fmt.Errorf("unsupported type %T", v) + } + for i := range s { + rows = append(rows, s[i]) + } + } + default: + return fmt.Errorf("unsupported type %T", arg) + } + } + + table := tablewriter.NewWriter(w) + table.SetHeader(header) + table.SetAutoWrapText(false) + table.SetAutoFormatHeaders(true) + table.SetHeaderAlignment(tablewriter.ALIGN_LEFT) + table.SetAlignment(tablewriter.ALIGN_LEFT) + table.SetCenterSeparator("") + table.SetColumnSeparator("") + table.SetRowSeparator("") + table.SetHeaderLine(false) + table.SetBorder(false) + table.SetTablePadding("\t") + table.SetNoWhiteSpace(true) + table.AppendBulk(rows) + table.Render() + + return nil + } +}