diff --git a/pkg/cmd/codespace/ssh.go b/pkg/cmd/codespace/ssh.go index 5d7c570a8..a0f596e49 100644 --- a/pkg/cmd/codespace/ssh.go +++ b/pkg/cmd/codespace/ssh.go @@ -13,6 +13,7 @@ import ( "strings" "github.com/cli/cli/v2/internal/codespaces" + "github.com/cli/cli/v2/pkg/cmdutil" "github.com/cli/cli/v2/pkg/liveshare" "github.com/spf13/cobra" ) @@ -193,7 +194,7 @@ users; see https://lwn.net/Articles/835962/ for discussion. // Copy copies files between the local and remote file systems. // The mechanics are similar to 'ssh' but using 'scp'. -func (a *App) Copy(ctx context.Context, args []string, opts cpOptions) (err error) { +func (a *App) Copy(ctx context.Context, args []string, opts cpOptions) error { if len(args) < 2 { return fmt.Errorf("cp requires source and destination arguments") } @@ -201,8 +202,10 @@ func (a *App) Copy(ctx context.Context, args []string, opts cpOptions) (err erro opts.scpArgs = append(opts.scpArgs, "-r") } opts.scpArgs = append(opts.scpArgs, "--") + hasRemote := false for _, arg := range args { if rest := strings.TrimPrefix(arg, "remote:"); rest != arg { + hasRemote = true // scp treats each filename argument as a shell expression, // subjecting it to expansion of environment variables, braces, // tilde, backticks, globs and so on. Because these present a @@ -225,6 +228,9 @@ func (a *App) Copy(ctx context.Context, args []string, opts cpOptions) (err erro } opts.scpArgs = append(opts.scpArgs, arg) } + if !hasRemote { + return &cmdutil.FlagError{Err: fmt.Errorf("at least one argument must have a 'remote:' prefix")} + } return a.SSH(ctx, nil, opts.sshOptions) } diff --git a/pkg/cmd/repo/fork/fork.go b/pkg/cmd/repo/fork/fork.go index 4134a7ba2..dcd5571f7 100644 --- a/pkg/cmd/repo/fork/fork.go +++ b/pkg/cmd/repo/fork/fork.go @@ -61,7 +61,7 @@ func NewCmdFork(f *cmdutil.Factory, runF func(*ForkOptions) error) *cobra.Comman Use: "fork [] [-- ...]", Args: func(cmd *cobra.Command, args []string) error { if cmd.ArgsLenAtDash() == 0 && len(args[1:]) > 0 { - return cmdutil.FlagError{Err: fmt.Errorf("repository argument required when passing 'git clone' flags")} + return &cmdutil.FlagError{Err: fmt.Errorf("repository argument required when passing 'git clone' flags")} } return nil }, diff --git a/pkg/cmd/workflow/run/run.go b/pkg/cmd/workflow/run/run.go index 0ab3f1749..5f10e515c 100644 --- a/pkg/cmd/workflow/run/run.go +++ b/pkg/cmd/workflow/run/run.go @@ -78,7 +78,7 @@ func NewCmdRun(f *cmdutil.Factory, runF func(*RunOptions) error) *cobra.Command `), Args: func(cmd *cobra.Command, args []string) error { if len(opts.MagicFields)+len(opts.RawFields) > 0 && len(args) == 0 { - return cmdutil.FlagError{Err: fmt.Errorf("workflow argument required when passing -f or -F")} + return &cmdutil.FlagError{Err: fmt.Errorf("workflow argument required when passing -f or -F")} } return nil }, @@ -103,7 +103,7 @@ func NewCmdRun(f *cmdutil.Factory, runF func(*RunOptions) error) *cobra.Command } opts.JSONInput = string(jsonIn) } else if opts.JSON { - return cmdutil.FlagError{Err: errors.New("--json specified but nothing on STDIN")} + return &cmdutil.FlagError{Err: errors.New("--json specified but nothing on STDIN")} } if opts.Selector == "" { diff --git a/pkg/cmdutil/errors.go b/pkg/cmdutil/errors.go index 8ae139ef4..1e40a0185 100644 --- a/pkg/cmdutil/errors.go +++ b/pkg/cmdutil/errors.go @@ -6,16 +6,17 @@ import ( "github.com/AlecAivazis/survey/v2/terminal" ) -// FlagError is the kind of error raised in flag processing +// A *FlagError indicates an error processing command-line flags or other arguments. +// Such errors cause the application to display the usage message. type FlagError struct { Err error } -func (fe FlagError) Error() string { +func (fe *FlagError) Error() string { return fe.Err.Error() } -func (fe FlagError) Unwrap() error { +func (fe *FlagError) Unwrap() error { return fe.Err }