Skip to content

Commit

Permalink
feat: Use cobra.Command.OutOrStdout method for output (#1288)
Browse files Browse the repository at this point in the history
Signed-off-by: Terry Howe <[email protected]>
  • Loading branch information
Terry Howe authored Mar 18, 2024
1 parent f1d319f commit bdc5696
Show file tree
Hide file tree
Showing 12 changed files with 51 additions and 37 deletions.
5 changes: 3 additions & 2 deletions cmd/oras/root/blob/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,14 @@ 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.Println("Missing", opts.RawReference)
fmt.Fprintln(outWriter, "Missing", opts.RawReference)
return nil
}
return fmt.Errorf("%s: the specified blob does not exist", opts.RawReference)
Expand Down Expand Up @@ -117,7 +118,7 @@ func deleteBlob(cmd *cobra.Command, opts *deleteBlobOptions) (err error) {
return opts.Output(os.Stdout, descJSON)
}

fmt.Println("Deleted", opts.AnnotatedReference())
fmt.Fprintln(outWriter, "Deleted", opts.AnnotatedReference())

return nil
}
5 changes: 3 additions & 2 deletions cmd/oras/root/blob/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,9 @@ func pushBlob(cmd *cobra.Command, opts *pushBlobOptions) (err error) {
return opts.Output(os.Stdout, descJSON)
}

fmt.Println("Pushed", opts.AnnotatedReference())
fmt.Println("Digest:", desc.Digest)
outWriter := cmd.OutOrStdout()
fmt.Fprintln(outWriter, "Pushed", opts.AnnotatedReference())
fmt.Fprintln(outWriter, "Digest:", desc.Digest)

return nil
}
Expand Down
5 changes: 3 additions & 2 deletions cmd/oras/root/cp.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ func runCopy(cmd *cobra.Command, opts *copyOptions) error {
// correct source digest
opts.From.RawReference = fmt.Sprintf("%s@%s", opts.From.Path, desc.Digest.String())
}
fmt.Println("Copied", opts.From.AnnotatedReference(), "=>", opts.To.AnnotatedReference())
outWriter := cmd.OutOrStdout()
fmt.Fprintln(outWriter, "Copied", opts.From.AnnotatedReference(), "=>", opts.To.AnnotatedReference())

if len(opts.extraRefs) != 0 {
tagNOpts := oras.DefaultTagNOptions
Expand All @@ -144,7 +145,7 @@ func runCopy(cmd *cobra.Command, opts *copyOptions) error {
}
}

fmt.Println("Digest:", desc.Digest)
fmt.Fprintln(outWriter, "Digest:", desc.Digest)

return nil
}
Expand Down
16 changes: 9 additions & 7 deletions cmd/oras/root/discover.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"context"
"encoding/json"
"fmt"
"io"
"os"
"strings"

Expand Down Expand Up @@ -127,15 +128,16 @@ func runDiscover(cmd *cobra.Command, opts *discoverOptions) error {
return printDiscoveredReferrersJSON(desc, refs)
}

outWriter := cmd.OutOrStdout()
if n := len(refs); n > 1 {
fmt.Println("Discovered", n, "artifacts referencing", opts.Reference)
fmt.Fprintln(outWriter, "Discovered", n, "artifacts referencing", opts.Reference)
} else {
fmt.Println("Discovered", n, "artifact referencing", opts.Reference)
fmt.Fprintln(outWriter, "Discovered", n, "artifact referencing", opts.Reference)
}
fmt.Println("Digest:", desc.Digest)
fmt.Fprintln(outWriter, "Digest:", desc.Digest)
if len(refs) > 0 {
fmt.Println()
_ = printDiscoveredReferrersTable(refs, opts.Verbose)
fmt.Fprintln(outWriter)
_ = printDiscoveredReferrersTable(outWriter, refs, opts.Verbose)
}
return nil
}
Expand Down Expand Up @@ -173,7 +175,7 @@ func fetchAllReferrers(ctx context.Context, repo oras.ReadOnlyGraphTarget, desc
return nil
}

func printDiscoveredReferrersTable(refs []ocispec.Descriptor, verbose bool) error {
func printDiscoveredReferrersTable(outWriter io.Writer, refs []ocispec.Descriptor, verbose bool) error {
typeNameTitle := "Artifact Type"
typeNameLength := len(typeNameTitle)
for _, ref := range refs {
Expand All @@ -183,7 +185,7 @@ func printDiscoveredReferrersTable(refs []ocispec.Descriptor, verbose bool) erro
}

print := func(key string, value interface{}) {
fmt.Println(key, strings.Repeat(" ", typeNameLength-len(key)+1), value)
fmt.Fprintln(outWriter, key, strings.Repeat(" ", typeNameLength-len(key)+1), value)
}

print(typeNameTitle, "Digest")
Expand Down
20 changes: 11 additions & 9 deletions cmd/oras/root/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package root
import (
"errors"
"fmt"
"io"
"os"
"strings"

Expand All @@ -28,7 +29,7 @@ import (
oerrors "oras.land/oras/cmd/oras/internal/errors"
"oras.land/oras/cmd/oras/internal/option"
"oras.land/oras/internal/credential"
"oras.land/oras/internal/io"
orasio "oras.land/oras/internal/io"
)

type loginOptions struct {
Expand Down Expand Up @@ -77,27 +78,28 @@ Example - Log in with username and password in an interactive terminal and no TL

func runLogin(cmd *cobra.Command, opts loginOptions) (err error) {
ctx, logger := opts.WithContext(cmd.Context())
outWriter := cmd.OutOrStdout()

// prompt for credential
if opts.Password == "" {
if opts.Username == "" {
// prompt for username
username, err := readLine("Username: ", false)
username, err := readLine(outWriter, "Username: ", false)
if err != nil {
return err
}
opts.Username = strings.TrimSpace(username)
}
if opts.Username == "" {
// prompt for token
if opts.Password, err = readLine("Token: ", true); err != nil {
if opts.Password, err = readLine(outWriter, "Token: ", true); err != nil {
return err
} else if opts.Password == "" {
return errors.New("token required")
}
} else {
// prompt for password
if opts.Password, err = readLine("Password: ", true); err != nil {
if opts.Password, err = readLine(outWriter, "Password: ", true); err != nil {
return err
} else if opts.Password == "" {
return errors.New("password required")
Expand All @@ -116,21 +118,21 @@ func runLogin(cmd *cobra.Command, opts loginOptions) (err error) {
if err = credentials.Login(ctx, store, remote, opts.Credential()); err != nil {
return err
}
fmt.Println("Login Succeeded")
fmt.Fprintln(outWriter, "Login Succeeded")
return nil
}

func readLine(prompt string, silent bool) (string, error) {
fmt.Print(prompt)
func readLine(outWriter io.Writer, prompt string, silent bool) (string, error) {
fmt.Fprint(outWriter, prompt)
fd := int(os.Stdin.Fd())
var bytes []byte
var err error
if silent && term.IsTerminal(fd) {
if bytes, err = term.ReadPassword(fd); err == nil {
_, err = fmt.Println()
_, err = fmt.Fprintln(outWriter)
}
} else {
bytes, err = io.ReadLine(os.Stdin)
bytes, err = orasio.ReadLine(os.Stdin)
}
if err != nil {
return "", err
Expand Down
5 changes: 3 additions & 2 deletions cmd/oras/root/manifest/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,14 @@ 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.Println("Missing", opts.RawReference)
fmt.Fprintln(outWriter, "Missing", opts.RawReference)
return nil
}
return fmt.Errorf("%s: the specified manifest does not exist", opts.RawReference)
Expand Down Expand Up @@ -126,7 +127,7 @@ func deleteManifest(cmd *cobra.Command, opts *deleteOptions) error {
return opts.Output(os.Stdout, descJSON)
}

fmt.Println("Deleted", opts.AnnotatedReference())
fmt.Fprintln(outWriter, "Deleted", opts.AnnotatedReference())

return nil
}
2 changes: 1 addition & 1 deletion cmd/oras/root/manifest/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ func pushManifest(cmd *cobra.Command, opts pushOptions) error {
}
}

fmt.Println("Digest:", desc.Digest)
fmt.Fprintln(cmd.OutOrStdout(), "Digest:", desc.Digest)

return nil
}
Expand Down
9 changes: 5 additions & 4 deletions cmd/oras/root/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,13 @@ func runPull(cmd *cobra.Command, opts *pullOptions) error {
}

// suggest oras copy for pulling layers without annotation
outWriter := cmd.OutOrStdout()
if layerSkipped {
fmt.Printf("Skipped pulling layers without file name in %q\n", ocispec.AnnotationTitle)
fmt.Printf("Use 'oras copy %s --to-oci-layout <layout-dir>' to pull all layers.\n", opts.RawReference)
fmt.Fprintf(outWriter, "Skipped pulling layers without file name in %q\n", ocispec.AnnotationTitle)
fmt.Fprintf(outWriter, "Use 'oras copy %s --to-oci-layout <layout-dir>' to pull all layers.\n", opts.RawReference)
} else {
fmt.Println("Pulled", opts.AnnotatedReference())
fmt.Println("Digest:", desc.Digest)
fmt.Fprintln(outWriter, "Pulled", opts.AnnotatedReference())
fmt.Fprintln(outWriter, "Digest:", desc.Digest)
}
return nil
}
Expand Down
3 changes: 2 additions & 1 deletion cmd/oras/root/repo/ls.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,10 @@ func listRepository(cmd *cobra.Command, opts *repositoryOptions) error {
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.Println(subRepo)
fmt.Fprintln(outWriter, subRepo)
}
}
return nil
Expand Down
5 changes: 3 additions & 2 deletions cmd/oras/root/repo/tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,15 @@ 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) {
continue
}
if filter != "" {
if tag == opts.Reference {
fmt.Println(tag)
fmt.Fprintln(outWriter, tag)
continue
}
desc, err := finder.Resolve(ctx, tag)
Expand All @@ -116,7 +117,7 @@ func showTags(cmd *cobra.Command, opts *showTagsOptions) error {
continue
}
}
fmt.Println(tag)
fmt.Fprintln(outWriter, tag)
}
return nil
})
Expand Down
5 changes: 3 additions & 2 deletions cmd/oras/root/resolve.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,11 @@ func runResolve(cmd *cobra.Command, opts *resolveOptions) error {
return fmt.Errorf("failed to resolve digest: %w", err)
}

outWriter := cmd.OutOrStdout()
if opts.fullRef {
fmt.Printf("%s@%s\n", opts.Path, desc.Digest)
fmt.Fprintf(outWriter, "%s@%s\n", opts.Path, desc.Digest)
} else {
fmt.Println(desc.Digest.String())
fmt.Fprintln(outWriter, desc.Digest.String())
}

return nil
Expand Down
8 changes: 5 additions & 3 deletions cmd/oras/root/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package root

import (
"fmt"
"io"
"os"
"runtime"
"strings"
Expand Down Expand Up @@ -45,14 +46,15 @@ Example - print version:
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
return runVersion()
outWriter := cmd.OutOrStdout()
return runVersion(outWriter)
},
}

return cmd
}

func runVersion() error {
func runVersion(outWriter io.Writer) error {
items := [][]string{
{"Version", version.GetVersion()},
{"Go version", runtime.Version()},
Expand All @@ -71,7 +73,7 @@ func runVersion() error {
}
}
for _, item := range items {
fmt.Println(item[0] + ": " + strings.Repeat(" ", size-len(item[0])) + item[1])
fmt.Fprintln(outWriter, item[0]+": "+strings.Repeat(" ", size-len(item[0]))+item[1])
}

return nil
Expand Down

0 comments on commit bdc5696

Please sign in to comment.