From 780c7da24665ecb9a91011367474f0be4f9caaac Mon Sep 17 00:00:00 2001 From: Terry Howe Date: Sat, 22 Jun 2024 04:46:11 -0600 Subject: [PATCH] refactor: Use printer object for output (#1426) Signed-off-by: Terry Howe --- cmd/oras/root/blob/delete.go | 7 ++++--- cmd/oras/root/blob/push.go | 8 +++----- cmd/oras/root/cp.go | 7 +++---- cmd/oras/root/login.go | 13 +++++++------ cmd/oras/root/manifest/delete.go | 7 ++++--- cmd/oras/root/manifest/push.go | 6 +++--- cmd/oras/root/repo/ls.go | 5 +++-- cmd/oras/root/repo/tags.go | 8 ++++---- cmd/oras/root/resolve.go | 7 ++++--- cmd/oras/root/version.go | 10 +++++----- 10 files changed, 40 insertions(+), 38 deletions(-) diff --git a/cmd/oras/root/blob/delete.go b/cmd/oras/root/blob/delete.go index af00e63e6..349354896 100644 --- a/cmd/oras/root/blob/delete.go +++ b/cmd/oras/root/blob/delete.go @@ -27,6 +27,7 @@ import ( "oras.land/oras/cmd/oras/internal/command" oerrors "oras.land/oras/cmd/oras/internal/errors" "oras.land/oras/cmd/oras/internal/option" + "oras.land/oras/cmd/oras/internal/output" "oras.land/oras/internal/registryutil" ) @@ -73,6 +74,7 @@ Example - Delete a blob and print its descriptor: } func deleteBlob(cmd *cobra.Command, opts *deleteBlobOptions) (err error) { + printer := output.NewPrinter(cmd.OutOrStdout(), opts.Verbose) ctx, logger := command.GetLogger(cmd, &opts.Common) blobs, err := opts.NewBlobDeleter(opts.Common, logger) if err != nil { @@ -83,14 +85,13 @@ func deleteBlob(cmd *cobra.Command, opts *deleteBlobOptions) (err error) { } // add both pull and delete scope hints for dst repository to save potential delete-scope token requests during deleting - outWriter := cmd.OutOrStdout() ctx = registryutil.WithScopeHint(ctx, blobs, auth.ActionPull, auth.ActionDelete) desc, err := blobs.Resolve(ctx, opts.Reference) if err != nil { if errors.Is(err, errdef.ErrNotFound) { if opts.Force && !opts.OutputDescriptor { // ignore nonexistent - fmt.Fprintln(outWriter, "Missing", opts.RawReference) + _ = printer.Println("Missing", opts.RawReference) return nil } return fmt.Errorf("%s: the specified blob does not exist", opts.RawReference) @@ -119,7 +120,7 @@ func deleteBlob(cmd *cobra.Command, opts *deleteBlobOptions) (err error) { return opts.Output(os.Stdout, descJSON) } - fmt.Fprintln(outWriter, "Deleted", opts.AnnotatedReference()) + _ = printer.Println("Deleted", opts.AnnotatedReference()) return nil } diff --git a/cmd/oras/root/blob/push.go b/cmd/oras/root/blob/push.go index daeee8503..71b3a2864 100644 --- a/cmd/oras/root/blob/push.go +++ b/cmd/oras/root/blob/push.go @@ -18,9 +18,7 @@ package blob import ( "context" "errors" - "fmt" "io" - "oras.land/oras/cmd/oras/internal/output" "os" ocispec "github.com/opencontainers/image-spec/specs-go/v1" @@ -31,6 +29,7 @@ import ( "oras.land/oras/cmd/oras/internal/display/status/track" oerrors "oras.land/oras/cmd/oras/internal/errors" "oras.land/oras/cmd/oras/internal/option" + "oras.land/oras/cmd/oras/internal/output" "oras.land/oras/internal/file" ) @@ -139,9 +138,8 @@ func pushBlob(cmd *cobra.Command, opts *pushBlobOptions) (err error) { return opts.Output(os.Stdout, descJSON) } - outWriter := cmd.OutOrStdout() - _, _ = fmt.Fprintln(outWriter, "Pushed", opts.AnnotatedReference()) - _, _ = fmt.Fprintln(outWriter, "Digest:", desc.Digest) + _ = printer.Println("Pushed", opts.AnnotatedReference()) + _ = printer.Println("Digest:", desc.Digest) return nil } diff --git a/cmd/oras/root/cp.go b/cmd/oras/root/cp.go index 4a34357dd..4b672ae7a 100644 --- a/cmd/oras/root/cp.go +++ b/cmd/oras/root/cp.go @@ -19,7 +19,6 @@ import ( "context" "encoding/json" "fmt" - "oras.land/oras/cmd/oras/internal/output" "slices" "strings" "sync" @@ -38,6 +37,7 @@ import ( "oras.land/oras/cmd/oras/internal/display/status/track" oerrors "oras.land/oras/cmd/oras/internal/errors" "oras.land/oras/cmd/oras/internal/option" + "oras.land/oras/cmd/oras/internal/output" "oras.land/oras/internal/docker" "oras.land/oras/internal/graph" "oras.land/oras/internal/registryutil" @@ -137,8 +137,7 @@ func runCopy(cmd *cobra.Command, opts *copyOptions) error { // correct source digest opts.From.RawReference = fmt.Sprintf("%s@%s", opts.From.Path, desc.Digest.String()) } - outWriter := cmd.OutOrStdout() - fmt.Fprintln(outWriter, "Copied", opts.From.AnnotatedReference(), "=>", opts.To.AnnotatedReference()) + _ = printer.Println("Copied", opts.From.AnnotatedReference(), "=>", opts.To.AnnotatedReference()) if len(opts.extraRefs) != 0 { tagNOpts := oras.DefaultTagNOptions @@ -148,7 +147,7 @@ func runCopy(cmd *cobra.Command, opts *copyOptions) error { } } - fmt.Fprintln(outWriter, "Digest:", desc.Digest) + _ = printer.Println("Digest:", desc.Digest) return nil } diff --git a/cmd/oras/root/login.go b/cmd/oras/root/login.go index 76f68182b..566155510 100644 --- a/cmd/oras/root/login.go +++ b/cmd/oras/root/login.go @@ -29,6 +29,7 @@ import ( "oras.land/oras/cmd/oras/internal/command" oerrors "oras.land/oras/cmd/oras/internal/errors" "oras.land/oras/cmd/oras/internal/option" + "oras.land/oras/cmd/oras/internal/output" "oras.land/oras/internal/credential" orasio "oras.land/oras/internal/io" ) @@ -78,14 +79,14 @@ Example - Log in with username and password in an interactive terminal and no TL } func runLogin(cmd *cobra.Command, opts loginOptions) (err error) { + printer := output.NewPrinter(cmd.OutOrStdout(), opts.Verbose) ctx, logger := command.GetLogger(cmd, &opts.Common) - outWriter := cmd.OutOrStdout() // prompt for credential if opts.Secret == "" { if opts.Username == "" { // prompt for username - username, err := readLine(outWriter, "Username: ", false) + username, err := readLine(printer, "Username: ", false) if err != nil { return err } @@ -93,14 +94,14 @@ func runLogin(cmd *cobra.Command, opts loginOptions) (err error) { } if opts.Username == "" { // prompt for token - if opts.Secret, err = readLine(outWriter, "Token: ", true); err != nil { + if opts.Secret, err = readLine(printer, "Token: ", true); err != nil { return err } else if opts.Secret == "" { return errors.New("token required") } } else { // prompt for password - if opts.Secret, err = readLine(outWriter, "Password: ", true); err != nil { + if opts.Secret, err = readLine(printer, "Password: ", true); err != nil { return err } else if opts.Secret == "" { return errors.New("password required") @@ -119,12 +120,12 @@ func runLogin(cmd *cobra.Command, opts loginOptions) (err error) { if err = credentials.Login(ctx, store, remote, opts.Credential()); err != nil { return err } - fmt.Fprintln(outWriter, "Login Succeeded") + _ = printer.Println("Login Succeeded") return nil } func readLine(outWriter io.Writer, prompt string, silent bool) (string, error) { - fmt.Fprint(outWriter, prompt) + _, _ = fmt.Fprint(outWriter, prompt) fd := int(os.Stdin.Fd()) var bytes []byte var err error diff --git a/cmd/oras/root/manifest/delete.go b/cmd/oras/root/manifest/delete.go index 2d1aa7988..3664f287c 100644 --- a/cmd/oras/root/manifest/delete.go +++ b/cmd/oras/root/manifest/delete.go @@ -27,6 +27,7 @@ import ( "oras.land/oras/cmd/oras/internal/command" oerrors "oras.land/oras/cmd/oras/internal/errors" "oras.land/oras/cmd/oras/internal/option" + "oras.land/oras/cmd/oras/internal/output" "oras.land/oras/internal/registryutil" ) @@ -77,6 +78,7 @@ Example - Delete a manifest by digest 'sha256:99e4703fbf30916f549cd6bfa9cdbab614 } func deleteManifest(cmd *cobra.Command, opts *deleteOptions) error { + printer := output.NewPrinter(cmd.OutOrStdout(), opts.Verbose) ctx, logger := command.GetLogger(cmd, &opts.Common) manifests, err := opts.NewManifestDeleter(opts.Common, logger) if err != nil { @@ -92,14 +94,13 @@ func deleteManifest(cmd *cobra.Command, opts *deleteOptions) error { // possibly needed when adding a new referrers index hints = append(hints, auth.ActionPush) } - outWriter := cmd.OutOrStdout() ctx = registryutil.WithScopeHint(ctx, manifests, hints...) desc, err := manifests.Resolve(ctx, opts.Reference) if err != nil { if errors.Is(err, errdef.ErrNotFound) { if opts.Force && !opts.OutputDescriptor { // ignore nonexistent - fmt.Fprintln(outWriter, "Missing", opts.RawReference) + _ = printer.Println("Missing", opts.RawReference) return nil } return fmt.Errorf("%s: the specified manifest does not exist", opts.RawReference) @@ -128,7 +129,7 @@ func deleteManifest(cmd *cobra.Command, opts *deleteOptions) error { return opts.Output(os.Stdout, descJSON) } - fmt.Fprintln(outWriter, "Deleted", opts.AnnotatedReference()) + _ = printer.Println("Deleted", opts.AnnotatedReference()) return nil } diff --git a/cmd/oras/root/manifest/push.go b/cmd/oras/root/manifest/push.go index 344953db0..194d04d6d 100644 --- a/cmd/oras/root/manifest/push.go +++ b/cmd/oras/root/manifest/push.go @@ -19,7 +19,6 @@ import ( "context" "errors" "fmt" - "oras.land/oras/cmd/oras/internal/output" "os" "strings" @@ -35,6 +34,7 @@ import ( oerrors "oras.land/oras/cmd/oras/internal/errors" "oras.land/oras/cmd/oras/internal/manifest" "oras.land/oras/cmd/oras/internal/option" + "oras.land/oras/cmd/oras/internal/output" "oras.land/oras/internal/file" ) @@ -189,14 +189,14 @@ func pushManifest(cmd *cobra.Command, opts pushOptions) error { } return opts.Output(os.Stdout, descJSON) } - printer.Println("Pushed", opts.AnnotatedReference()) + _ = printer.Println("Pushed", opts.AnnotatedReference()) if len(opts.extraRefs) != 0 { if _, err = oras.TagBytesN(ctx, status.NewTagStatusPrinter(printer, target), mediaType, contentBytes, opts.extraRefs, tagBytesNOpts); err != nil { return err } } - fmt.Fprintln(cmd.OutOrStdout(), "Digest:", desc.Digest) + _ = printer.Println("Digest:", desc.Digest) return nil } diff --git a/cmd/oras/root/repo/ls.go b/cmd/oras/root/repo/ls.go index d5215ab0f..8b989e959 100644 --- a/cmd/oras/root/repo/ls.go +++ b/cmd/oras/root/repo/ls.go @@ -25,6 +25,7 @@ import ( "oras.land/oras/cmd/oras/internal/command" oerrors "oras.land/oras/cmd/oras/internal/errors" "oras.land/oras/cmd/oras/internal/option" + "oras.land/oras/cmd/oras/internal/output" "oras.land/oras/internal/repository" ) @@ -72,16 +73,16 @@ Example - List the repositories under the registry that include values lexically } func listRepository(cmd *cobra.Command, opts *repositoryOptions) error { + printer := output.NewPrinter(cmd.OutOrStdout(), opts.Verbose) ctx, logger := command.GetLogger(cmd, &opts.Common) reg, err := opts.Remote.NewRegistry(opts.hostname, opts.Common, logger) if err != nil { return err } err = reg.Repositories(ctx, opts.last, func(repos []string) error { - outWriter := cmd.OutOrStdout() for _, repo := range repos { if subRepo, found := strings.CutPrefix(repo, opts.namespace); found { - fmt.Fprintln(outWriter, subRepo) + _ = printer.Println(subRepo) } } return nil diff --git a/cmd/oras/root/repo/tags.go b/cmd/oras/root/repo/tags.go index b3daaffb1..1994d048f 100644 --- a/cmd/oras/root/repo/tags.go +++ b/cmd/oras/root/repo/tags.go @@ -16,7 +16,6 @@ limitations under the License. package repo import ( - "fmt" "strings" "github.com/opencontainers/go-digest" @@ -25,6 +24,7 @@ import ( "oras.land/oras/cmd/oras/internal/command" oerrors "oras.land/oras/cmd/oras/internal/errors" "oras.land/oras/cmd/oras/internal/option" + "oras.land/oras/cmd/oras/internal/output" "oras.land/oras/internal/contentutil" ) @@ -81,6 +81,7 @@ Example - [Experimental] Show tags associated with a digest: } func showTags(cmd *cobra.Command, opts *showTagsOptions) error { + printer := output.NewPrinter(cmd.OutOrStdout(), opts.Verbose) ctx, logger := command.GetLogger(cmd, &opts.Common) finder, err := opts.NewReadonlyTarget(ctx, opts.Common, logger) if err != nil { @@ -99,7 +100,6 @@ func showTags(cmd *cobra.Command, opts *showTagsOptions) error { } logger.Warnf("[Experimental] querying tags associated to %s, it may take a while...\n", filter) } - outWriter := cmd.OutOrStdout() return finder.Tags(ctx, opts.last, func(tags []string) error { for _, tag := range tags { if opts.excludeDigestTag && isDigestTag(tag) { @@ -107,7 +107,7 @@ func showTags(cmd *cobra.Command, opts *showTagsOptions) error { } if filter != "" { if tag == opts.Reference { - fmt.Fprintln(outWriter, tag) + _ = printer.Println(tag) continue } desc, err := finder.Resolve(ctx, tag) @@ -118,7 +118,7 @@ func showTags(cmd *cobra.Command, opts *showTagsOptions) error { continue } } - fmt.Fprintln(outWriter, tag) + _ = printer.Println(tag) } return nil }) diff --git a/cmd/oras/root/resolve.go b/cmd/oras/root/resolve.go index ed4f826b0..68e94df32 100644 --- a/cmd/oras/root/resolve.go +++ b/cmd/oras/root/resolve.go @@ -24,6 +24,7 @@ import ( "oras.land/oras/cmd/oras/internal/command" oerrors "oras.land/oras/cmd/oras/internal/errors" "oras.land/oras/cmd/oras/internal/option" + "oras.land/oras/cmd/oras/internal/output" ) type resolveOptions struct { @@ -62,6 +63,7 @@ Example - Resolve digest of the target artifact: } func runResolve(cmd *cobra.Command, opts *resolveOptions) error { + printer := output.NewPrinter(cmd.OutOrStdout(), opts.Verbose) ctx, logger := command.GetLogger(cmd, &opts.Common) repo, err := opts.NewReadonlyTarget(ctx, opts.Common, logger) if err != nil { @@ -78,11 +80,10 @@ func runResolve(cmd *cobra.Command, opts *resolveOptions) error { return fmt.Errorf("failed to resolve digest: %w", err) } - outWriter := cmd.OutOrStdout() if opts.fullRef { - fmt.Fprintf(outWriter, "%s@%s\n", opts.Path, desc.Digest) + _ = printer.Printf("%s@%s\n", opts.Path, desc.Digest) } else { - fmt.Fprintln(outWriter, desc.Digest.String()) + _ = printer.Println(desc.Digest.String()) } return nil diff --git a/cmd/oras/root/version.go b/cmd/oras/root/version.go index a071744fc..ede9abf96 100644 --- a/cmd/oras/root/version.go +++ b/cmd/oras/root/version.go @@ -17,13 +17,13 @@ package root import ( "fmt" - "io" "os" "runtime" "strings" "github.com/spf13/cobra" + "oras.land/oras/cmd/oras/internal/output" "oras.land/oras/internal/version" ) @@ -46,15 +46,15 @@ Example - print version: return nil }, RunE: func(cmd *cobra.Command, args []string) error { - outWriter := cmd.OutOrStdout() - return runVersion(outWriter) + printer := output.NewPrinter(cmd.OutOrStdout(), false) + return runVersion(printer) }, } return cmd } -func runVersion(outWriter io.Writer) error { +func runVersion(printer *output.Printer) error { items := [][]string{ {"Version", version.GetVersion()}, {"Go version", runtime.Version()}, @@ -73,7 +73,7 @@ func runVersion(outWriter io.Writer) error { } } for _, item := range items { - fmt.Fprintln(outWriter, item[0]+": "+strings.Repeat(" ", size-len(item[0]))+item[1]) + _ = printer.Println(item[0] + ": " + strings.Repeat(" ", size-len(item[0])) + item[1]) } return nil