Skip to content
Open
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
14 changes: 14 additions & 0 deletions shortcuts/common/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,7 @@ func (s Shortcut) mountDeclarative(parent *cobra.Command, f *cmdutil.Factory) {
cmd := &cobra.Command{
Use: shortcut.Command,
Short: shortcut.Description,
Args: rejectPositionalArgs(),
RunE: func(cmd *cobra.Command, _ []string) error {
return runShortcut(cmd, f, &shortcut, botOnly)
},
Expand Down Expand Up @@ -681,6 +682,19 @@ func handleShortcutDryRun(f *cmdutil.Factory, rctx *RuntimeContext, s *Shortcut)
return nil
}

// rejectPositionalArgs returns a cobra.PositionalArgs that rejects any
// positional arguments. The error is intentionally a plain error (not
// ExitError) so that cobra prints usage and the root handler prints a
// simple "Error:" line instead of a JSON envelope.
func rejectPositionalArgs() cobra.PositionalArgs {
return func(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
return nil
}
return fmt.Errorf("positional arguments are not supported (got %q); pass values via flags", args)
}
}

func registerShortcutFlags(cmd *cobra.Command, s *Shortcut) {
for _, fl := range s.Flags {
desc := fl.Desc
Expand Down
58 changes: 58 additions & 0 deletions shortcuts/common/runner_args_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
// SPDX-License-Identifier: MIT

package common

import (
"strings"
"testing"

"github.com/spf13/cobra"
)

func TestRejectPositionalArgs_WithArgs(t *testing.T) {
t.Parallel()

validator := rejectPositionalArgs()

err := validator(&cobra.Command{}, []string{"hello"})
if err == nil {
t.Fatal("expected error for positional arg, got nil")
}
if !strings.Contains(err.Error(), "positional arguments are not supported") {
t.Errorf("expected positional args rejection message, got: %v", err)
}
if !strings.Contains(err.Error(), `"hello"`) {
t.Errorf("expected the positional arg value in error, got: %v", err)
}
}

func TestRejectPositionalArgs_MultipleArgs(t *testing.T) {
t.Parallel()

validator := rejectPositionalArgs()

err := validator(&cobra.Command{}, []string{"hello", "world"})
if err == nil {
t.Fatal("expected error for multiple positional args, got nil")
}
if !strings.Contains(err.Error(), "positional arguments are not supported") {
t.Errorf("unexpected error message: %v", err)
}
if !strings.Contains(err.Error(), "hello") || !strings.Contains(err.Error(), "world") {
t.Errorf("expected all positional args in error, got: %v", err)
}
}

func TestRejectPositionalArgs_NoArgs(t *testing.T) {
t.Parallel()

validator := rejectPositionalArgs()

if err := validator(&cobra.Command{}, nil); err != nil {
t.Fatalf("expected no error for nil args, got: %v", err)
}
if err := validator(&cobra.Command{}, []string{}); err != nil {
t.Fatalf("expected no error for empty args, got: %v", err)
}
}
Loading