Skip to content

Commit

Permalink
refactor: make command accessible in option parser (#1315)
Browse files Browse the repository at this point in the history
Signed-off-by: Xiaoxuan Wang <[email protected]>
  • Loading branch information
wangxiaoxuan273 authored Apr 1, 2024
1 parent c24ac15 commit d00ae9e
Show file tree
Hide file tree
Showing 26 changed files with 42 additions and 36 deletions.
3 changes: 2 additions & 1 deletion cmd/oras/internal/option/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"os"

"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"golang.org/x/term"
"oras.land/oras/internal/trace"
Expand Down Expand Up @@ -49,7 +50,7 @@ func (opts *Common) WithContext(ctx context.Context) (context.Context, logrus.Fi
}

// Parse gets target options from user input.
func (opts *Common) Parse() error {
func (opts *Common) Parse(*cobra.Command) error {
// use STDERR as TTY output since STDOUT is reserved for pipeable output
return opts.parseTTY(os.Stderr)
}
Expand Down
3 changes: 2 additions & 1 deletion cmd/oras/internal/option/packer.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"strings"

ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"oras.land/oras-go/v2/content"
oerrors "oras.land/oras/cmd/oras/internal/errors"
Expand Down Expand Up @@ -73,7 +74,7 @@ func (opts *Packer) ExportManifest(ctx context.Context, fetcher content.Fetcher,
}
return os.WriteFile(opts.ManifestExportPath, manifestBytes, 0666)
}
func (opts *Packer) Parse() error {
func (opts *Packer) Parse(*cobra.Command) error {
if !opts.PathValidationDisabled {
var failedPaths []string
for _, path := range opts.FileRefs {
Expand Down
8 changes: 5 additions & 3 deletions cmd/oras/internal/option/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,20 @@ package option

import (
"reflect"

"github.com/spf13/cobra"
)

// FlagParser parses flags in an option.
type FlagParser interface {
Parse() error
Parse(cmd *cobra.Command) error
}

// Parse parses applicable fields of the passed-in option pointer and returns
// error during parsing.
func Parse(optsPtr interface{}) error {
func Parse(cmd *cobra.Command, optsPtr interface{}) error {
return rangeFields(optsPtr, func(fp FlagParser) error {
return fp.Parse()
return fp.Parse(cmd)
})
}

Expand Down
7 changes: 4 additions & 3 deletions cmd/oras/internal/option/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@ import (
"errors"
"testing"

"github.com/spf13/cobra"
"oras.land/oras/cmd/oras/internal/option"
)

type Test struct {
CntPtr *int
}

func (t *Test) Parse() error {
func (t *Test) Parse(cmd *cobra.Command) error {
*t.CntPtr += 1
if *t.CntPtr == 2 {
return errors.New("should not be tried twice")
Expand All @@ -48,7 +49,7 @@ func TestParse_once(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := option.Parse(&tt.args); (err != nil) != tt.wantErr {
if err := option.Parse(nil, &tt.args); (err != nil) != tt.wantErr {
t.Errorf("Parse() error = %v, wantErr %v", err, tt.wantErr)
}

Expand Down Expand Up @@ -76,7 +77,7 @@ func TestParse_err(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := option.Parse(&tt.args); (err != nil) != tt.wantErr {
if err := option.Parse(nil, &tt.args); (err != nil) != tt.wantErr {
t.Errorf("Parse() error = %v, wantErr %v", err, tt.wantErr)
}

Expand Down
3 changes: 2 additions & 1 deletion cmd/oras/internal/option/platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"strings"

ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)

Expand All @@ -36,7 +37,7 @@ func (opts *Platform) ApplyFlags(fs *pflag.FlagSet) {
}

// parse parses the input platform flag to an oci platform type.
func (opts *Platform) Parse() error {
func (opts *Platform) Parse(*cobra.Command) error {
if opts.platform == "" {
return nil
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/oras/internal/option/platform_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func TestPlatform_Parse_err(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := tt.opts.Parse()
err := tt.opts.Parse(nil)
if err == nil {
t.Errorf("Platform.Parse() error = %v, wantErr %v", err, true)
return
Expand All @@ -68,7 +68,7 @@ func TestPlatform_Parse(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := tt.opts.Parse(); err != nil {
if err := tt.opts.Parse(nil); err != nil {
t.Errorf("Platform.Parse() error = %v", err)
}
got := tt.opts.Platform
Expand Down
2 changes: 1 addition & 1 deletion cmd/oras/internal/option/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func (opts *Remote) ApplyFlagsWithPrefix(fs *pflag.FlagSet, prefix, description
}

// Parse tries to read password with optional cmd prompt.
func (opts *Remote) Parse() error {
func (opts *Remote) Parse(*cobra.Command) error {
if err := opts.parseCustomHeaders(); err != nil {
return err
}
Expand Down
8 changes: 4 additions & 4 deletions cmd/oras/internal/option/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func (opts *Target) ApplyFlagsWithPrefix(fs *pflag.FlagSet, prefix, description
}

// Parse gets target options from user input.
func (opts *Target) Parse() error {
func (opts *Target) Parse(cmd *cobra.Command) error {
switch {
case opts.IsOCILayout:
opts.Type = TargetTypeOCILayout
Expand All @@ -111,7 +111,7 @@ func (opts *Target) Parse() error {
Recommendation: "Please make sure the provided reference is in the form of <registry>/<repo>[:tag|@digest]",
}
}
return opts.Remote.Parse()
return opts.Remote.Parse(cmd)
}
}

Expand Down Expand Up @@ -330,13 +330,13 @@ func (opts *BinaryTarget) ApplyFlags(fs *pflag.FlagSet) {
}

// Parse parses user-provided flags and arguments into option struct.
func (opts *BinaryTarget) Parse() error {
func (opts *BinaryTarget) Parse(cmd *cobra.Command) error {
opts.From.warned = make(map[string]*sync.Map)
opts.To.warned = opts.From.warned
// resolve are parsed in array order, latter will overwrite former
opts.From.resolveFlag = append(opts.resolveFlag, opts.From.resolveFlag...)
opts.To.resolveFlag = append(opts.resolveFlag, opts.To.resolveFlag...)
return Parse(opts)
return Parse(cmd, opts)
}

// Modify handles error during cmd execution.
Expand Down
6 changes: 3 additions & 3 deletions cmd/oras/internal/option/target_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import (

func TestTarget_Parse_oci(t *testing.T) {
opts := Target{IsOCILayout: true}
err := opts.Parse()
err := opts.Parse(nil)
if !errors.Is(err, errdef.ErrInvalidReference) {
t.Errorf("Target.Parse() error = %v, expect %v", err, errdef.ErrInvalidReference)
}
Expand All @@ -44,7 +44,7 @@ func TestTarget_Parse_remote(t *testing.T) {
RawReference: "mocked/test",
IsOCILayout: false,
}
if err := opts.Parse(); err != nil {
if err := opts.Parse(nil); err != nil {
t.Errorf("Target.Parse() error = %v", err)
}
if opts.Type != TargetTypeRemote {
Expand All @@ -57,7 +57,7 @@ func TestTarget_Parse_remote_err(t *testing.T) {
RawReference: "/test",
IsOCILayout: false,
}
if err := opts.Parse(); err == nil {
if err := opts.Parse(nil); err == nil {
t.Errorf("expect Target.Parse() to fail but not")
}
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/oras/root/attach.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ Example - Attach file to the manifest tagged 'v1' in an OCI image layout folder
PreRunE: func(cmd *cobra.Command, args []string) error {
opts.RawReference = args[0]
opts.FileRefs = args[1:]
if err := option.Parse(&opts); err != nil {
if err := option.Parse(cmd, &opts); err != nil {
return err
}
return nil
Expand Down
2 changes: 1 addition & 1 deletion cmd/oras/root/blob/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ Example - Delete a blob and print its descriptor:
if opts.OutputDescriptor && !opts.Force {
return errors.New("must apply --force to confirm the deletion if the descriptor is outputted")
}
return option.Parse(&opts)
return option.Parse(cmd, &opts)
},
RunE: func(cmd *cobra.Command, args []string) error {
return deleteBlob(cmd, &opts)
Expand Down
2 changes: 1 addition & 1 deletion cmd/oras/root/blob/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ Example - Fetch and print a blob from OCI image layout archive file 'layout.tar'
return errors.New("`--output -` cannot be used with `--descriptor` at the same time")
}
opts.RawReference = args[0]
err := option.Parse(&opts)
err := option.Parse(cmd, &opts)
if err == nil {
opts.UpdateTTY(cmd.Flags().Changed(option.NoTTYFlag), opts.outputPath == "-")
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/oras/root/blob/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Example - Push blob 'hi.txt' into an OCI image layout folder 'layout-dir':
return errors.New("`--size` must be provided if the blob is read from stdin")
}
}
return option.Parse(&opts)
return option.Parse(cmd, &opts)
},
RunE: func(cmd *cobra.Command, args []string) error {
return pushBlob(cmd, &opts)
Expand Down
2 changes: 1 addition & 1 deletion cmd/oras/root/cp.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ Example - Copy an artifact with multiple tags with concurrency tuned:
refs := strings.Split(args[1], ",")
opts.To.RawReference = refs[0]
opts.extraRefs = refs[1:]
return option.Parse(&opts)
return option.Parse(cmd, &opts)
},
RunE: func(cmd *cobra.Command, args []string) error {
return runCopy(cmd, &opts)
Expand Down
2 changes: 1 addition & 1 deletion cmd/oras/root/discover.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ Example - Discover referrers of the manifest tagged 'v1' in an OCI image layout
Args: oerrors.CheckArgs(argument.Exactly(1), "the target artifact to discover referrers from"),
PreRunE: func(cmd *cobra.Command, args []string) error {
opts.RawReference = args[0]
return option.Parse(&opts)
return option.Parse(cmd, &opts)
},
RunE: func(cmd *cobra.Command, args []string) error {
return runDiscover(cmd, &opts)
Expand Down
2 changes: 1 addition & 1 deletion cmd/oras/root/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Example - Log in with username and password in an interactive terminal and no TL
`,
Args: oerrors.CheckArgs(argument.Exactly(1), "the registry to log in to"),
PreRunE: func(cmd *cobra.Command, args []string) error {
return option.Parse(&opts)
return option.Parse(cmd, &opts)
},
RunE: func(cmd *cobra.Command, args []string) error {
opts.Hostname = args[0]
Expand Down
2 changes: 1 addition & 1 deletion cmd/oras/root/manifest/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ Example - Delete a manifest by digest 'sha256:99e4703fbf30916f549cd6bfa9cdbab614
if opts.OutputDescriptor && !opts.Force {
return errors.New("must apply --force to confirm the deletion if the descriptor is outputted")
}
return option.Parse(&opts)
return option.Parse(cmd, &opts)
},
RunE: func(cmd *cobra.Command, args []string) error {
return deleteManifest(cmd, &opts)
Expand Down
2 changes: 1 addition & 1 deletion cmd/oras/root/manifest/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ Example - Fetch raw manifest from an OCI layout archive file 'layout.tar':
return errors.New("`--output -` cannot be used with `--descriptor` at the same time")
}
opts.RawReference = args[0]
return option.Parse(&opts)
return option.Parse(cmd, &opts)
},
Aliases: []string{"get"},
RunE: func(cmd *cobra.Command, args []string) error {
Expand Down
2 changes: 1 addition & 1 deletion cmd/oras/root/manifest/fetch_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ Example - Fetch and print the prettified descriptor of the config:
return errors.New("`--output -` cannot be used with `--descriptor` at the same time")
}
opts.RawReference = args[0]
return option.Parse(&opts)
return option.Parse(cmd, &opts)
},
RunE: func(cmd *cobra.Command, args []string) error {
return fetchConfig(cmd, &opts)
Expand Down
2 changes: 1 addition & 1 deletion cmd/oras/root/manifest/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ Example - Push a manifest to an OCI image layout folder 'layout-dir' and tag wit
refs := strings.Split(args[0], ",")
opts.RawReference = refs[0]
opts.extraRefs = refs[1:]
return option.Parse(&opts)
return option.Parse(cmd, &opts)
},
RunE: func(cmd *cobra.Command, args []string) error {
return pushManifest(cmd, opts)
Expand Down
2 changes: 1 addition & 1 deletion cmd/oras/root/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ Example - Pull artifact files from an OCI layout archive 'layout.tar':
Args: oerrors.CheckArgs(argument.Exactly(1), "the artifact reference you want to pull"),
PreRunE: func(cmd *cobra.Command, args []string) error {
opts.RawReference = args[0]
return option.Parse(&opts)
return option.Parse(cmd, &opts)
},
RunE: func(cmd *cobra.Command, args []string) error {
return runPull(cmd, &opts)
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 @@ -105,7 +105,7 @@ Example - Push file "hi.txt" into an OCI image layout folder 'layout-dir' with t
opts.RawReference = refs[0]
opts.extraRefs = refs[1:]
opts.FileRefs = args[1:]
if err := option.Parse(&opts); err != nil {
if err := option.Parse(cmd, &opts); err != nil {
return err
}
switch opts.PackVersion {
Expand Down
2 changes: 1 addition & 1 deletion cmd/oras/root/repo/ls.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Example - List the repositories under the registry that include values lexically
Args: oerrors.CheckArgs(argument.Exactly(1), "the target registry to list repositories from"),
Aliases: []string{"list"},
PreRunE: func(cmd *cobra.Command, args []string) error {
return option.Parse(&opts)
return option.Parse(cmd, &opts)
},
RunE: func(cmd *cobra.Command, args []string) error {
var err error
Expand Down
2 changes: 1 addition & 1 deletion cmd/oras/root/repo/tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Example - [Experimental] Show tags associated with a digest:
Aliases: []string{"show-tags"},
PreRunE: func(cmd *cobra.Command, args []string) error {
opts.RawReference = args[0]
return option.Parse(&opts)
return option.Parse(cmd, &opts)
},
RunE: func(cmd *cobra.Command, args []string) error {
return showTags(cmd, &opts)
Expand Down
2 changes: 1 addition & 1 deletion cmd/oras/root/resolve.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Example - Resolve digest of the target artifact:
Aliases: []string{"digest"},
PreRunE: func(cmd *cobra.Command, args []string) error {
opts.RawReference = args[0]
return option.Parse(&opts)
return option.Parse(cmd, &opts)
},
RunE: func(cmd *cobra.Command, args []string) error {
return runResolve(cmd, &opts)
Expand Down
2 changes: 1 addition & 1 deletion cmd/oras/root/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ Example - Tag the manifest 'v1.0.1' to 'v1.0.2' in an OCI image layout folder 'l
PreRunE: func(cmd *cobra.Command, args []string) error {
opts.RawReference = args[0]
opts.targetRefs = args[1:]
if err := option.Parse(&opts); err != nil {
if err := option.Parse(cmd, &opts); err != nil {
if inner, ok := err.(*oerrors.Error); ok {
if errors.Is(inner, errdef.ErrInvalidReference) {
inner.Err = fmt.Errorf("unable to add tag for '%s': %w", opts.RawReference, inner.Err)
Expand Down

0 comments on commit d00ae9e

Please sign in to comment.