Skip to content

Commit

Permalink
chore(ux): improve error message for oras tag list (#1219)
Browse files Browse the repository at this point in the history
Signed-off-by: Billy Zha <[email protected]>
  • Loading branch information
qweeah authored Dec 28, 2023
1 parent 03ff401 commit 040c11c
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 10 deletions.
6 changes: 3 additions & 3 deletions cmd/oras/internal/option/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ type Target struct {
// - registry and repository for the remote target
Path string

isOCILayout bool
IsOCILayout bool
}

// ApplyFlags applies flags to a command flag set for unary target
Expand All @@ -78,7 +78,7 @@ func (opts *Target) AnnotatedReference() string {
// the full form is not implemented until a new type comes in.
func (opts *Target) applyFlagsWithPrefix(fs *pflag.FlagSet, prefix, description string) {
flagPrefix, notePrefix := applyPrefix(prefix, description)
fs.BoolVarP(&opts.isOCILayout, flagPrefix+"oci-layout", "", false, "set "+notePrefix+"target as an OCI image layout")
fs.BoolVarP(&opts.IsOCILayout, flagPrefix+"oci-layout", "", false, "set "+notePrefix+"target as an OCI image layout")
}

// ApplyFlagsWithPrefix applies flags to a command flag set with a prefix string.
Expand All @@ -91,7 +91,7 @@ func (opts *Target) ApplyFlagsWithPrefix(fs *pflag.FlagSet, prefix, description
// Parse gets target options from user input.
func (opts *Target) Parse() error {
switch {
case opts.isOCILayout:
case opts.IsOCILayout:
opts.Type = TargetTypeOCILayout
if len(opts.headerFlags) != 0 {
return errors.New("custom header flags cannot be used on an OCI image layout target")
Expand Down
4 changes: 2 additions & 2 deletions cmd/oras/internal/option/target_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
)

func TestTarget_Parse_oci(t *testing.T) {
opts := Target{isOCILayout: true}
opts := Target{IsOCILayout: true}

if err := opts.Parse(); err != nil {
t.Errorf("Target.Parse() error = %v", err)
Expand All @@ -31,7 +31,7 @@ func TestTarget_Parse_oci(t *testing.T) {
}

func TestTarget_Parse_remote(t *testing.T) {
opts := Target{isOCILayout: false}
opts := Target{IsOCILayout: false}
if err := opts.Parse(); err != nil {
t.Errorf("Target.Parse() error = %v", err)
}
Expand Down
16 changes: 15 additions & 1 deletion cmd/oras/root/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package root

import (
"context"
"errors"
"fmt"

"github.com/spf13/cobra"
Expand Down Expand Up @@ -58,7 +59,20 @@ Example - Tag the manifest 'v1.0.1' in 'localhost:5000/hello' to 'v1.0.1', 'v1.0
Example - Tag the manifest 'v1.0.1' to 'v1.0.2' in an OCI image layout folder 'layout-dir':
oras tag layout-dir:v1.0.1 v1.0.2
`,
Args: oerrors.CheckArgs(argument.AtLeast(1), "the to-be-retage artifact and the tags to be added"),
Args: func(cmd *cobra.Command, args []string) error {
if len(args) > 0 && (args[0] == "list" || args[0] == "ls") {
container := "a repository"
if opts.IsOCILayout {
container = "an OCI image layout"
}
return &oerrors.Error{
Err: errors.New(`there is no "list" sub-command for "oras tag" command`),
Usage: fmt.Sprintf("%s %s", cmd.CommandPath(), cmd.Use),
Recommendation: fmt.Sprintf(`If you want to list available tags in %s, use "oras repo tags"`, container),
}
}
return oerrors.CheckArgs(argument.AtLeast(1), "the artifact to be retagged and the tags to be added")(cmd, args)
},
PreRunE: func(cmd *cobra.Command, args []string) error {
opts.RawReference = args[0]
if _, err := registry.ParseReference(opts.RawReference); err != nil {
Expand Down
9 changes: 5 additions & 4 deletions test/e2e/suite/command/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,18 @@ var _ = Describe("ORAS beginners:", func() {
ORAS("tag", RegistryRef(ZOTHost, ImageRepo, "i-dont-think-this-tag-exists"), "tagged").ExpectFailure().MatchErrKeyWords("Error:").Exec()
})

It("should fail when provided invalid reference", func() {
ORAS("tag", "list", "tagged").ExpectFailure().MatchErrKeyWords("Error:", "'list'").Exec()
})

It("should fail and show detailed error description if no argument provided", func() {
err := ORAS("tag").ExpectFailure().Exec().Err
gomega.Expect(err).Should(gbytes.Say("Error"))
gomega.Expect(err).Should(gbytes.Say("\nUsage: oras tag"))
gomega.Expect(err).Should(gbytes.Say("\n"))
gomega.Expect(err).Should(gbytes.Say(`Run "oras tag -h"`))
})

It("should fail with suggestion if calling with `tag list`", func() {
ORAS("tag", "list").ExpectFailure().MatchErrKeyWords("Error:", `there is no "list" sub-command for "oras tag" command`, "repository", "oras repo tags").Exec()
ORAS("tag", "list", Flags.Layout).ExpectFailure().MatchErrKeyWords("Error:", `there is no "list" sub-command for "oras tag" command`, "OCI Image Layout", "oras repo tags").Exec()
})
})
})

Expand Down

0 comments on commit 040c11c

Please sign in to comment.