Skip to content

Commit

Permalink
feat!: migrate to the new progress package
Browse files Browse the repository at this point in the history
Signed-off-by: Shiwei Zhang <[email protected]>
  • Loading branch information
shizhMSFT committed Dec 30, 2024
1 parent 0db90bd commit d327a75
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 234 deletions.
10 changes: 5 additions & 5 deletions cmd/oras/internal/display/status/progress/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (

ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"oras.land/oras/cmd/oras/internal/display/status/console"
"oras.land/oras/internal/experimental/track"
"oras.land/oras/internal/progress"
)

const (
Expand All @@ -42,11 +42,11 @@ type manager struct {
updating sync.WaitGroup
renderDone chan struct{}
renderClosed chan struct{}
prompt map[track.State]string
prompt map[progress.State]string
}

// NewManager initialized a new progress manager.
func NewManager(tty *os.File, prompt map[track.State]string) (track.Manager, error) {
func NewManager(tty *os.File, prompt map[progress.State]string) (progress.Manager, error) {
c, err := console.NewConsole(tty)
if err != nil {
return nil, err
Expand Down Expand Up @@ -99,7 +99,7 @@ func (m *manager) render() {
}

// Track appends a new status with 2-line space for rendering.
func (m *manager) Track(desc ocispec.Descriptor) (track.Tracker, error) {
func (m *manager) Track(desc ocispec.Descriptor) (progress.Tracker, error) {
if m.closed() {
return nil, errManagerStopped
}
Expand All @@ -114,7 +114,7 @@ func (m *manager) Track(desc ocispec.Descriptor) (track.Tracker, error) {
return m.statusChan(s, desc), nil
}

func (m *manager) statusChan(s *status, desc ocispec.Descriptor) track.Tracker {
func (m *manager) statusChan(s *status, desc ocispec.Descriptor) progress.Tracker {
ch := make(chan *status, BufferSize)
m.updating.Add(1)
go func() {
Expand Down
10 changes: 5 additions & 5 deletions cmd/oras/internal/display/status/progress/messenger.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,27 @@ import (

ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"oras.land/oras/cmd/oras/internal/display/status/progress/humanize"
"oras.land/oras/internal/experimental/track"
"oras.land/oras/internal/progress"
)

// Messenger is progress message channel.
type Messenger struct {
ch chan *status
closed bool
desc ocispec.Descriptor
prompt map[track.State]string
prompt map[progress.State]string
}

func (m *Messenger) Update(status track.Status) error {
if status.State == track.StateInitialized {
func (m *Messenger) Update(status progress.Status) error {
if status.State == progress.StateInitialized {
m.start()
}
m.send(m.prompt[status.State], status.Offset)
return nil
}

func (m *Messenger) Fail(err error) error {
return err
return nil
}

func (m *Messenger) Close() error {
Expand Down
28 changes: 15 additions & 13 deletions cmd/oras/internal/display/status/track/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,45 +20,47 @@ import (
"os"

ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"oras.land/oras/cmd/oras/internal/display/status/progress"
"oras.land/oras/internal/experimental/track"
sprogress "oras.land/oras/cmd/oras/internal/display/status/progress"
"oras.land/oras/internal/progress"
)

type reader struct {
*track.ReadTracker
io.Reader
progress.Tracker

manager track.Manager
manager progress.Manager
}

// NewReader returns a new reader with tracked progress.
func NewReader(r io.Reader, descriptor ocispec.Descriptor, actionPrompt string, donePrompt string, tty *os.File) (*reader, error) {
prompt := map[track.State]string{
track.StateInitialized: actionPrompt,
track.StateTransmitting: actionPrompt,
track.StateTransmitted: donePrompt,
prompt := map[progress.State]string{
progress.StateInitialized: actionPrompt,
progress.StateTransmitting: actionPrompt,
progress.StateTransmitted: donePrompt,
}

manager, err := progress.NewManager(tty, prompt)
manager, err := sprogress.NewManager(tty, prompt)
if err != nil {
return nil, err
}
return managedReader(r, descriptor, manager)
}

func managedReader(r io.Reader, descriptor ocispec.Descriptor, manager track.Manager) (*reader, error) {
func managedReader(r io.Reader, descriptor ocispec.Descriptor, manager progress.Manager) (*reader, error) {
tracker, err := manager.Track(descriptor)
if err != nil {
return nil, err
}

return &reader{
ReadTracker: track.NewReadTracker(tracker, r),
manager: manager,
Reader: progress.TrackReader(tracker, r),
Tracker: tracker,
manager: manager,
}, nil
}

// StopManager stops the messenger channel and related manager.
func (r *reader) StopManager() {
r.Close()
_ = r.Tracker.Close()
_ = r.manager.Close()
}
43 changes: 27 additions & 16 deletions cmd/oras/internal/display/status/track/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,29 +25,29 @@ import (
"oras.land/oras-go/v2"
"oras.land/oras-go/v2/errdef"
"oras.land/oras-go/v2/registry"
"oras.land/oras/cmd/oras/internal/display/status/progress"
"oras.land/oras/internal/experimental/track"
sprogress "oras.land/oras/cmd/oras/internal/display/status/progress"
"oras.land/oras/internal/progress"
)

// GraphTarget is a tracked oras.GraphTarget.
type GraphTarget interface {
oras.GraphTarget
io.Closer
Report(desc ocispec.Descriptor, state track.State) error
Report(desc ocispec.Descriptor, state progress.State) error
}

type graphTarget struct {
oras.GraphTarget
manager track.Manager
manager progress.Manager
}

type referenceGraphTarget struct {
*graphTarget
}

// NewTarget creates a new tracked Target.
func NewTarget(t oras.GraphTarget, prompt map[track.State]string, tty *os.File) (GraphTarget, error) {
manager, err := progress.NewManager(tty, prompt)
func NewTarget(t oras.GraphTarget, prompt map[progress.State]string, tty *os.File) (GraphTarget, error) {
manager, err := sprogress.NewManager(tty, prompt)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -78,16 +78,19 @@ func (t *graphTarget) Push(ctx context.Context, expected ocispec.Descriptor, con
return err
}
defer r.Close()
r.Start()
if err := progress.Start(r); err != nil {
return err
}
if err := t.GraphTarget.Push(ctx, expected, r); err != nil {
if errors.Is(err, errdef.ErrAlreadyExists) {
// allowed error types in oras-go oci and memory store
r.Done()
if err := progress.Done(r); err != nil {
return err
}
}
return err
}
r.Done()
return nil
return progress.Done(r)
}

// PushReference pushes the content to the base oras.GraphTarget with tracking.
Expand All @@ -97,13 +100,14 @@ func (rgt *referenceGraphTarget) PushReference(ctx context.Context, expected oci
return err
}
defer r.Close()
r.Start()
if err := progress.Start(r); err != nil {
return err
}
err = rgt.GraphTarget.(registry.ReferencePusher).PushReference(ctx, expected, r, reference)
if err != nil {
return err
}
r.Done()
return nil
return progress.Done(r)
}

// Close closes the tracking manager.
Expand All @@ -112,9 +116,16 @@ func (t *graphTarget) Close() error {
}

// Report prompts the user with the provided state and descriptor.
func (t *graphTarget) Report(desc ocispec.Descriptor, state track.State) error {
return track.Record(t.manager, desc, track.Status{
func (t *graphTarget) Report(desc ocispec.Descriptor, state progress.State) error {
tracker, err := t.manager.Track(desc)
if err != nil {
return err
}
if err = tracker.Update(progress.Status{
State: state,
Offset: desc.Size,
})
}); err != nil {
return err
}
return tracker.Close()
}
58 changes: 33 additions & 25 deletions cmd/oras/internal/display/status/tty.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ import (
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"oras.land/oras-go/v2"
"oras.land/oras-go/v2/content"
strack "oras.land/oras/cmd/oras/internal/display/status/track"
"oras.land/oras/internal/experimental/track"
"oras.land/oras/cmd/oras/internal/display/status/track"
"oras.land/oras/internal/progress"
)

// TTYPushHandler handles TTY status output for push command.
type TTYPushHandler struct {
tty *os.File
tracked strack.GraphTarget
tracked track.GraphTarget
committed *sync.Map
fetcher content.Fetcher
}
Expand All @@ -58,13 +58,13 @@ func (ph *TTYPushHandler) OnEmptyArtifact() error {

// TrackTarget returns a tracked target.
func (ph *TTYPushHandler) TrackTarget(gt oras.GraphTarget) (oras.GraphTarget, StopTrackTargetFunc, error) {
prompt := map[track.State]string{
track.StateInitialized: PushPromptUploading,
track.StateTransmitting: PushPromptUploading,
track.StateTransmitted: PushPromptUploaded,
track.StateExists: PushPromptExists,
prompt := map[progress.State]string{
progress.StateInitialized: PushPromptUploading,
progress.StateTransmitting: PushPromptUploading,
progress.StateTransmitted: PushPromptUploaded,
progress.StateExists: PushPromptExists,
}
tracked, err := strack.NewTarget(gt, prompt, ph.tty)
tracked, err := track.NewTarget(gt, prompt, ph.tty)
if err != nil {
return nil, nil, err
}
Expand All @@ -75,7 +75,7 @@ func (ph *TTYPushHandler) TrackTarget(gt oras.GraphTarget) (oras.GraphTarget, St
// OnCopySkipped is called when an object already exists.
func (ph *TTYPushHandler) OnCopySkipped(_ context.Context, desc ocispec.Descriptor) error {
ph.committed.Store(desc.Digest.String(), desc.Annotations[ocispec.AnnotationTitle])
return ph.tracked.Report(desc, track.StateExists)
return ph.tracked.Report(desc, progress.StateExists)
}

// PreCopy implements PreCopy of CopyHandler.
Expand All @@ -91,7 +91,7 @@ func (ph *TTYPushHandler) PostCopy(ctx context.Context, desc ocispec.Descriptor)
return err
}
for _, successor := range successors {
if err = ph.tracked.Report(successor, track.StateSkipped); err != nil {
if err = ph.tracked.Report(successor, progress.StateSkipped); err != nil {
return err
}
}
Expand All @@ -106,7 +106,7 @@ func NewTTYAttachHandler(tty *os.File, fetcher content.Fetcher) AttachHandler {
// TTYPullHandler handles TTY status output for pull events.
type TTYPullHandler struct {
tty *os.File
tracked strack.GraphTarget
tracked track.GraphTarget
}

// NewTTYPullHandler returns a new handler for Pull status events.
Expand All @@ -133,24 +133,24 @@ func (ph *TTYPullHandler) OnNodeProcessing(_ ocispec.Descriptor) error {

// OnNodeRestored implements PullHandler.
func (ph *TTYPullHandler) OnNodeRestored(desc ocispec.Descriptor) error {
return ph.tracked.Report(desc, track.StateMounted)
return ph.tracked.Report(desc, progress.StateMounted)
}

// OnNodeSkipped implements PullHandler.
func (ph *TTYPullHandler) OnNodeSkipped(desc ocispec.Descriptor) error {
return ph.tracked.Report(desc, track.StateSkipped)
return ph.tracked.Report(desc, progress.StateSkipped)
}

// TrackTarget returns a tracked target.
func (ph *TTYPullHandler) TrackTarget(gt oras.GraphTarget) (oras.GraphTarget, StopTrackTargetFunc, error) {
prompt := map[track.State]string{
track.StateInitialized: PullPromptDownloading,
track.StateTransmitting: PullPromptDownloading,
track.StateTransmitted: PullPromptPulled,
track.StateSkipped: PullPromptSkipped,
track.StateMounted: PullPromptRestored,
prompt := map[progress.State]string{
progress.StateInitialized: PullPromptDownloading,
progress.StateTransmitting: PullPromptDownloading,
progress.StateTransmitted: PullPromptPulled,
progress.StateSkipped: PullPromptSkipped,
progress.StateMounted: PullPromptRestored,
}
tracked, err := strack.NewTarget(gt, prompt, ph.tty)
tracked, err := track.NewTarget(gt, prompt, ph.tty)
if err != nil {
return nil, nil, err
}
Expand All @@ -174,8 +174,16 @@ func NewTTYCopyHandler(tty *os.File) CopyHandler {

// StartTracking returns a tracked target from a graph target.
func (ch *TTYCopyHandler) StartTracking(gt oras.GraphTarget) (oras.GraphTarget, error) {
prompt := map[progress.State]string{
progress.StateInitialized: copyPromptCopying,
progress.StateTransmitting: copyPromptCopying,
progress.StateTransmitted: copyPromptCopied,
progress.StateExists: copyPromptExists,
progress.StateSkipped: copyPromptSkipped,
progress.StateMounted: copyPromptMounted,
}
var err error
ch.tracked, err = track.NewTarget(gt, copyPromptCopying, copyPromptCopied, ch.tty)
ch.tracked, err = track.NewTarget(gt, prompt, ch.tty)
if err != nil {
return nil, err
}
Expand All @@ -190,7 +198,7 @@ func (ch *TTYCopyHandler) StopTracking() error {
// OnCopySkipped is called when an object already exists.
func (ch *TTYCopyHandler) OnCopySkipped(_ context.Context, desc ocispec.Descriptor) error {
ch.committed.Store(desc.Digest.String(), desc.Annotations[ocispec.AnnotationTitle])
return ch.tracked.Prompt(desc, copyPromptExists)
return ch.tracked.Report(desc, progress.StateExists)
}

// PreCopy implements PreCopy of CopyHandler.
Expand All @@ -206,7 +214,7 @@ func (ch *TTYCopyHandler) PostCopy(ctx context.Context, desc ocispec.Descriptor)
return err
}
for _, successor := range successors {
if err = ch.tracked.Prompt(successor, copyPromptSkipped); err != nil {
if err = ch.tracked.Report(successor, progress.StateSkipped); err != nil {
return err
}
}
Expand All @@ -216,5 +224,5 @@ func (ch *TTYCopyHandler) PostCopy(ctx context.Context, desc ocispec.Descriptor)
// OnMounted implements OnMounted of CopyHandler.
func (ch *TTYCopyHandler) OnMounted(_ context.Context, desc ocispec.Descriptor) error {
ch.committed.Store(desc.Digest.String(), desc.Annotations[ocispec.AnnotationTitle])
return ch.tracked.Prompt(desc, copyPromptMounted)
return ch.tracked.Report(desc, progress.StateMounted)
}
Loading

0 comments on commit d327a75

Please sign in to comment.