Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: add stdout to metadata handlers #1312

Merged
merged 4 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions cmd/oras/internal/display/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ limitations under the License.
package display

import (
"io"
"os"

"oras.land/oras/cmd/oras/internal/display/metadata"
Expand All @@ -26,7 +27,7 @@ import (
)

// NewPushHandler returns status and metadata handlers for push command.
func NewPushHandler(format string, tty *os.File, verbose bool) (status.PushHandler, metadata.PushHandler) {
func NewPushHandler(format string, tty *os.File, out io.Writer, verbose bool) (status.PushHandler, metadata.PushHandler) {
var statusHandler status.PushHandler
if tty != nil {
statusHandler = status.NewTTYPushHandler(tty)
Expand All @@ -39,18 +40,18 @@ func NewPushHandler(format string, tty *os.File, verbose bool) (status.PushHandl
var metadataHandler metadata.PushHandler
switch format {
case "":
metadataHandler = text.NewPushHandler()
metadataHandler = text.NewPushHandler(out)
case "json":
metadataHandler = json.NewPushHandler()
metadataHandler = json.NewPushHandler(out)
default:
metadataHandler = template.NewPushHandler(format)
metadataHandler = template.NewPushHandler(out, format)
}

return statusHandler, metadataHandler
}

// NewAttachHandler returns status and metadata handlers for attach command.
func NewAttachHandler(format string, tty *os.File, verbose bool) (status.AttachHandler, metadata.AttachHandler) {
func NewAttachHandler(format string, tty *os.File, out io.Writer, verbose bool) (status.AttachHandler, metadata.AttachHandler) {
var statusHandler status.AttachHandler
if tty != nil {
statusHandler = status.NewTTYAttachHandler(tty)
Expand All @@ -63,11 +64,11 @@ func NewAttachHandler(format string, tty *os.File, verbose bool) (status.AttachH
var metadataHandler metadata.AttachHandler
switch format {
case "":
metadataHandler = text.NewAttachHandler()
metadataHandler = text.NewAttachHandler(out)
case "json":
metadataHandler = json.NewAttachHandler()
metadataHandler = json.NewAttachHandler(out)
default:
metadataHandler = template.NewAttachHandler(format)
metadataHandler = template.NewAttachHandler(out, format)
}

return statusHandler, metadataHandler
Expand Down
16 changes: 11 additions & 5 deletions cmd/oras/internal/display/metadata/json/attach.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,27 @@ limitations under the License.
package json

import (
"io"

ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"oras.land/oras/cmd/oras/internal/display/metadata"
"oras.land/oras/cmd/oras/internal/display/metadata/model"
"oras.land/oras/cmd/oras/internal/option"
)

// AttachHandler handles json metadata output for attach events.
type AttachHandler struct{}
type AttachHandler struct {
out io.Writer
}

// NewAttachHandler creates a new handler for attach events.
func NewAttachHandler() metadata.AttachHandler {
return AttachHandler{}
func NewAttachHandler(out io.Writer) metadata.AttachHandler {
return &AttachHandler{
out: out,
}
}

// OnCompleted is called when the attach command is completed.
func (AttachHandler) OnCompleted(opts *option.Target, root, subject ocispec.Descriptor) error {
return printJSON(model.NewPush(root, opts.Path))
func (ah *AttachHandler) OnCompleted(opts *option.Target, root, subject ocispec.Descriptor) error {
return printJSON(ah.out, model.NewPush(root, opts.Path))
}
6 changes: 3 additions & 3 deletions cmd/oras/internal/display/metadata/json/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ package json

import (
"encoding/json"
"os"
"io"
)

func printJSON(object any) error {
encoder := json.NewEncoder(os.Stdout)
func printJSON(out io.Writer, object any) error {
encoder := json.NewEncoder(out)
encoder.SetIndent("", " ")
return encoder.Encode(object)
}
11 changes: 8 additions & 3 deletions cmd/oras/internal/display/metadata/json/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ limitations under the License.
package json

import (
"io"

ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"oras.land/oras/cmd/oras/internal/display/metadata"
"oras.land/oras/cmd/oras/internal/display/metadata/model"
Expand All @@ -25,11 +27,14 @@ import (
// PushHandler handles JSON metadata output for push events.
type PushHandler struct {
path string
out io.Writer
}

// NewPushHandler creates a new handler for push events.
func NewPushHandler() metadata.PushHandler {
return &PushHandler{}
func NewPushHandler(out io.Writer) metadata.PushHandler {
return &PushHandler{
out: out,
}
}

// OnCopied is called after files are copied.
Expand All @@ -40,5 +45,5 @@ func (ph *PushHandler) OnCopied(opts *option.Target) error {

// OnCompleted is called after the push is completed.
func (ph *PushHandler) OnCompleted(root ocispec.Descriptor) error {
return printJSON(model.NewPush(root, ph.path))
return printJSON(ph.out, model.NewPush(root, ph.path))
}
12 changes: 9 additions & 3 deletions cmd/oras/internal/display/metadata/template/attach.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ limitations under the License.
package template

import (
"io"

ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"oras.land/oras/cmd/oras/internal/display/metadata"
"oras.land/oras/cmd/oras/internal/display/metadata/model"
Expand All @@ -25,14 +27,18 @@ import (
// AttachHandler handles go-template metadata output for attach events.
type AttachHandler struct {
template string
out io.Writer
}

// NewAttachHandler returns a new handler for attach metadata events.
func NewAttachHandler(template string) metadata.AttachHandler {
return &AttachHandler{template: template}
func NewAttachHandler(out io.Writer, template string) metadata.AttachHandler {
return &AttachHandler{
out: out,
template: template,
}
}

// OnCompleted formats the metadata of attach command.
func (ah *AttachHandler) OnCompleted(opts *option.Target, root, subject ocispec.Descriptor) error {
return parseAndWrite(model.NewPush(root, opts.Path), ah.template)
return parseAndWrite(ah.out, model.NewPush(root, opts.Path), ah.template)
}
12 changes: 9 additions & 3 deletions cmd/oras/internal/display/metadata/template/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ limitations under the License.
package template

import (
"io"

ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"oras.land/oras/cmd/oras/internal/display/metadata"
"oras.land/oras/cmd/oras/internal/display/metadata/model"
Expand All @@ -26,11 +28,15 @@ import (
type PushHandler struct {
template string
path string
out io.Writer
}

// NewPushHandler returns a new handler for push events.
func NewPushHandler(template string) metadata.PushHandler {
return &PushHandler{template: template}
func NewPushHandler(out io.Writer, template string) metadata.PushHandler {
return &PushHandler{
out: out,
template: template,
}
}

// OnStarted is called after files are copied.
Expand All @@ -41,5 +47,5 @@ func (ph *PushHandler) OnCopied(opts *option.Target) error {

// OnCompleted is called after the push is completed.
func (ph *PushHandler) OnCompleted(root ocispec.Descriptor) error {
return parseAndWrite(model.NewPush(root, ph.path), ph.template)
return parseAndWrite(ph.out, model.NewPush(root, ph.path), ph.template)
}
6 changes: 3 additions & 3 deletions cmd/oras/internal/display/metadata/template/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ limitations under the License.
package template

import (
"os"
"io"
"text/template"

"github.com/Masterminds/sprig/v3"
)

func parseAndWrite(object any, templateStr string) error {
func parseAndWrite(out io.Writer, object any, templateStr string) error {
t, err := template.New("format output").Funcs(sprig.FuncMap()).Parse(templateStr)
if err != nil {
return err
}
return t.Execute(os.Stdout, object)
return t.Execute(out, object)
}
17 changes: 11 additions & 6 deletions cmd/oras/internal/display/metadata/text/attach.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package text

import (
"fmt"
"io"
"strings"

ocispec "github.com/opencontainers/image-spec/specs-go/v1"
Expand All @@ -25,23 +26,27 @@ import (
)

// AttachHandler handles text metadata output for attach events.
type AttachHandler struct{}
type AttachHandler struct {
out io.Writer
}

// NewAttachHandler returns a new handler for attach events.
func NewAttachHandler() metadata.AttachHandler {
return AttachHandler{}
func NewAttachHandler(out io.Writer) metadata.AttachHandler {
return &AttachHandler{
out: out,
}
}

// OnCompleted is called when the attach command is completed.
func (AttachHandler) OnCompleted(opts *option.Target, root, subject ocispec.Descriptor) error {
func (ah *AttachHandler) OnCompleted(opts *option.Target, root, subject ocispec.Descriptor) error {
digest := subject.Digest.String()
if !strings.HasSuffix(opts.RawReference, digest) {
opts.RawReference = fmt.Sprintf("%s@%s", opts.Path, subject.Digest)
}
_, err := fmt.Println("Attached to", opts.AnnotatedReference())
_, err := fmt.Fprintln(ah.out, "Attached to", opts.AnnotatedReference())
if err != nil {
return err
}
_, err = fmt.Println("Digest:", root.Digest)
_, err = fmt.Fprintln(ah.out, "Digest:", root.Digest)
return err
}
19 changes: 12 additions & 7 deletions cmd/oras/internal/display/metadata/text/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,33 @@ package text

import (
"fmt"
"io"

ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"oras.land/oras/cmd/oras/internal/display/metadata"
"oras.land/oras/cmd/oras/internal/option"
)

// PushHandler handles text metadata output for push events.
type PushHandler struct{}
type PushHandler struct {
out io.Writer
}

// NewPushHandler returns a new handler for push events.
func NewPushHandler() metadata.PushHandler {
return PushHandler{}
func NewPushHandler(out io.Writer) metadata.PushHandler {
return &PushHandler{
out: out,
}
}

// OnCopied is called after files are copied.
func (PushHandler) OnCopied(opts *option.Target) error {
_, err := fmt.Println("Pushed", opts.AnnotatedReference())
func (p *PushHandler) OnCopied(opts *option.Target) error {
_, err := fmt.Fprintln(p.out, "Pushed", opts.AnnotatedReference())
return err
}

// OnCompleted is called after the push is completed.
func (PushHandler) OnCompleted(root ocispec.Descriptor) error {
_, err := fmt.Println("Digest:", root.Digest)
func (p *PushHandler) OnCompleted(root ocispec.Descriptor) error {
_, err := fmt.Fprintln(p.out, "Digest:", root.Digest)
return err
}
2 changes: 1 addition & 1 deletion cmd/oras/root/attach.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ func runAttach(cmd *cobra.Command, opts *attachOptions) error {
Recommendation: `To attach to an existing artifact, please provide files via argument or annotations via flag "--annotation". Run "oras attach -h" for more options and examples`,
}
}
displayStatus, displayMetadata := display.NewAttachHandler(opts.Template, opts.TTY, opts.Verbose)
displayStatus, displayMetadata := display.NewAttachHandler(opts.Template, opts.TTY, cmd.OutOrStdout(), opts.Verbose)

// prepare manifest
store, err := file.New("")
Expand Down
2 changes: 1 addition & 1 deletion cmd/oras/root/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ func runPush(cmd *cobra.Command, opts *pushOptions) error {
if err != nil {
return err
}
displayStatus, displayMetadata := display.NewPushHandler(opts.Template, opts.TTY, opts.Verbose)
displayStatus, displayMetadata := display.NewPushHandler(opts.Template, opts.TTY, cmd.OutOrStdout(), opts.Verbose)

// prepare pack
packOpts := oras.PackManifestOptions{
Expand Down
Loading