Skip to content

Commit

Permalink
feat: support progress output in pull (#1148)
Browse files Browse the repository at this point in the history
Signed-off-by: Billy Zha <[email protected]>
  • Loading branch information
qweeah authored Oct 27, 2023
1 parent 264df60 commit 9ec4f1b
Show file tree
Hide file tree
Showing 9 changed files with 211 additions and 68 deletions.
2 changes: 1 addition & 1 deletion cmd/oras/internal/display/progress/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const (
bufFlushDuration = 200 * time.Millisecond
)

var errManagerStopped = errors.New("progress output manage has already been stopped")
var errManagerStopped = errors.New("progress output manager has already been stopped")

// Status is print message channel
type Status chan *status
Expand Down
4 changes: 2 additions & 2 deletions cmd/oras/internal/display/track/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import (
type GraphTarget interface {
oras.GraphTarget
io.Closer
Prompt(desc ocispec.Descriptor, prompt string, verbose bool) error
Prompt(desc ocispec.Descriptor, prompt string) error
}

type graphTarget struct {
Expand Down Expand Up @@ -102,7 +102,7 @@ func (t *graphTarget) Close() error {
}

// Prompt prompts the user with the provided prompt and descriptor.
func (t *graphTarget) Prompt(desc ocispec.Descriptor, prompt string, verbose bool) error {
func (t *graphTarget) Prompt(desc ocispec.Descriptor, prompt string) error {
status, err := t.manager.Add()
if err != nil {
return err
Expand Down
112 changes: 112 additions & 0 deletions cmd/oras/internal/display/track/target_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
Copyright The ORAS Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package track

import (
"bytes"
"context"
"io"
"testing"

"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"oras.land/oras-go/v2"
"oras.land/oras-go/v2/content/memory"
"oras.land/oras/cmd/oras/internal/display/console/testutils"
)

type testReferenceGraphTarget struct {
oras.GraphTarget
}

func (t *testReferenceGraphTarget) PushReference(ctx context.Context, expected ocispec.Descriptor, content io.Reader, reference string) error {
err := t.GraphTarget.Push(ctx, expected, content)
if err != nil {
return err
}
return t.GraphTarget.Tag(ctx, expected, reference)
}

func Test_referenceGraphTarget_PushReference(t *testing.T) {
// prepare
pty, device, err := testutils.NewPty()
if err != nil {
t.Fatal(err)
}
defer device.Close()
src := memory.New()
content := []byte("test")
r := bytes.NewReader(content)
desc := ocispec.Descriptor{
MediaType: "application/octet-stream",
Digest: digest.FromBytes(content),
Size: int64(len(content)),
}
// test
tag := "tagged"
actionPrompt := "action"
donePrompt := "done"
target, err := NewTarget(&testReferenceGraphTarget{src}, actionPrompt, donePrompt, device)
if err != nil {
t.Fatal(err)
}
if rgt, ok := target.(*referenceGraphTarget); ok {
if err := rgt.PushReference(context.Background(), desc, r, tag); err != nil {
t.Fatal(err)
}
if err := rgt.manager.Close(); err != nil {
t.Fatal(err)
}
} else {
t.Fatal("not testing based on a referenceGraphTarget")
}
// validate
if err = testutils.MatchPty(pty, device, donePrompt, desc.MediaType, "100.00%", desc.Digest.String()); err != nil {
t.Fatal(err)
}
}

func Test_referenceGraphTarget_Prompt(t *testing.T) {
// prepare
pty, device, err := testutils.NewPty()
if err != nil {
t.Fatal(err)
}
defer device.Close()
content := []byte("test")
desc := ocispec.Descriptor{
MediaType: "application/octet-stream",
Digest: digest.FromBytes(content),
Size: int64(len(content)),
}
// test
prompt := "prompt"
target, err := NewTarget(memory.New(), "action", "done", device)
if err != nil {
t.Fatal(err)
}
m := target.(*graphTarget).manager
if err := target.Prompt(desc, prompt); err != nil {
t.Fatal(err)
}
if err := m.Close(); err != nil {
t.Fatal(err)
}
// validate
if err = testutils.MatchPty(pty, device, prompt, desc.MediaType, "100.00%", desc.Digest.String()); err != nil {
t.Fatal(err)
}
}
2 changes: 1 addition & 1 deletion cmd/oras/root/attach.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ func runAttach(ctx context.Context, opts attachOptions) error {

// prepare push
var tracked track.GraphTarget
dst, tracked, err = getTrackedTarget(dst, opts.TTY)
dst, tracked, err = getTrackedTarget(dst, opts.TTY, "Uploading", "Uploaded ")
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/oras/root/blob/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,12 @@ func (opts *fetchBlobOptions) doFetch(ctx context.Context, src oras.ReadOnlyTarg
}

if opts.TTY == nil {
// none tty output
// none TTY output
if _, err = io.Copy(writer, vr); err != nil {
return ocispec.Descriptor{}, err
}
} else {
// tty output
// TTY output
trackedReader, err := track.NewReader(vr, desc, "Downloading", "Downloaded ", opts.TTY)
if err != nil {
return ocispec.Descriptor{}, err
Expand Down
4 changes: 2 additions & 2 deletions cmd/oras/root/blob/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ func pushBlob(ctx context.Context, opts pushBlobOptions) (err error) {
}
func (opts *pushBlobOptions) doPush(ctx context.Context, t oras.Target, desc ocispec.Descriptor, r io.Reader) error {
if opts.TTY == nil {
// none tty output
// none TTY output
if err := display.PrintStatus(desc, "Uploading", opts.Verbose); err != nil {
return err
}
Expand All @@ -152,7 +152,7 @@ func (opts *pushBlobOptions) doPush(ctx context.Context, t oras.Target, desc oci
return display.PrintStatus(desc, "Uploaded ", opts.Verbose)
}

// tty output
// TTY output
trackedReader, err := track.NewReader(r, desc, "Uploading", "Uploaded ", opts.TTY)
if err != nil {
return err
Expand Down
4 changes: 2 additions & 2 deletions cmd/oras/root/cp.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,12 +180,12 @@ func doCopy(ctx context.Context, src oras.ReadOnlyGraphTarget, dst oras.GraphTar
dst = tracked
extendedCopyOptions.OnCopySkipped = func(ctx context.Context, desc ocispec.Descriptor) error {
committed.Store(desc.Digest.String(), desc.Annotations[ocispec.AnnotationTitle])
return tracked.Prompt(desc, "Exists ", opts.Verbose)
return tracked.Prompt(desc, "Exists ")
}
extendedCopyOptions.PostCopy = func(ctx context.Context, desc ocispec.Descriptor) error {
committed.Store(desc.Digest.String(), desc.Annotations[ocispec.AnnotationTitle])
return display.PrintSuccessorStatus(ctx, desc, tracked, committed, func(desc ocispec.Descriptor) error {
return tracked.Prompt(desc, "Skipped", opts.Verbose)
return tracked.Prompt(desc, "Skipped")
})
}
}
Expand Down
Loading

0 comments on commit 9ec4f1b

Please sign in to comment.