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: make command accessible in option parser #1315

Merged
merged 4 commits into from
Apr 1, 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
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
Loading