From 52b2fa0a886ffbe3f3bb0e0a433705ac772f2ae2 Mon Sep 17 00:00:00 2001 From: "Zheao.Li" Date: Thu, 29 Dec 2022 11:57:49 +0800 Subject: [PATCH] [Refactor]: Move fmtutil from cmd to pkg/formatter Signed-off-by: Zheao.Li --- cmd/nerdctl/apparmor_ls_linux.go | 5 ++- cmd/nerdctl/container_inspect.go | 8 +++- cmd/nerdctl/events.go | 3 +- cmd/nerdctl/history.go | 4 +- cmd/nerdctl/image_inspect.go | 8 +++- cmd/nerdctl/images.go | 4 +- cmd/nerdctl/info.go | 3 +- cmd/nerdctl/namespace_inspect.go | 7 +++- cmd/nerdctl/network_inspect.go | 8 +++- cmd/nerdctl/network_ls.go | 7 ++-- cmd/nerdctl/ps.go | 4 +- cmd/nerdctl/stats.go | 4 +- cmd/nerdctl/version.go | 3 +- cmd/nerdctl/volume_inspect.go | 7 +++- cmd/nerdctl/volume_ls.go | 7 ++-- .../fmtutil.go => pkg/formatter/common.go | 39 ++++++------------- 16 files changed, 66 insertions(+), 55 deletions(-) rename cmd/nerdctl/fmtutil.go => pkg/formatter/common.go (73%) diff --git a/cmd/nerdctl/apparmor_ls_linux.go b/cmd/nerdctl/apparmor_ls_linux.go index 34a4ab1b92e..57ad991ad5b 100644 --- a/cmd/nerdctl/apparmor_ls_linux.go +++ b/cmd/nerdctl/apparmor_ls_linux.go @@ -24,6 +24,7 @@ import ( "text/template" "github.com/containerd/nerdctl/pkg/apparmorutil" + "github.com/containerd/nerdctl/pkg/formatter" "github.com/spf13/cobra" ) @@ -70,7 +71,7 @@ func apparmorLsAction(cmd *cobra.Command, args []string) error { return errors.New("format and quiet must not be specified together") } var err error - tmpl, err = parseTemplate(format) + tmpl, err = formatter.ParseTemplate(format) if err != nil { return err } @@ -96,7 +97,7 @@ func apparmorLsAction(cmd *cobra.Command, args []string) error { fmt.Fprintf(w, "%s\t%s\n", f.Name, f.Mode) } } - if f, ok := w.(Flusher); ok { + if f, ok := w.(formatter.Flusher); ok { return f.Flush() } return nil diff --git a/cmd/nerdctl/container_inspect.go b/cmd/nerdctl/container_inspect.go index 8580af92130..81b1a784174 100644 --- a/cmd/nerdctl/container_inspect.go +++ b/cmd/nerdctl/container_inspect.go @@ -22,6 +22,7 @@ import ( "time" "github.com/containerd/nerdctl/pkg/containerinspector" + "github.com/containerd/nerdctl/pkg/formatter" "github.com/containerd/nerdctl/pkg/idutil/containerwalker" "github.com/containerd/nerdctl/pkg/inspecttypes/dockercompat" @@ -81,8 +82,11 @@ func containerInspectAction(cmd *cobra.Command, args []string) error { if len(errs) > 0 { return fmt.Errorf("%d errors: %v", len(errs), errs) } - - return formatSlice(cmd, f.entries) + format, err := cmd.Flags().GetString("format") + if err != nil { + return err + } + return formatter.FormatSlice(format, cmd.OutOrStdout(), f.entries) } type containerInspector struct { diff --git a/cmd/nerdctl/events.go b/cmd/nerdctl/events.go index 916dcb4e82d..d3faeb8ae18 100644 --- a/cmd/nerdctl/events.go +++ b/cmd/nerdctl/events.go @@ -26,6 +26,7 @@ import ( "github.com/containerd/containerd/events" "github.com/containerd/containerd/log" + "github.com/containerd/nerdctl/pkg/formatter" "github.com/containerd/typeurl" "github.com/spf13/cobra" @@ -81,7 +82,7 @@ func eventsAction(cmd *cobra.Command, args []string) error { case "raw", "table", "wide": return errors.New("unsupported format: \"raw\", \"table\", and \"wide\"") default: - tmpl, err = parseTemplate(format) + tmpl, err = formatter.ParseTemplate(format) if err != nil { return err } diff --git a/cmd/nerdctl/history.go b/cmd/nerdctl/history.go index 27f1ff58b22..c1e9ae79ecb 100644 --- a/cmd/nerdctl/history.go +++ b/cmd/nerdctl/history.go @@ -195,7 +195,7 @@ func printHistory(cmd *cobra.Command, historys []historyPrintable) error { return errors.New("format and quiet must not be specified together") } var err error - tmpl, err = parseTemplate(format) + tmpl, err = formatter.ParseTemplate(format) if err != nil { return err } @@ -214,7 +214,7 @@ func printHistory(cmd *cobra.Command, historys []historyPrintable) error { } } - if f, ok := w.(Flusher); ok { + if f, ok := w.(formatter.Flusher); ok { return f.Flush() } return nil diff --git a/cmd/nerdctl/image_inspect.go b/cmd/nerdctl/image_inspect.go index 15e5bf912fa..1bc7af68d52 100644 --- a/cmd/nerdctl/image_inspect.go +++ b/cmd/nerdctl/image_inspect.go @@ -23,6 +23,7 @@ import ( "github.com/containerd/containerd" "github.com/containerd/containerd/platforms" + "github.com/containerd/nerdctl/pkg/formatter" "github.com/containerd/nerdctl/pkg/idutil/imagewalker" "github.com/containerd/nerdctl/pkg/imageinspector" "github.com/containerd/nerdctl/pkg/inspecttypes/dockercompat" @@ -128,8 +129,11 @@ func imageInspectActionWithPlatform(cmd *cobra.Command, args []string, platform if len(errs) > 0 { return fmt.Errorf("%d errors: %v", len(errs), errs) } - - return formatSlice(cmd, f.entries) + format, err := cmd.Flags().GetString("format") + if err != nil { + return err + } + return formatter.FormatSlice(format, cmd.OutOrStdout(), f.entries) } type imageInspector struct { diff --git a/cmd/nerdctl/images.go b/cmd/nerdctl/images.go index 60ffd9165e6..f51db89876f 100644 --- a/cmd/nerdctl/images.go +++ b/cmd/nerdctl/images.go @@ -267,7 +267,7 @@ func printImages(ctx context.Context, cmd *cobra.Command, client *containerd.Cli return errors.New("format and quiet must not be specified together") } var err error - tmpl, err = parseTemplate(format) + tmpl, err = formatter.ParseTemplate(format) if err != nil { return err } @@ -295,7 +295,7 @@ func printImages(ctx context.Context, cmd *cobra.Command, client *containerd.Cli logrus.Warn(err) } } - if f, ok := w.(Flusher); ok { + if f, ok := w.(formatter.Flusher); ok { return f.Flush() } return nil diff --git a/cmd/nerdctl/info.go b/cmd/nerdctl/info.go index 9268492e500..3d7374426d3 100644 --- a/cmd/nerdctl/info.go +++ b/cmd/nerdctl/info.go @@ -23,6 +23,7 @@ import ( "strings" "text/template" + "github.com/containerd/nerdctl/pkg/formatter" "golang.org/x/text/cases" "golang.org/x/text/language" @@ -67,7 +68,7 @@ func infoAction(cmd *cobra.Command, args []string) error { return err } if format != "" { - tmpl, err = parseTemplate(format) + tmpl, err = formatter.ParseTemplate(format) if err != nil { return err } diff --git a/cmd/nerdctl/namespace_inspect.go b/cmd/nerdctl/namespace_inspect.go index 408164082bb..382328610f3 100644 --- a/cmd/nerdctl/namespace_inspect.go +++ b/cmd/nerdctl/namespace_inspect.go @@ -18,6 +18,7 @@ package main import ( "github.com/containerd/containerd/namespaces" + "github.com/containerd/nerdctl/pkg/formatter" "github.com/containerd/nerdctl/pkg/inspecttypes/native" "github.com/spf13/cobra" ) @@ -58,5 +59,9 @@ func labelInspectAction(cmd *cobra.Command, args []string) error { } result[index] = nsInspect } - return formatSlice(cmd, result) + format, err := cmd.Flags().GetString("format") + if err != nil { + return err + } + return formatter.FormatSlice(format, cmd.OutOrStdout(), result) } diff --git a/cmd/nerdctl/network_inspect.go b/cmd/nerdctl/network_inspect.go index 06facf36d93..95e2731a534 100644 --- a/cmd/nerdctl/network_inspect.go +++ b/cmd/nerdctl/network_inspect.go @@ -20,6 +20,7 @@ import ( "encoding/json" "fmt" + "github.com/containerd/nerdctl/pkg/formatter" "github.com/containerd/nerdctl/pkg/inspecttypes/dockercompat" "github.com/containerd/nerdctl/pkg/inspecttypes/native" "github.com/containerd/nerdctl/pkg/netutil" @@ -100,8 +101,11 @@ func networkInspectAction(cmd *cobra.Command, args []string) error { return fmt.Errorf("unknown mode %q", mode) } } - - return formatSlice(cmd, result) + format, err := cmd.Flags().GetString("format") + if err != nil { + return err + } + return formatter.FormatSlice(format, cmd.OutOrStdout(), result) } func networkInspectShellComplete(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { diff --git a/cmd/nerdctl/network_ls.go b/cmd/nerdctl/network_ls.go index 26933333f33..1a9793f6f84 100644 --- a/cmd/nerdctl/network_ls.go +++ b/cmd/nerdctl/network_ls.go @@ -23,6 +23,7 @@ import ( "text/tabwriter" "text/template" + "github.com/containerd/nerdctl/pkg/formatter" "github.com/containerd/nerdctl/pkg/netutil" "github.com/spf13/cobra" @@ -79,7 +80,7 @@ func networkLsAction(cmd *cobra.Command, args []string) error { return errors.New("format and quiet must not be specified together") } var err error - tmpl, err = parseTemplate(format) + tmpl, err = formatter.ParseTemplate(format) if err != nil { return err } @@ -114,7 +115,7 @@ func networkLsAction(cmd *cobra.Command, args []string) error { } } if n.NerdctlLabels != nil { - p.Labels = formatLabels(*n.NerdctlLabels) + p.Labels = formatter.FormatLabels(*n.NerdctlLabels) } pp[i] = p } @@ -146,7 +147,7 @@ func networkLsAction(cmd *cobra.Command, args []string) error { fmt.Fprintf(w, "%s\t%s\t%s\n", p.ID, p.Name, p.file) } } - if f, ok := w.(Flusher); ok { + if f, ok := w.(formatter.Flusher); ok { return f.Flush() } return nil diff --git a/cmd/nerdctl/ps.go b/cmd/nerdctl/ps.go index b377263d82b..5fece981d26 100644 --- a/cmd/nerdctl/ps.go +++ b/cmd/nerdctl/ps.go @@ -182,7 +182,7 @@ func printContainers(ctx context.Context, client *containerd.Client, cmd *cobra. return errors.New("format and quiet must not be specified together") } var err error - tmpl, err = parseTemplate(format) + tmpl, err = formatter.ParseTemplate(format) if err != nil { return err } @@ -277,7 +277,7 @@ func printContainers(ctx context.Context, client *containerd.Client, cmd *cobra. } } - if f, ok := w.(Flusher); ok { + if f, ok := w.(formatter.Flusher); ok { return f.Flush() } return nil diff --git a/cmd/nerdctl/stats.go b/cmd/nerdctl/stats.go index e843aefc3b7..5f42f8f04aa 100644 --- a/cmd/nerdctl/stats.go +++ b/cmd/nerdctl/stats.go @@ -134,7 +134,7 @@ func statsAction(cmd *cobra.Command, args []string) error { case "raw": return errors.New("unsupported format: \"raw\"") default: - tmpl, err = parseTemplate(format) + tmpl, err = formatter.ParseTemplate(format) if err != nil { return err } @@ -348,7 +348,7 @@ func statsAction(cmd *cobra.Command, args []string) error { } } } - if f, ok := w.(Flusher); ok { + if f, ok := w.(formatter.Flusher); ok { f.Flush() } diff --git a/cmd/nerdctl/version.go b/cmd/nerdctl/version.go index 15915173439..b2a780f3504 100644 --- a/cmd/nerdctl/version.go +++ b/cmd/nerdctl/version.go @@ -23,6 +23,7 @@ import ( "os" "text/template" + "github.com/containerd/nerdctl/pkg/formatter" "github.com/containerd/nerdctl/pkg/infoutil" "github.com/containerd/nerdctl/pkg/inspecttypes/dockercompat" "github.com/spf13/cobra" @@ -54,7 +55,7 @@ func versionAction(cmd *cobra.Command, args []string) error { } if format != "" { var err error - tmpl, err = parseTemplate(format) + tmpl, err = formatter.ParseTemplate(format) if err != nil { return err } diff --git a/cmd/nerdctl/volume_inspect.go b/cmd/nerdctl/volume_inspect.go index 8fc19b458b4..d2fc5bf44f0 100644 --- a/cmd/nerdctl/volume_inspect.go +++ b/cmd/nerdctl/volume_inspect.go @@ -17,6 +17,7 @@ package main import ( + "github.com/containerd/nerdctl/pkg/formatter" "github.com/spf13/cobra" ) @@ -57,8 +58,12 @@ func volumeInspectAction(cmd *cobra.Command, args []string) error { } result[i] = vol } + format, err := cmd.Flags().GetString("format") + if err != nil { + return err + } - return formatSlice(cmd, result) + return formatter.FormatSlice(format, cmd.OutOrStdout(), result) } func volumeInspectShellComplete(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { diff --git a/cmd/nerdctl/volume_ls.go b/cmd/nerdctl/volume_ls.go index 3f38c921447..4488e98dc0b 100644 --- a/cmd/nerdctl/volume_ls.go +++ b/cmd/nerdctl/volume_ls.go @@ -26,6 +26,7 @@ import ( "text/template" "github.com/containerd/containerd/pkg/progress" + "github.com/containerd/nerdctl/pkg/formatter" "github.com/containerd/nerdctl/pkg/inspecttypes/native" "github.com/sirupsen/logrus" @@ -116,7 +117,7 @@ func volumeLsAction(cmd *cobra.Command, args []string) error { return errors.New("format and quiet must not be specified together") } var err error - tmpl, err = parseTemplate(format) + tmpl, err = formatter.ParseTemplate(format) if err != nil { return err } @@ -139,7 +140,7 @@ func volumeLsAction(cmd *cobra.Command, args []string) error { Scope: "local", } if v.Labels != nil { - p.Labels = formatLabels(*v.Labels) + p.Labels = formatter.FormatLabels(*v.Labels) } if volumeSize { p.Size = progress.Bytes(v.Size).String() @@ -160,7 +161,7 @@ func volumeLsAction(cmd *cobra.Command, args []string) error { fmt.Fprintf(w, "%s\t%s\n", p.Name, p.Mountpoint) } } - if f, ok := w.(Flusher); ok { + if f, ok := w.(formatter.Flusher); ok { return f.Flush() } return nil diff --git a/cmd/nerdctl/fmtutil.go b/pkg/formatter/common.go similarity index 73% rename from cmd/nerdctl/fmtutil.go rename to pkg/formatter/common.go index cb52442f2e0..8915f0dc3ec 100644 --- a/cmd/nerdctl/fmtutil.go +++ b/pkg/formatter/common.go @@ -14,17 +14,17 @@ limitations under the License. */ -package main +package formatter import ( "bytes" "encoding/json" "errors" "fmt" + "io" "text/template" "github.com/docker/cli/templates" - "github.com/spf13/cobra" ) // Flusher is implemented by text/tabwriter.Writer @@ -32,43 +32,26 @@ type Flusher interface { Flush() error } -func formatLabels(labels map[string]string) string { - var res string - for k, v := range labels { - s := k + "=" + v - if res == "" { - res = s - } else { - res += "," + s - } - } - return res -} - -// formatSlice formats the slice with `--format` flag. +// FormatSlice formats the slice with `--format` flag. // // --format="" (default): JSON // --format='{{json .}}': JSON lines // -// formatSlice is expected to be only used for `nerdctl OBJECT inspect` commands. -func formatSlice(cmd *cobra.Command, x []interface{}) error { +// FormatSlice is expected to be only used for `nerdctl OBJECT inspect` commands. +func FormatSlice(format string, writer io.Writer, x []interface{}) error { var tmpl *template.Template - format, err := cmd.Flags().GetString("format") - if err != nil { - return err - } switch format { case "": b, err := json.MarshalIndent(x, "", " ") if err != nil { return err } - fmt.Fprintln(cmd.OutOrStdout(), string(b)) + fmt.Fprintln(writer, string(b)) case "raw", "table", "wide": return errors.New("unsupported format: \"raw\", \"table\", and \"wide\"") default: var err error - tmpl, err = parseTemplate(format) + tmpl, err = ParseTemplate(format) if err != nil { return err } @@ -82,7 +65,7 @@ func formatSlice(cmd *cobra.Command, x []interface{}) error { } } } - if _, err = fmt.Fprintf(cmd.OutOrStdout(), b.String()+"\n"); err != nil { + if _, err = fmt.Fprintf(writer, b.String()+"\n"); err != nil { return err } } @@ -113,9 +96,9 @@ func tryRawFormat(b *bytes.Buffer, f interface{}, tmpl *template.Template) error return nil } -// parseTemplate wraps github.com/docker/cli/templates.Parse() to allow `json` as an alias of `{{json .}}`. -// parseTemplate can be removed when https://github.com/docker/cli/pull/3355 gets merged and tagged (Docker 22.XX). -func parseTemplate(format string) (*template.Template, error) { +// ParseTemplate wraps github.com/docker/cli/templates.Parse() to allow `json` as an alias of `{{json .}}`. +// ParseTemplate can be removed when https://github.com/docker/cli/pull/3355 gets merged and tagged (Docker 22.XX). +func ParseTemplate(format string) (*template.Template, error) { aliases := map[string]string{ "json": "{{json .}}", }